pax_global_header00006660000000000000000000000064151744737430014531gustar00rootroot0000000000000052 comment=571246107ac9cb88dee2c6c69cda5dd9805820da chafa-1.18.2/000077500000000000000000000000001517447374300126645ustar00rootroot00000000000000chafa-1.18.2/.gitattributes000066400000000000000000000000141517447374300155520ustar00rootroot00000000000000* text=auto chafa-1.18.2/.github/000077500000000000000000000000001517447374300142245ustar00rootroot00000000000000chafa-1.18.2/.github/workflows/000077500000000000000000000000001517447374300162615ustar00rootroot00000000000000chafa-1.18.2/.github/workflows/c-cpp.yml000066400000000000000000000035421517447374300200120ustar00rootroot00000000000000name: C/C++ CI on: push: branches: [ "master" ] pull_request: branches: [ "master" ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Running prerequisites run: > sudo apt update -y sudo apt install -y automake libtool libglib2.0-dev libavif-dev libjpeg-dev librsvg2-dev libtiff-dev libwebp-dev gtk-doc-tools docbook-xml libxml2-utils export LD_LIBRARY_PATH=$(if [[ $CC == "clang" ]]; then echo -n '/usr/local/clang/lib'; fi) mkdir build - name: Building working-directory: ./build run: > CFLAGS=' -g -O2 -fsanitize=address,undefined -fsanitize-undefined-trap-on-error -fstack-protector-all -Werror -Wno-error=attributes -Wno-error=cast-qual -Wno-error=unused -Wno-error=unused-function -Wno-error=unused-macros -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=unused-const-variable -Wno-error=unused-value -Wno-error=comment -Wno-error=missing-braces' ../autogen.sh --prefix=/usr --enable-gtk-doc --enable-man make -j4 - name: Running tests working-directory: ./build run: make check || { RET=$$?; find . -name "test-suite.log" -exec cat {} + ; exit $RET; } - name: Installing chafa working-directory: ./build run: > sudo make install chafa --version - name: Run post install working-directory: ./tests run: ./postinstall.sh - name: After failure if: failure() run: > touch tests/test-suite.log cat tests/test-suite.log chafa-1.18.2/.gitignore000066400000000000000000000004761517447374300146630ustar00rootroot00000000000000*~ \#*\# *.la *.lo *.o *.stamp *-stamp .deps .libs Makefile Makefile.in /aclocal.m4 /ar-lib /autom4te.cache /chafa.pc /compile /config.guess /config.h /config.h.in /config.log /config.status /config.sub /configure /depcomp /gtk-doc.m4 /gtk-doc.make /install-sh /libtool /ltmain.sh /m4 /missing /stamp-h1 /test-driver chafa-1.18.2/.travis.yml000066400000000000000000000020711517447374300147750ustar00rootroot00000000000000language: c dist: bionic compiler: - clang - gcc before_install: - sudo apt-get install -qq -y automake libtool libglib2.0-dev libmagickwand-dev libjpeg-dev librsvg2-dev libtiff-dev libwebp-dev gtk-doc-tools docbook-xml libxml2-utils # Needed for ImageMagick/clang runtime not finding libomp.so - export LD_LIBRARY_PATH=$(if [[ $CC == "clang" ]]; then echo -n '/usr/local/clang/lib'; fi) script: - mkdir build && cd build && CFLAGS='-g -O2 -fsanitize=address,undefined -fsanitize-undefined-trap-on-error -Werror -Wno-error=unused -Wno-error=unused-function -Wno-error=unused-parameter -Wno-error=unused-variable -Wno-error=unused-const-variable -Wno-error=unused-value -Wno-error=comment -Wno-error=missing-braces' ../autogen.sh --prefix=/usr --enable-gtk-doc --enable-man --without-imagemagick && make -j4 && make check && rm -Rf ../build/* && ../autogen.sh --prefix=/usr --enable-gtk-doc --enable-man && make -j4 && sudo make install && chafa --version && cd ../tests && ./postinstall.sh after_failure: - touch tests/test-suite.log && cat tests/test-suite.log chafa-1.18.2/AUTHORS000066400000000000000000000031121517447374300137310ustar00rootroot00000000000000Chafa is principally written and maintained by Hans Petter Jansson . Feel free to contact him with any questions and comments. There is a growing list of contributors; these can be found in the git log. For a complete list, you could try: git log --pretty="format:%an <%ae>" | sort -f | uniq Per 2025-05-18, this yields the following (sans duplicates): alkahest AnonymouX47 begasus Biswapriyo Nath Daniel Eklöf data-man Delgan Eli Schwartz Emanuel Haupt Erica Felix Yan Hans Petter Jansson Hoang Nguyen Johan Mattsson <39247600+mjunix@users.noreply.github.com> korei999 Launch Lee <80872691+LaunchLee@users.noreply.github.com> Michael Vetter Mikel Olasagasti Uranga Mo Zhou oshaboy <35503208+oshaboy@users.noreply.github.com> oupson Ricardo Arguello Robert-André Mauchin Roman Wagner Samuel Thibault Sebastian Stark Simon Law sitiom Sotiris Papatheodorou Sudhakar Verma Tim Gates Wu Zhenyu Øyvind Kolås chafa-1.18.2/COPYING000066400000000000000000001045151517447374300137250ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . chafa-1.18.2/COPYING.LESSER000066400000000000000000000167441517447374300147270ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. chafa-1.18.2/HACKING000066400000000000000000000066071517447374300136640ustar00rootroot00000000000000How to hack on Chafa ==================== Code formatting and structure ----------------------------- The code is mostly C99 with limited use of extensions. It should compile with most standards-compliant C compilers released in the last couple of years. GLib is our primary support library, and the code is in general very GLib-y. We use only the base library, no GObject or GIO. Formatting is done with spaces (no tabs) and four-space indenting stops. The directory layout is as follows: * Top level ............ Build scripts, README, etc. |- chafa ............. The Chafa library. All exported APIs are here. | `- internal ....... Chafa library internals. Internal APIs. | `- smolscale ... Private copy of a pixmap scaling library. |- docs .............. Built documentation (API and man pages). |- libnsgif .......... Private copy of a GIF library, used by tools. |- lodepng ........... Private copy of a PNG library, used by tools. |- tests ............. Tests for library and tools. `- tools ............. Command-line tools. |- chafa .......... The Chafa command-line graphics viewer. `- fontgen ........ Experimental font generator. Making source releases ---------------------- Releases are made as compressed, signed tar archives ("tarballs"). We use semantic versioning. The following can be done multiple times and at any time during development, always on the master branch: 1) Write/edit NEWS section with a (TBA) placeholder for release date. Then right before the release, still on the master branch: 2) Update the soversion in chafa/Makefile.am (-version-info c:r:a): - If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’). - If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0. - If any interfaces have been added since the last public release, then increment age. - If any interfaces have been removed or changed since the last public release, then set age to 0. 3) If this is a minor (x.y.0) release, bump package to the next even version in configure.ac. 4) Make sure 'make distcheck' passes. Correct any issues. 5) Commit and push above changes. Wait for green CI and correct any issues. 6) Edit NEWS and replace (TBA) with today's date. 7) If this is a minor (x.y.0) release, edit README.md and update the CI links. They should reference master and the latest stable branch. 8) If this is a micro (x.y.z) release, switch to that release's maintenance branch (x.y) and cherry-pick all changes from the previous steps into it, then increment the micro version in configure.ac. 9) Commit above changes. 10) Tag and sign the release: 'git tag -s x.y.z'. Annotate with the appropriate NEWS item, without the --- underline for the heading. 11) If this is a minor (x.y.0) release, make a maintenance branch for it, rooted at the tag: 'git branch x.y'. But keep working on master. 12) Build tarball: 'make distcheck'. 13) Sign tarball: 'gpg --sign --detach --armor chafa-x.y.z.tar.xz'. 14) If this was a minor (x.y.0) release, bump package to the next odd version. 15) Commit the post-release version bump. 16) Push changes. Make sure to push tags and branches too. 17) Upload the tarball and signature to GitHub, and copy the NEWS item there. Add markdown formatting. That should do it. chafa-1.18.2/Makefile.am000066400000000000000000000011331517447374300147160ustar00rootroot00000000000000SUBDIRS = chafa docs examples libnsgif lodepng tools tests SGR0=$$(tput sgr0 2>/dev/null) SETAF9=$$(tput setaf 9 2>/dev/null) SETAF11=$$(tput setaf 11 2>/dev/null) EXTRA_DIST = \ HACKING \ README.md \ SECURITY.md \ autogen.sh \ chafa.pc.in pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = chafa.pc all-local: @echo @echo --- @echo --- Success! You can now run tools/chafa/chafa, or install everything @echo --- using "make install" or "sudo make install". @echo --- @echo --- ${SETAF9}NOTE:${SGR0} You may have to run ${SETAF11}sudo ldconfig${SGR0} after installing. @echo --- @echo chafa-1.18.2/NEWS000066400000000000000000001057761517447374300134030ustar00rootroot00000000000000Chafa releases ============== 1.18.2 (2026-04-30) ------------------- This is a bugfix release focused on security, hardening and correctness. One of the listed bugs is related to "unreasonable" CLI parameters like output sizes hundreds of thousands of cells wide; while OOB access is always a bug, users are reminded that we don't recommend forwarding CLI parameters from untrusted sources without prior sanitization. Thanks to everyone who contributed patches and analysis. * Support BigTIFF images (github#328, reported by Govinda Kamath). * Bug fixes: [unfiled] Integer overflow and OOB write with big output size (@Captainjack-kor). [unfiled] OOB write in symbol-mode Floyd-Steinberg dithering. [unfiled] CLI: Incomplete sanitization of filenames printed to terminal. [unfiled] CLI: Integer overflow in XWD header validation. [unfiled] CLI: Pointer arithmetic past end of GIF file allocation. [unfiled] OOB reading canvas cell colors in FGBG mode. [unfiled] Compiler warnings from headers with C99 and -Wpedantic. 1.18.1 (2026-02-08) ------------------- This is a bugfix and quality-of-life release. * New option: --probe-mode=[any|ctty|stdio]. This specifies whether to probe the terminal through stdio or ctty (usually /dev/tty). Defaults to "any", which will probe stdio if it looks like a tty, otherwise the ctty. This allows the terminal to be probed when I/O is redirected (github#325, reported by @algometric). * We now try harder to restore the terminal to a usable state after SIGINT is received, even if we couldn't do a clean exit in a reasonable time frame (github#309, reported by Hayaki Saito). * Bash completions were added and zsh completions updated (github#315, @desertstsung). * Improved compatibility for the Kitty protocol, specifically with iTerm2 (@zouyonghe). * Bug fixes: github#184 Test failure on sparc64 (reported by Mo Zhou). github#292 Test failure on i386 (reported by Mo Zhou). github#321 Bad console modes on win32 after exit (reported by Julian Noble). [unfiled] Stalling on closed output pipe on OpenBSD. 1.18.0 (2025-11-09) ------------------- This is a feature and bugfix release. * Increased GLib minimum version to 2.58 (released in 2018). * New options: --files=FNAME and --files0=FNAME. These allow reading lists of input files from a file or standard input. Paths can be separated by newlines or a zero byte (--files0). These options can be specified multiple times. * New option: --link=[auto|on|off]. When used with --label, this controls whether each label should be an OSC 8-style hyperlink to its input file. * Multiple files can now be decoded in parallel. This greatly speeds up grid mode on multi-core systems. Controllable with --threads. * ConHost support was removed due to incompleteness and lack of interest. * Image loaders: - Added support for CoreGraphics loaders on MacOS (github#301, Hayaki Saito). - Added support for HEIF files on all platforms (github#297). * Terminal support: - Improved detection of ghostty inside tmux (github#296, reported by @timsofteng). - Added support for GNU/Hurd console. * Tests: - Expanded symbol matching tests with more cases and detailed diagnostics. - Added a test for CLI tool return values in various scenarios. * Bug fixes: github#293 Don't leave stdin in non-blocking mode (found by @YanceyChiew). [unfiled] Use glibtoolize when libtoolize is unavailable (Hayaki Saito). [unfiled] GNU/Hurd: Don't stall if pipe is closed on remote end. [unfiled] _mm_empty() not always called immediately after MMX use. [unfiled] FP division by zero possible in sixel palette generation. [unfiled] Don't wait for response if probing is unsupported. [unfiled] Wrong exit code returned on some failures. 1.16.2 (2025-07-04) ------------------- This is a bugfix release. It also improves I/O robustness and SVG rendering quality. * Bug fixes: github#288 SVG scaling seems to be done after bitmap conversion (found by @joveian). [unfiled] MinGW: Undeclared function error for strlen() (Carlo Bramini). [unfiled] Assert when using chafa_canvas_draw_all_pixels() with Kitty passthrough (found by @ravachol). [unfiled] Hangs when running with closed stdin (found by Xavier Moffett). [unfiled] Potential overrun when output dimension is exactly 1 pixel. [unfiled] Small memory leak on failed load in the grid layout. [unfiled] Occasional warnings from JPEG loader that should not be printed. 1.16.1 (2025-05-21) ------------------- This release fixes two important bugs. * Bug fixes: github#282 Fish completion not included in release tarball (found by @knuxify). github#283 Piping and redirection are broken in Windows (found by @veltza). 1.16.0 (2025-05-18) ------------------- This is a feature release with lots of additional polish and some new API. Thanks to everyone who chipped in with issues and code. Special thanks to @AnonymouX47 for helping out with the grid implementation and for going above and beyond with QA and bugfixing in general. * Added terminal probing. Currently we can determine geometry, colors and sixel capabilities this way. This supplements the existing heuristics. * The internal terminal database and heuristics were refactored for clarity, with new API added to simplify the configuration process. * I/O is now threaded, resulting in improved responsiveness and pipelining. * New option: --grid=WxH, --grid=[auto|on|off] or -g. This lays out multiple images in a grid for easy browsing. * New option: --label=[on|off] or -l. Labels each image with its filename. Works in both continuous and grid layouts. * New option: --probe=[auto|on|off]. Controls whether to actively probe the terminal. Can take a real number denoting how long to wait for a response. * Sixel quality improved significantly. The quantizer was reimplemented with modern algorithms (github#174), and blue noise dithering was introduced (github#238). * The new blue noise dithering is also available in symbols mode, and can be turned on with '--dither noise'. It can be turned off with '--dither none'. * Numerous small improvements were made to sixel handling: - Terminal cursor placement quirks are now represented and handled. - Images can now cover their cell extents completely. - Workaround for animations "walking up the screen" on quirky terminals. * The JPEG XL loader was improved with optional memory mapping and better container support (@oupson). * Enabled wildcard expansion in Windows builds (github#266). * Added completions for the fish shell (Hoang Nguyen) and updated those for zsh (Sebastian Stark). * Bug fixes: github#111 Provide auto detection of background for perception of transparency (found by Akash Patel). github#228 Sixel capability not detected in foot + tmux (found by @amigthea). github#236 Ghostty shows pwd/lock indicator when using Chafa (found by Eduard Rozenberg). github#238 Sixel image quality significantly different from img2sixel and ImageMagick (found by Rashil Gandhi). github#239 Chafa leaves echo on (found by @veltza). github#245 JPEG file not recognized (found by Lionel Dricot). github#246 Examples using deprecated functions (found by @sechshelme). github#249 Sixel detection doesn't set default values (found by @veltza). github#254 -t 1 doesn't work with -f iterm (@AnonymouX47). github#255 Animations scroll/walk up the screen (found by @AnonymouX47). github#265 Enable Kitty image protocol for Warp (found by Soham Parmar). github#266 On Windows, in a cmd.exe window, filename wildcard expansion is broken (found by @garoto). github#273 -t 1 messes up some images (found by @AnonymouX47). github#274 -f {kitty,iterm} swaps BG color channels for SVG (found by @AnonymouX47). github#278 Images not always padded to cell boundary (found by @veltza). [unfiled] Fix broken bashisms resulting in logic failure (Eli Schwartz). [unfiled] Small leak in chafa_canvas_print_rows() (@korei999). [unfiled] Uninitialized histogram in nearest-neighbor interp. 1.14.5 (2024-11-03) ------------------- This release addresses a handful of medium-severity bugs. * Bug fixes: github#217 Improve sixel and general terminal support inside tmux (found by Steven Walton). github#221 Support JPEGs with CMYK color space (found by Lionel Dricot). github#225 Fix --font-ratio doing nothing (found by @johnd0e). [unfiled] Ensure CLI tool gets linked with libm. 1.14.4 (2024-09-10) ------------------- This quick follow-up release corrects the incomplete fix for the CLI argument fraction parsing. It now accepts C locale formatting in addition to that of the current locale. * Bug fixes: github#216 Dither intensity does not work properly (found by @veltza). 1.14.3 (2024-09-09) ------------------- This release brings important fixes for sixel rendering and Windows Terminal, plus a few other odds and ends. * Sixel transparency has been reenabled for still frames. Animations will be pre-composited on an opaque background to prevent flicker/glitchiness (discussed in github#211, big thanks to James Holderness). * Now supports the Ghostty terminal, defaulting to the Kitty graphics protocol there. * Bug fixes: github#185 Chafa version 1.14 breaks image preview on lf (found by @Steven79203). github#210 Crash with -f sixels (found by Chris Antos). github#211 Sixels are too small in Windows Terminal (found by @veltza). github#212 Aspect-preserving calculations are off in some cases. [unfiled] Inconsistent fraction parsing in CLI arguments. [unfiled] A few small memory leaks in the JPEG XL loader. 1.14.2 (2024-07-26) ------------------- This is a bugfix release. github#205 is particularly serious, since it affects many users on distributions that build with LTO enabled. * Bug fixes: github#203 Chafa 1.14.1 fails to build on i686 (reported by @tranzystorekk). github#205 Symbols mode not working since 1.14.1 (reported by Folke Lemaitre). github#206 Crash when importing more than 32767 glyphs (reported by @stgiga). [unfiled] Fix erroneous base64 encoding of final byte in some circumstances. 1.14.1 (2024-06-17) ------------------- This release brings bug fixes, compatibility improvements and some performance enhancements. * A JPEG XL (.jxl) loader was added using libjxl (github#188, @oupson). * Added detection of the Eat "Emulate a Terminal" Emacs terminal (Simon Law). * Symbols mode was sped up significantly on AVX2-capable platforms. * Tests: A new test driver was added. It will log the specifics of any failures, which aids debugging of CI builds (issue found by Mo Zhou). * Bug fixes: github#189 Fix installation of zsh completions (Felix Yan). github#190 Fix a small memory leak in ChafaCanvas (found by @jstkdng). github#192 Wrong sixel padding in some circumstances (found by @dnkl). github#195 tmux passthrough enabled when already set (found by Ron Lau). github#196 iTerm mode not enabled automatically (found by @sudo-burger). 1.14.0 (2024-01-08) ------------------- This is a feature release with mostly practical improvements and bug fixes. It also adds a modest amount of new API in preparation for things to come. * Removed ImageMagick loader support. Packagers can now remove this dependency (github#157). * Polite mode is now off by default. The new default eliminates cursor flicker and makes the output more robust against unusual terminal settings. The old behavior can be restored with "--polite on". * Added image loaders for the AVIF and QOI formats. Thanks to @jerch for suggesting the latter. * sRGB gamma is now handled correctly in scaling operations. * New option: --passthrough=. This allows passing graphics protocols like Sixels, iTerm and Kitty through a terminal multiplexer. It will be enabled automatically for Kitty, and can be enabled manually for other protocols with more limited support (github#116, github#162, thanks to Samantha Collins and @m040601). * New option: --view-size=. Specifies width and height of the viewport, overriding the detected terminal size (github#140, reported by Jamin Thornsberry). * New option: --fit-width. Fits images to the width of the viewport, allowing them to be taller than the viewport's height (github#115, thanks to @SuperDuperDeou). * New option: --relative=. Enables relative cursor positioning. Useful if you've pre-positioned the cursor at a particular offset where you want frames to appear, but tends to make the output illegible in pagers, e.g. 'less -R' (github#146, thanks to @Delgan and @AnonymouX47). * New option: --exact-size=. Preserves the input pixel size when possible. Useful to avoid artifacts caused by resampling (github#119, reported by @ErrorNoInternet). * New symbol selector: "imported". This selects glyphs loaded with --glyph-file (github#124, reported by @clort81). * MS Windows: Experimental support for ConHost output (-f conhost). This allows direct output on older versions of MS Windows (github#170, @oshaboy). * Fontgen: Added a BDF font writer (Mo Zhou). * Fontgen: Cleanup and modernization (Mo Zhou). * The help text and manual page were overhauled for readability, and the API documentation now includes symbol indexes by version and deprecation status. * Added a zsh completion script (Wu Zhenyu). * Installation methods added: Scoop (Launch Lee) and Winget (@sitiom). * CI: Ported to GitHub actions (Erica Ferrua Edwardsdóttir). * Bug fixes: github#107 "Unknown file format" when using AVIF on stdin (found by @ndren). github#152 Broken linking with libwebp-1.3.1 (found by Vladimír Čunát). [unfiled] Fix make check with --without-tools (Samuel Thibault). [unfiled] Fix --duration not working well with still images (@Delgan). [unfiled] Fix sixel rendering of animations (@Delgan). [unfiled] Fix operator precedence in geometry calculation (Johan Mattsson). 1.12.5 (2023-05-21) ------------------- This is a bugfix release. * Bug fixes: github#123 Crash on canvas created with chafa_canvas_new_similar() (reported by Erica Ferrua Edwardsdóttir). github#141 Distortion when rowstride is not a multiple of 4 (reported by @jstkdng). [unfiled] Missing comma in --help output (reported by @Freed-Wu). 1.12.4 (2022-11-12) ------------------- This release improves support for Microsoft Windows and fixes several bugs. * MS Windows: Added support for Unicode command-line arguments. * MS Windows: Enabled support for building a DLL. * Improved quality of accelerated symbol picking (the default with -w 6 and lower), especially along sharp edges. * The XWD loader now supports unaligned image data, which can occur when the header is of an uneven length. Such images will no longer be rejected. * Bug fixes: github#100 Reading image data from stdin fails on Windows (reported by @TransparentLC). github#104 Artifacts with transparent animations on Kitty (reported by Akash Patel). github#112 Bad documentation for -c default (reported by Jakub Wilk). github#113 Autogen/build fails on CentOS 7 (partial solution) (reported by Ivan Shatsky). huntr.dev Uncontrolled memory allocation in lodepng (reported by @JieyongMa). [unfiled] -lm should not be in pkg-config Libs: list (Tomasz Kłoczko). [unfiled] The --watch switch was broken with the introduction of --animate. 1.12.3 (2022-07-01) ------------------- A bug crept into the previous release that prevented successful package builds in some environments. This has been fixed. * Increased GLib minimum version to 2.26. * Enabled a few compiler warnings not included in '-Wall -Wextra' in order to catch more potential issues early. Also started using '-Werror' selectively. * Silenced deprecation warnings for older GLib APIs that we would like to keep using a bit longer. * Bug fixes: github#96 Regression: Fails to build on Linux/Debian (reported by Mo Zhou). 1.12.2 (2022-06-28) ------------------- This release adds basic support for Microsoft Windows. * Made everything compile for the x86_64-w64-mingw32 target using gcc. * Added support for the Windows 10 Command Prompt. * Improved error reporting. 1.12.1 (2022-06-20) ------------------- This release fixes one important input validation bug and several instances of undefined behavior revealed by fuzzing. * Increased GLib minimum version to 2.20. * Added 12 new test inputs, including bad inputs to handle gracefully. * Added a few symbols to API documentation that were accidentally left out. * Bug fixes: huntr.dev CVE-2022-2061: Out-of-bounds read in libnsgif's lzw_decode() (Sudhakar Verma of CrowdStrike). [unfiled] Undefined behavior in libnsgif due to uninitialized frame fields. [unfiled] Signed integer overflow in chafa_pack_color(). [unfiled] Integer overflow in normalization pass on some images. [unfiled] Potential unaligned access with corrupt XWD images. [unfiled] Integer overflow in quantization on some images. [unfiled] Calculating offset from NULL pointer in LodePNG. 1.12.0 (2022-06-06) ------------------- This is a feature release with new image loaders aimed at phasing out ImageMagick. It also has new convenience functions, character art improvements, tests and bug fixes. Special thanks go to the very fine security researchers at huntr.dev for their help in hardening Chafa over the last few releases. * The ImageMagick dependency is now optional and deprecated. Packagers are encouraged to drop the ImageMagick dependency (--without-imagemagick) and add direct dependencies on relevant image codecs. ImageMagick support will be removed in a future release. * Added image loaders for the following formats: JPEG, SVG, TIFF, WebP. Like the existing GIF, PNG and XWD loaders, these are much faster and generally safer than their ImageMagick counterparts. If ImageMagick is enabled, it will be used as a fallback. Supported image loaders will be listed in the --version output. * Implemented a 16/8 mode producing 8 colors and an additional 8 bright foreground-only colors for a total of 16 foreground and 8 background colors. When using ANSI escape sequences in symbol mode, the sequence for bold text is used to enable bright colors. This scheme corresponds to that of the IBM PC's VGA hardware text modes and was popular with terminal emulators in the late 1980s to early 2000s. With a few tweaks, output from this mode can be turned into ANSI art scene .ANS files compatible with utilities like the wonderful Ansilove, e.g: $ chafa -f symbols -c 16/8 -s 80 --symbols space+solid+half --fill stipple \ in.jpg | tr -d '\n' | iconv -c -f utf8 -t cp437 > out.ans $ ansilove out.ans -o out.png * New builtin Latin symbols (available with --symbols latin). This class comprises most of the symbols from the Latin-1 Supplement, Latin Extended-A and -B, IPA Extensions and Spacing Modifier Letters plus a few Latin-like symbols from other ranges, using Terminus as the reference font. The ASCII class is also a subset of this class. * Reworked ASCII symbols to be more representative of modern terminal fonts. As with the other Latin ranges, the reference font is now Terminus. * New option: --scale . This takes a real number specifying the on-screen scaling factor relative to the input's pixel size, respecting the terminal size. The special argument 'max' will fit the output to the terminal. The defaults are 1.0 for iTerm, Kitty and sixels, and 4.0 for symbols. Suggested by Lionel Dricot in github#84. * Deprecated option: --zoom. Use '--scale max' instead. * Added a battery of simple tests that can be run with 'make check'. * Made 'configure' friendlier. It's now more lenient with dependencies, and the summary is more detailed and colorized if possible. * Bug fixes: github#62 Too big alloc on bogus terminal dimensions (reported by Sotiris Papatheodorou and Mo Zhou). huntr.dev Null pointer dereference caused by calling post_func on unused batch entries (reported by @han0nly). [unfiled] Small memory leaks when using iTerm and Kitty formats. [unfiled] Wide symbol coverages leaked in symbol map destructor. [unfiled] No error code if files failed to load. 1.10.3 (2022-05-04) ------------------- This release fixes multiple input validation issues. These were found in the 'chafa' command-line tool and do not affect the library backend. * Improved input validation in the XWD loader. * Bug fixes: huntr.dev Buffer over-read when compiled with -O0 or non-x86 target (reported by @JieyongMa). 1.10.2 (2022-04-25) ------------------- This release adds security/responsible disclosure guidelines and fixes a few issues with input validation in the 'chafa' command-line tool. * Added disclosure guidelines in SECURITY.md (suggested by Jamie Slome). * Bug fixes: huntr.dev Null pointer dereference in libnsgif with crafted GIF file (reported by @JieyongMa). [unfiled] File magic would not effectively rule out internal loaders. [unfiled] Very big images could cause absurd allocation requests triggering an abort in the loader. 1.10.1 (2022-04-04) ------------------- This release brings one small but important fix and a few minor corrections to the documentation. * Bug fixes: github#87 Garbled last row of pixels on some images (found by @hydrargyrum). [unfiled] Correctly label new functions since 1.10. 1.10.0 (2022-03-20) ------------------- This is a feature release focused on compatibility, presentation and ergonomics. * New option: --animate . On by default. Can be turned off to replace animations with a still frame. Suggested by Lionel Dricot in github#79. * New option: --center or -C . Off by default. Can be turned on to center images. Suggested by Lionel Dricot in github#83. * New options: --margin-bottom and --margin-right . These permit using all available space (with --margin-bottom 0) or some smaller amount. Suggested by @crmabs in github#61. * New option: --polite . On by default. Can be turned off to correct issues caused by previous terminal state (e.g. no sixel scrolling) and improve presentation (e.g. by temporarily hiding the cursor). This can leave the terminal in an altered state, which is somewhat rude. * New option: --threads . Allows manually specifying the number of threads to use. Defaults to one per detected logical CPU core. * When invoked with redirected input and no arguments, act like a filter as if invoked with "-". Here's an example that downloads an image, converts it to Unicode text and mails it to hello@example.com: $ curl https://hpjansson.org/chafa/img/lc.jpg \ | chafa -f symbols -c none -s 77 --invert --dither bayer \ | mailx hello@example.com * If input or output is being redirected, default to playing animations only once instead of looping forever. This can be overridden with '-d inf'. * Replaced obsolete Autoconf macros (Mikel Olasagasti Uranga). * Improved image loaders: - GIF: Load GIF87a images as well as GIF89a. - PNG: Add an internal copy of LodePNG, bypassing ImageMagick. This improves performance and helps with eventually phasing out the latter. - XWD: Support images generated by 'convert'. * Improved terminal support: - Contour: Enable sixel support (Dmitry Atamanov). - foot: Open-ended TERM string matching (Daniel Eklöf). - Konsole: Enable sixel support (Dmitry Atamanov). - WezTerm: Enable sixel support. * Bug fixes: github#76 Smolscale uses too much stack space (found by Hoang Nguyen). github#81 Chafa --version is returned to stderr, not stdout (found by Lionel Dricot). [unfiled] Potential memory overrun when using Floyd-Steinberg dithering in symbols mode. [unfiled] iTerm2 compatibility issue with WezTerm and possibly others. 1.8.0 (2021-08-31) ------------------ This is a major feature release. * Added basic support for the Kitty and iTerm2 graphics protocols. These are enabled automatically when corresponding terminal support is detected, or manually with '-f kitty' or '-f iterm'. * Implemented an 8-color mode, selectable with '-c 8' (Øyvind Kolås). * Implemented a foreground-only switch, '--fg-only'. This produces character art using foreground colors only, and will avoid modifying or resetting the background color. Looks best with non-contiguous symbols (e.g. ascii). * Added builtins for Japanese kana fullwidth symbols. These can now be used without loading any external fonts (try '-c none --symbols wide'). * Added builtins for legacy computer symbols (mainly wedges and sextant blocks). These were widely used in PETSCII and Teletext, and can be enabled using --symbols or --fill with their respective tags: legacy, wedge and sextant (Øyvind Kolås). * Since there is a growing number of builtin symbols that may not be available everywhere, the default selection has been restricted to the widely supported block and border sets. * If possible, we now select a visually blank character from the specified symbol/fill sets instead of hardcoding ASCII space for featureless cells. One practical upshot of this is that the constant-width braille range can be used to produce consistent images even in contexts with variable-width fonts. U+2800 (BRAILLE PATTERN BLANK) will then be used in blank cells. * Improved terminal size detection when used with pipelines and redirection. This should now produce an image properly sized for your terminal: $ curl https://i.imgur.com/WFDEFVg.jpeg | chafa - | tee out * ChafaCanvas gained API functions for programmatically getting and setting character cell contents. These are used in a new example in tests/ncurses.c demonstrating ncurses integration. * Made --disable-rpath the default in order to simplify packaging. * Added a HACKING file featuring a much needed release checklist. * Improved terminal support: - Ctx will now use optimizing REP sequences at high -O levels. - foot now defaults to sixels (Daniel Eklöf). - iTerm2 now defaults to the iTerm2 protocol. - Kitty now defaults to the Kitty protocol. - st now defaults to truecolor symbols (Roman Wagner). * Bug fixes: github#44 Missing error handling on stdout writes (reported by Markus Elfring). [unfiled] Solid symbols erroneously replaced by fill in FGBG mode. [unfiled] Integer formatter was not using fast path for 8-bit values. [unfiled] Wrong default cell aspect used for sixel graphics. 1.6.1 (2021-06-03) ------------------ This is a bugfix release. * Add NOCONFIGURE variable to autogen.sh to skip configure (Biswapriyo Nath). * Bug fixes: github#50 SIGBUS while loading huge GIFs (reported by Grzegorz Koperwas). github#52 Produces small glitches in output with some images (reported by Sami Farin). github#54 Haiku port fails on 32bit (Luc Schrijvers). [unfiled] Exclude RTL code points that could break the output. [unfiled] Apple Terminal lacks truecolor support, so make it default to 256 colors (reported by Behdad Esfahbod). [unfiled] Fix typo affecting middle dot symbol. 1.6.0 (2021-01-15) ------------------ This release adds major features and important fixes to both libchafa and the chafa command-line tool. * Added support for fullwidth symbols that take up two character cells. These are common in East Asian scripts. Single-cell and double-cell symbols can be mixed, and -f symbols mode will use both if possible. * New symbol tags: Alpha, digit, alnum, narrow, wide, ambiguous, ugly, bad. "Ambiguous" symbols have uncertain widths and may render poorly in some terminals. "Ugly" denotes symbols that are unsuitable for Chafa's cell-based graphics (multicolor emoji, ideographic descriptors, etc). "Bad" is a superset of these two categories. Bad symbols are always excluded unless explicitly enabled with e.g. CHAFA_SYMBOL_TAG_BAD (--symbols +bad in the frontend). * The font loader (--glyph-file option) now does a better job with proportional fonts. * Added options for controlling lossless optimization of output. Currently, attribute reuse and character repetition (REP sequence) are implemented. * Added -O option to the frontend. This controls the optimization level. * Added a simple abstraction layer for terminal control sequences (ChafaTermInfo and ChafaTermDb). This allows for improved terminal support. * FbTerm is now supported with TERM=fbterm in the environment. * Bug fixes: github#43 Fix signal handler (reported by Markus Elfring). [unfiled] Crash when invalid font paths were passed on command line. [unfiled] Small typo in fontgen's README (Tim Gates). [unfiled] Bad contrast adjustment in images with transparency. 1.4.1 (2020-04-10) ------------------ This is a bugfix release. * Added configure option --disable-rpath. This allows packagers to prevent the hard-coded library search path from being embedded in the chafa command-line tool (Mo Zhou, github#39). * Added defaults for the yaft terminal. * Bug fixes: github#40 Fails to build on hurd-i386 + other i386 (reported by Mo Zhou). [unfiled] Rare failed assert with mostly transparent sixel image (reported by Reddit user spryfigure). [unfiled] Minor typo in function docstring. 1.4.0 (2020-04-01) ------------------ This release adds major features to both libchafa and the chafa command-line tool. * Added sixel graphics support. Chafa will automatically produce sixels if the connected terminal supports it. It can also be forced using the new -f or --format flag. This is a new implementation written from the ground up to maximize throughput. * Added the --glyph-file option, which loads glyph-symbol mappings from any file format supported by FreeType (TTF, PCF, etc). This allows for custom font support and improved symbol selection. * Added the --speed option specifying animation speed. It accepts a unitless multiplier, a specific number of frames per second, or "max" for maximum throughput. * There are now two ways to assign colors to symbol cells. Formerly, this was done based on the average color of the covered area. The new default is to use the median color, which produces sharper edges, but is slightly more prone to high-frequency noise. The new option --color-extractor selects the method to employ. * When displaying multiple files, the default delay between files has been changed from three seconds to zero. Animations will still play through once. This can be overridden on the chafa command line with -d or --duration. * Minor tweaks to built-in symbols. * Performance improvements: - Halved pixel storage requirements from 64 bits to 32 bits, resulting in significant memory savings. - Now builds with -ffast-math, yielding a big speedup for DIN99d. 1.2.2 (2020-03-02) ------------------ This minor release fixes a bug causing builds linking with libchafa to fail. * Bug fixes: github#34 Cannot compile example (found by Petr Bílek). 1.2.1 (2019-08-15) ------------------ This minor release fixes a few bugs and improves terminal detection. * Detect kitty and mlterm virtual terminals and apply optimal defaults accordingly. * Make Automake build more strict and fix a few compatibility nits. * Bug fixes: github#30 Failed to build on hurd-i386 (found by Mo Zhou). [unfiled] Crash on certain broken GIFs. 1.2.0 (2019-08-04) ------------------ This is a feature and performance release. * Added --dither, --dither-grain and --dither-intensity options. These allow for sub-cell dithering in quantized modes (none, 2, 16, 240 and 256). Especially beneficial when used with -p off. * Added API for ordered and diffusion-based dithering in quantization. * Added API support for multiple 8bpc pixel modes: RGB, BGR, RGBA, BGRA, ARGB, ABGR with either premultiplied or unassociated alpha channels. * Smooth scaling is now done internally, meaning libchafa consumers no longer need to prescale images. * Implemented a machine learning tool that can generate custom fonts for efficient image reproduction from a provided dataset. This is left uninstalled since it's still experimental (Mo Zhou). * Throughput improvements: - GIF animations now start playing instantly. - GIF CPU overhead reduced by 75%, peak memory use down 95%-99% (!). - XWD common case CPU overhead down 60-70%, peak memory down 70%. - Additional halving of CPU overhead in 240- and 256-color modes. - Streamlined pixel pipeline for better parallelization. * Installation instructions: - New: Guix (Guy Fleury Iteriteka). - New: openSUSE (Michael Vetter). * Bug fixes: [unfiled] Certain SVGs had transparency replaced with a white background (nemo). [unfiled] -lm dependency belongs in libchafa, not frontend. 1.0.1 (2018-12-18) ------------------ * Bug fixes: [unfiled] Bad geometry calculation when specifying one dimension and omitting the other. 1.0.0 (2018-12-16) ------------------ This release adds features, greatly improves performance and fixes several bugs. Programs written for the command line and libchafa interfaces in this release will be supported by future versions in the 1.y.z series without the need for modification or recompilation. * Added ability to specify "fill" symbols to use as halftone for better color approximation. This can be used to augment the regular symbol selection or to replace it (with --symbols none) for a different, purely intensity-based effect. * Improved preprocessing in 2-color and 16-color modes. This is optional (default: on) and consists of a contrast boost and, for the 16-color mode, an additional saturation boost. The new implementation lives in libchafa and does not rely on ImageMagick. It is multithreaded, and due to its specialized nature, much faster. * Added --watch option to continuously monitor a file. * Added more symbols: - Most of the ASCII range. - Braille range (github#2, thanks to Adam Borowski). - Miscellaneous math and scanline symbols. - More geometric symbols (black circle, triangles) (Mo Zhou). * Throughput improvements: - Fast symbol candidate set reduction by median cut. - Parallel processing with threads. - Prescaling using bilinear interpolation instead of lanczos. * Installation instructions: - New: Arch (github#12, Felix Yan). - New: Debian testing/unstable (github#9, Mo Zhou). - New: Fedora (github#14, Ricardo Arguello). - Mention missing dependency for Debian (github#13, @medusacle). * Bug fixes: github#1 -c none produces pointless \e[0m after every line (found by Adam Borowski). github#3 Compile error (found by Lajos Papp). github#4 AM_PROG_LIBTOOL is obsolete, replace it with LT_INIT (Robert-André Mauchin). github#5 Port chafa to i386 architecture (Mo Zhou). github#7 Chafa should not return an error when being asked for --version (Mo Zhou). github#10 Fix detection of MagickWand methods (Felix Yan). github#11 ImageMagick 7 support (found by Felix Yan). github#21 chafa.c:547: pointless assignment (found by @dcb314). 0.9.0 (2018-04-24) ------------------ Initial release. chafa-1.18.2/README000066400000000000000000000056071517447374300135540ustar00rootroot00000000000000Chafa ===== Chafa is a command-line utility that converts image data, including animated GIFs, into graphics formats or ANSI/Unicode character art suitable for display in a terminal. It has broad feature support, allowing it to be used on devices ranging from historical teleprinters to modern terminal emulators and everything in between. The core functionality is provided by a C library with a public, well-documented API. Both library and frontend tools are covered by the Lesser GPL license, version 3 or later (LGPLv3+). For the most up-to-date information, please see https://hpjansson.org/chafa/ Installing with package manager ------------------------------- Chafa is available as packages for many software distributions. A few are listed below, along with their command-line installation instructions: Arch Linux .... pacman -S chafa Brew .......... brew install chafa Debian ........ apt install chafa Fedora ........ dnf install chafa FreeBSD ....... pkg install chafa Gentoo ........ emerge media-gfx/chafa Guix .......... guix install chafa Kali Linux .... apt install chafa MacPorts ...... port install chafa OpenBSD ....... pkg_add chafa openSUSE ...... zypper in chafa Ubuntu ........ apt install chafa On Windows, Chafa can be installed via Scoop and Winget: Scoop ....... scoop install chafa Winget ....... winget install hpjansson.Chafa See https://hpjansson.org/chafa/download/ for more. Installing from tarball ----------------------- You will need GCC, make and the GLib development package installed to compile Chafa from a release tarball. If you want to build the command-line tool `chafa` and not just the library, you will additionally need the ImageMagick development packages. Prebuilt documentation is included in the release tarball, and you do not need gtk-doc unless you want to make changes/rebuild it. After unpacking, cd to the toplevel directory and issue the following shell commands: $ ./configure $ make $ sudo make install Installing from git repository ------------------------------ You will need GCC, make, Autoconf, Automake, Libtool and the GLib development package installed to compile Chafa from its git repository. If you want to build the command-line tool `chafa` and not just the library, you will additionally need development packages for: * FreeType2 * libjpeg (optional) * librsvg (optional) * libtiff (optional) * libwebp (optional) * ImageMagick (optional, deprecated) If you want to build documentation, you will also need gtk-doc. Start by cloning the repository: $ git clone https://github.com/hpjansson/chafa.git Then cd to the toplevel directory and issue the following shell commands: $ ./autogen.sh $ make $ sudo make install Python bindings --------------- Erica Ferrua Edwardsdóttir maintains excellent Python bindings for Chafa. If Python's your thing, check them out. They are easy to use and come with a detailed tutorial: https://chafapy.mage.black/ chafa-1.18.2/README.md000066400000000000000000000072261517447374300141520ustar00rootroot00000000000000

Master Build Status Latest Release Friendly Chat

About • Gallery • Packages • Development

## About Chafa is a command-line utility that converts image data, including animated GIFs, into graphics formats or ANSI/Unicode character art suitable for display in a terminal. It has broad feature support, allowing it to be used on devices ranging from historical teleprinters to modern terminal emulators and everything in between. The core functionality is provided by a C library with a public, well-documented API. Both library and frontend tools are covered by the Lesser GPL license, version 3 or later (LGPLv3+). The [official web pages](https://hpjansson.org/chafa/) and [C API documentation](https://hpjansson.org/chafa/ref/) can be found online. Check out the [gallery](https://hpjansson.org/chafa/gallery/) for screenshots. ## Installing Chafa is most likely packaged for your distribution, so if you're not going to hack on it, you're better off using [official packages](https://hpjansson.org/chafa/download/). If you want to build the latest and greatest yourself, read on. You will need GCC, make, Autoconf, Automake, Libtool and the GLib development package installed to compile Chafa from its git repository. If you want to build the command-line tool `chafa` and not just the library, you will additionally need development packages for: * FreeType2. Often packaged as `libfreetype6-dev` or `freetype2-devel`. * libjpeg (optional). Look for `libjpeg-dev`, `libjpeg62-devel` or `libjpeg8-devel`. * librsvg (optional). Look for `librsvg2-dev` or `librsvg-devel`. * libtiff (optional). Look for `libtiff5-dev` or `libtiff-devel`. * libwebp (optional). Look for `libwebp-dev` or `libwebp-devel`. If you want to build documentation, you will also need gtk-doc. Start by cloning the repository: ```sh $ git clone https://github.com/hpjansson/chafa.git ``` Then cd to the toplevel directory and issue the following shell commands: ```sh $ ./autogen.sh $ make $ sudo make install ``` That should do it! ## Python bindings [Erica Ferrua Edwardsdóttir](https://mage.black/) maintains [excellent Python bindings](https://chafapy.mage.black/) for Chafa. If Python's your thing, check them out. They are easy to use and come with a [detailed tutorial](https://chafapy.mage.black/usage/tutorial.html). ## JavaScript bindings [Héctor Molinero Fernández](https://hector.molinero.dev/) maintains [wonderful JavaScript bindings](https://github.com/hectorm/chafa-wasm) built around his WebAssembly port. These are available from NPM and can be used in Node.js, web browsers, and more. chafa-1.18.2/SECURITY.md000066400000000000000000000026371517447374300144650ustar00rootroot00000000000000# Security Policies and Procedures This document outlines security procedures and general policies for Chafa. ## Reporting a Bug We are grateful for the testing and analysis carried out by the community. All bug reports are taken seriously. Normally, bugs can be filed directly in the public GitHub issue tracker, but if you believe there is a security impact, please contact the lead maintainer at his e-mail address instead. We will most likely respond within 48 hours, but since Chafa is a volunteer project, please allow up to a week for those rare times we're away from the keyboard or general connectivity. When a fix is published, you will receive credit under your real name or bug tracker handle in the NEWS document and possibly elsewhere (GitHub, blog post, etc). If you prefer to remain anonymous or pseudonymous, you should mention this in your e-mail. ## Disclosure Policy The maintainer will coordinate the fix and release process, involving the following steps: * Confirm the problem and determine the affected versions. * Audit code to find any potential similar problems. * Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible. You may be asked to provide further information in pursuit of a fix. ## Comments on this Policy If you have suggestions on how this process could be improved, please submit an issue or pull request. chafa-1.18.2/TODO000066400000000000000000000061131517447374300133550ustar00rootroot00000000000000TODO ==== If you're particularly interested in any of this, send patches/pull requests or maybe just prod me a little. Minor Features/UX ----------------- - Accept -o, --output to write to file. - Add a --test option to print a test page. - Add a --show-symbols op to print matching symbols. - If FG color is transparent, see if we can use an inverted symbol and swap with BG. - Avoid using transparent foreground due to XFCE Terminal (other terminals?) weird handling with background picture set? - Except in FGBG modes. - Test with more terminals. - PuTTY on Windows 10? - Terminology. - Emulate tycat. - Emacs ansi-term. - Emacs shell (TERM=dumb). - Come up with some kind of support matrix. - More symbols/symbol aliases: - CP437. - Output to retro art formats: - RexPaint. - lvllvl.com. - CharPad/CharPad Pro. - Marq's PETSCII Editor (http://www.kameli.net/marq/?page_id=2717). - PabloDraw. - ANSILove (direct to .ANS, other formats?). - Others? - More image loaders: - BMP. The GIMP has a fairly complete decoder. - XPM. https://en.wikipedia.org/wiki/X_PixMap - PBM, PGM, PPM. https://en.wikipedia.org/wiki/Netpbm - Run image decoders (and Chafa backend?) in sandboxed subprocess. Major features -------------- - Selection from multiple internal named font bitmap sets (IBM, C64, etc). - Custom palettes. - External (e.g. in GIMP format, or extract from image) or named internal. - Using different palettes for BG and FG allows for retro modes like the C64's Extended Color Character Mode (ECM). - Pixmap export (raw image buffer from backend, PNG or TIFF export in frontend). - Lossy/lossless intra-frame compression. Data rate regulated: - By desired output size. - By maximum desired per-cell error. - By total error? - Slide window over row, calculate mean colors, calc error? - Lossy/lossless delta compression. - Double-buffer with a checkpoint call to swap. - Dirty map not enough in case each frame is composited in multiple steps. - Emit difference between checkpoint state and current. - Optimization: Keep a rect or region of changed area. - Multiply previous symbol's new error with weight to increase or decrease stability (prevent flicker)? - Drawing context with clip rect/region, etc. - Potentially a context stack. - Getting into NCurses territory... - Video playback. - Interactive UI (may need to be in separate tool). Optimization ------------ - Preload next image/frame in delay phase. - Don't calculate error if we're only using a single symbol (e.g. vhalf). The Fine Material ----------------- - Tips. - For scrolling, use e.g. chafa input.jpg -s 200 | less -S - Rate-controlled playback with e.g. cat input.txt | pv -qL 100k - X11 applications in terminal $ Xvfb :99 -ac -fbdir t -screen 0 1440x900x24 & $ DISPLAY=:99 lament -root & $ chafa --watch t/Xvfb_screen0 - gnome-shell in terminal $ XDG_SESSION_TYPE=x11 DISPLAY=:99 gnome-shell - Run as different user. - Using (unreleased) ffmpeg driver: $ ./ffmpeg -i movie.mkv -pix_fmt rgba -f chafa -color 16 -symbols vhalf,space -fill ascii - chafa-1.18.2/acinclude.m4000066400000000000000000000073331517447374300150630ustar00rootroot00000000000000# From GLib. # # Checks the location of the XML Catalog # Usage: # JH_PATH_XML_CATALOG([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # Defines XMLCATALOG and XML_CATALOG_FILE substitutions AC_DEFUN([JH_PATH_XML_CATALOG], [ # check for the presence of the XML catalog AC_ARG_WITH([xml-catalog], AS_HELP_STRING([--with-xml-catalog=CATALOG], [path to xml catalog to use]),, [with_xml_catalog=/etc/xml/catalog]) jh_found_xmlcatalog=true XML_CATALOG_FILE="$with_xml_catalog" AC_SUBST([XML_CATALOG_FILE]) AC_MSG_CHECKING([for XML catalog ($XML_CATALOG_FILE)]) if test -f "$XML_CATALOG_FILE"; then AC_MSG_RESULT([found]) else jh_found_xmlcatalog=false AC_MSG_RESULT([not found]) fi # check for the xmlcatalog program AC_PATH_PROG(XMLCATALOG, xmlcatalog, no) if test "x$XMLCATALOG" = xno; then jh_found_xmlcatalog=false fi if $jh_found_xmlcatalog; then ifelse([$1],,[:],[$1]) else ifelse([$2],,[AC_MSG_ERROR([could not find XML catalog])],[$2]) fi ]) # From GLib. # # Checks if a particular URI appears in the XML catalog # Usage: # JH_CHECK_XML_CATALOG(URI, [FRIENDLY-NAME], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) AC_DEFUN([JH_CHECK_XML_CATALOG], [ AC_REQUIRE([JH_PATH_XML_CATALOG],[JH_PATH_XML_CATALOG(,[:])])dnl AC_MSG_CHECKING([for ifelse([$2],,[$1],[$2]) in XML catalog]) if $jh_found_xmlcatalog && \ AC_RUN_LOG([$XMLCATALOG --noout "$XML_CATALOG_FILE" "$1" >&2]); then AC_MSG_RESULT([found]) ifelse([$3],,,[$3 ])dnl else AC_MSG_RESULT([not found]) ifelse([$4],, [AC_MSG_ERROR([could not find ifelse([$2],,[$1],[$2]) in XML catalog])], [$4]) fi ]) # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS chafa-1.18.2/autogen.sh000077500000000000000000000060531517447374300146710ustar00rootroot00000000000000#!/bin/sh # Run this to generate all the initial makefiles, etc. srcdir=`dirname $0` test -z "$srcdir" && srcdir=. ORIGDIR=`pwd` cd $srcdir PROJECT=chafa TEST_TYPE=-f FILE=chafa/Makefile.am DIE=0 MISSING_TOOLS= MY_ECHO=$(which echo) [ x$MY_ECHO = x ] && MY_ECHO=echo SGR0=$(tput sgr0 2>/dev/null) SETAF1=$(tput setaf 1 2>/dev/null) SETAF3=$(tput setaf 3 2>/dev/null) (autoconf --version) < /dev/null > /dev/null 2>&1 || { MISSING_TOOLS="${MISSING_TOOLS}autoconf " DIE=1 } (automake --version) < /dev/null > /dev/null 2>&1 || { MISSING_TOOLS="${MISSING_TOOLS}automake " DIE=1 } (libtoolize --version || glibtoolize --version) < /dev/null > /dev/null 2>&1 || { MISSING_TOOLS="${MISSING_TOOLS}libtool " DIE=1 } (pkg-config --version) < /dev/null > /dev/null 2>&1 || { MISSING_TOOLS="${MISSING_TOOLS}pkg-config " DIE=1 } if test "$DIE" -eq 1; then ${MY_ECHO} ${MY_ECHO} "Missing mandatory tools:${SETAF1} $MISSING_TOOLS" ${MY_ECHO} "${SGR0}" ${MY_ECHO} "These are required for building Chafa from its git repository." ${MY_ECHO} "You should be able to install them using your operating system's" ${MY_ECHO} "package manager (apt-get, yum, zypper or similar). Alternately" ${MY_ECHO} "they can be obtained directly from GNU: https://ftp.gnu.org/gnu/" ${MY_ECHO} ${MY_ECHO} "If you can't provide these tools, you may still be able to" ${MY_ECHO} "build Chafa from a tarball release: https://hpjansson.org/chafa/releases/" ${MY_ECHO} fi if test "$DIE" -eq 1; then exit 1 fi test $TEST_TYPE $FILE || { ${MY_ECHO} ${MY_ECHO} "You must run this script in the top-level $PROJECT directory." ${MY_ECHO} exit 1 } if test x$NOCONFIGURE = x && test -z "$*"; then ${MY_ECHO} ${MY_ECHO} "I am going to run ./configure with no arguments - if you wish " ${MY_ECHO} "to pass any to it, please specify them on the $0 command line." ${MY_ECHO} fi am_opt="--include-deps --add-missing" ${MY_ECHO} "Running libtoolize..." LIBTOOLIZE=$(which libtoolize glibtoolize 2>/dev/null | head -n1) ${LIBTOOLIZE} --force --copy GTKDOCIZE=$(which gtkdocize 2>/dev/null) if test -z $GTKDOCIZE; then ${MY_ECHO} "Missing optional tool:${SETAF3} gtk-doc" ${MY_ECHO} "${SGR0}" ${MY_ECHO} "Without this, no developer documentation will be generated." ${MY_ECHO} rm -f gtk-doc.make cat > gtk-doc.make < /dev/null 2>&1 && autoheader ${MY_ECHO} "Running automake..." automake -a $am_opt ${MY_ECHO} "Running autoconf..." autoconf cd $ORIGDIR conf_flags="--enable-maintainer-mode" if test x$NOCONFIGURE = x; then ${MY_ECHO} Running $srcdir/configure $conf_flags "$@" ... $srcdir/configure $conf_flags "$@" || exit 1 else ${MY_ECHO} Skipping configure process. fi chafa-1.18.2/chafa.pc.in000066400000000000000000000004271517447374300146620ustar00rootroot00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: Chafa Description: Image to character art facsimile Requires: glib-2.0 Version: @VERSION@ Libs: -L${libdir} -lchafa Libs.private: -lm Cflags: -I${includedir}/chafa -I${libdir}/chafa/include chafa-1.18.2/chafa/000077500000000000000000000000001517447374300137265ustar00rootroot00000000000000chafa-1.18.2/chafa/.gitignore000066400000000000000000000000451517447374300157150ustar00rootroot00000000000000/chafa-term-seq-doc.h /chafaconfig.h chafa-1.18.2/chafa/Makefile.am000066400000000000000000000037431517447374300157710ustar00rootroot00000000000000SUBDIRS = internal DISTCLEANFILES = BUILT_SOURCES = ## --- Library --- lib_LTLIBRARIES = libchafa.la noinst_LTLIBRARIES = noinst_HEADERS = libchafa_la_CFLAGS = $(LIBCHAFA_CFLAGS) $(GLIB_CFLAGS) -DCHAFA_COMPILATION libchafa_la_LDFLAGS = $(LIBCHAFA_LDFLAGS) -no-undefined -version-info 11:2:11 libchafa_la_LIBADD = $(GLIB_LIBS) internal/libchafa-internal.la -lm libchafa_la_SOURCES = \ chafa-canvas.c \ chafa-canvas-config.c \ chafa-features.c \ chafa-frame.c \ chafa-image.c \ chafa-placement.c \ chafa-symbol-map.c \ chafa-term-db.c \ chafa-term-info.c \ chafa-util.c chafaincludedir=$(includedir)/chafa chafainclude_HEADERS = \ chafa.h \ chafa-canvas.h \ chafa-canvas-config.h \ chafa-common.h \ chafa-features.h \ chafa-frame.h \ chafa-image.h \ chafa-placement.h \ chafa-symbol-map.h \ chafa-term-db.h \ chafa-term-info.h \ chafa-term-seq-def.h \ chafa-util.h \ chafa-version-macros.h # Generate header prototypes with docstrings (-CC to pass through comments) # for terminal sequence accessors. These will be processed by gtk-doc to # produce documentation. noinst_HEADERS += chafa-term-seq-doc.h chafa-term-seq-doc-in.h DISTCLEANFILES += chafa-term-seq-doc.h BUILT_SOURCES += chafa-term-seq-doc.h chafa-term-seq-doc.h: $(srcdir)/chafa-term-seq-doc-in.h $(CPP) $(CPPFLAGS) -CC $< -o $@ # Generate chafaconfig.h # # The timestamp of the stamp file is used to indicate if chafaconfig.h is # up to date with respect to config.status. In the usual case, changes # to config.status will not result in changes to chafaconfig.h, so we # avoid touching its timestamp (so we don't rebuild the whole tree). DISTCLEANFILES += chafaconfig-stamp chafaconfig.h BUILT_SOURCES += chafaconfig-stamp configexecincludedir = $(libdir)/chafa/include nodist_configexecinclude_HEADERS = chafaconfig.h chafaconfig-stamp: ../config.status $(AM_V_GEN) cd $(top_builddir) && \ $(SHELL) ./config.status chafa/chafaconfig.h @touch chafaconfig-stamp ## --- General --- AM_CPPFLAGS = \ -I$(top_srcdir) chafa-1.18.2/chafa/chafa-canvas-config.c000066400000000000000000000654141517447374300176620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* memset, memcpy */ #include "chafa.h" #include "internal/chafa-private.h" /** * SECTION:chafa-canvas-config * @title: ChafaCanvasConfig * @short_description: Describes a configuration for #ChafaCanvas * * A #ChafaCanvasConfig describes a set of parameters for #ChafaCanvas, such * as its geometry, color space and other output characteristics. * * To create a new #ChafaCanvasConfig, use chafa_canvas_config_new (). You * can then modify it using its setters, e.g. chafa_canvas_config_set_canvas_mode () * before assigning it to a new #ChafaCanvas with chafa_canvas_new (). * * Note that it is not possible to change a canvas' configuration after * the canvas is created. **/ /* Private */ void chafa_canvas_config_init (ChafaCanvasConfig *canvas_config) { g_return_if_fail (canvas_config != NULL); memset (canvas_config, 0, sizeof (*canvas_config)); canvas_config->refs = 1; canvas_config->canvas_mode = CHAFA_CANVAS_MODE_TRUECOLOR; canvas_config->color_extractor = CHAFA_COLOR_EXTRACTOR_AVERAGE; canvas_config->color_space = CHAFA_COLOR_SPACE_RGB; canvas_config->pixel_mode = CHAFA_PIXEL_MODE_SYMBOLS; canvas_config->width = 80; canvas_config->height = 24; canvas_config->cell_width = 8; canvas_config->cell_height = 8; canvas_config->dither_mode = CHAFA_DITHER_MODE_NONE; canvas_config->dither_grain_width = 4; canvas_config->dither_grain_height = 4; canvas_config->dither_intensity = 1.0f; canvas_config->fg_color_packed_rgb = 0xffffff; canvas_config->bg_color_packed_rgb = 0x000000; canvas_config->alpha_threshold = 127; canvas_config->work_factor = 0.5f; canvas_config->preprocessing_enabled = TRUE; canvas_config->optimizations = CHAFA_OPTIMIZATION_ALL; canvas_config->fg_only_enabled = FALSE; chafa_symbol_map_init (&canvas_config->symbol_map); chafa_symbol_map_add_by_tags (&canvas_config->symbol_map, CHAFA_SYMBOL_TAG_BLOCK); chafa_symbol_map_add_by_tags (&canvas_config->symbol_map, CHAFA_SYMBOL_TAG_BORDER); chafa_symbol_map_add_by_tags (&canvas_config->symbol_map, CHAFA_SYMBOL_TAG_SPACE); chafa_symbol_map_remove_by_tags (&canvas_config->symbol_map, CHAFA_SYMBOL_TAG_WIDE); chafa_symbol_map_init (&canvas_config->fill_symbol_map); } void chafa_canvas_config_deinit (ChafaCanvasConfig *canvas_config) { g_return_if_fail (canvas_config != NULL); chafa_symbol_map_deinit (&canvas_config->symbol_map); chafa_symbol_map_deinit (&canvas_config->fill_symbol_map); } void chafa_canvas_config_copy_contents (ChafaCanvasConfig *dest, const ChafaCanvasConfig *src) { g_return_if_fail (dest != NULL); g_return_if_fail (src != NULL); memcpy (dest, src, sizeof (*dest)); chafa_symbol_map_copy_contents (&dest->symbol_map, &src->symbol_map); chafa_symbol_map_copy_contents (&dest->fill_symbol_map, &src->fill_symbol_map); dest->refs = 1; } /* Public */ /** * chafa_canvas_config_new: * * Creates a new #ChafaCanvasConfig with default settings. This * object can later be used in the creation of a #ChafaCanvas. * * Returns: The new #ChafaCanvasConfig **/ ChafaCanvasConfig * chafa_canvas_config_new (void) { ChafaCanvasConfig *canvas_config; canvas_config = g_new (ChafaCanvasConfig, 1); chafa_canvas_config_init (canvas_config); return canvas_config; } /** * chafa_canvas_config_copy: * @config: A #ChafaSymbolMap to copy. * * Creates a new #ChafaCanvasConfig that's a copy of @config. * * Returns: The new #ChafaCanvasConfig **/ ChafaCanvasConfig * chafa_canvas_config_copy (const ChafaCanvasConfig *config) { ChafaCanvasConfig *new_config; new_config = g_new (ChafaCanvasConfig, 1); chafa_canvas_config_copy_contents (new_config, config); return new_config; } /** * chafa_canvas_config_ref: * @config: #ChafaCanvasConfig to add a reference to. * * Adds a reference to @config. **/ void chafa_canvas_config_ref (ChafaCanvasConfig *config) { gint refs; g_return_if_fail (config != NULL); refs = g_atomic_int_get (&config->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&config->refs); } /** * chafa_canvas_config_unref: * @config: #ChafaCanvasConfig to remove a reference from. * * Removes a reference from @config. **/ void chafa_canvas_config_unref (ChafaCanvasConfig *config) { gint refs; g_return_if_fail (config != NULL); refs = g_atomic_int_get (&config->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&config->refs)) { chafa_canvas_config_deinit (config); g_free (config); } } /** * chafa_canvas_config_get_geometry: * @config: A #ChafaCanvasConfig * @width_out: Location to store width in, or %NULL * @height_out: Location to store height in, or %NULL * * Returns @config's width and height in character cells in the * provided output locations. **/ void chafa_canvas_config_get_geometry (const ChafaCanvasConfig *config, gint *width_out, gint *height_out) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); if (width_out) *width_out = config->width; if (height_out) *height_out = config->height; } /** * chafa_canvas_config_set_geometry: * @config: A #ChafaCanvasConfig * @width: Width in character cells * @height: Height in character cells * * Sets @config's width and height in character cells to @width x @height. **/ void chafa_canvas_config_set_geometry (ChafaCanvasConfig *config, gint width, gint height) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (width > 0); g_return_if_fail (height > 0); config->width = width; config->height = height; } /** * chafa_canvas_config_get_cell_geometry: * @config: A #ChafaCanvasConfig * @cell_width_out: Location to store cell width in, or %NULL * @cell_height_out: Location to store cell height in, or %NULL * * Returns @config's cell width and height in pixels in the * provided output locations. * * Since: 1.4 **/ void chafa_canvas_config_get_cell_geometry (const ChafaCanvasConfig *config, gint *cell_width_out, gint *cell_height_out) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); if (cell_width_out) *cell_width_out = config->cell_width; if (cell_height_out) *cell_height_out = config->cell_height; } /** * chafa_canvas_config_set_cell_geometry: * @config: A #ChafaCanvasConfig * @cell_width: Cell width in pixels * @cell_height: Cell height in pixels * * Sets @config's cell width and height in pixels to @cell_width x @cell_height. * * Since: 1.4 **/ void chafa_canvas_config_set_cell_geometry (ChafaCanvasConfig *config, gint cell_width, gint cell_height) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (cell_width > 0); g_return_if_fail (cell_height > 0); config->cell_width = cell_width; config->cell_height = cell_height; } /** * chafa_canvas_config_get_canvas_mode: * @config: A #ChafaCanvasConfig * * Returns @config's #ChafaCanvasMode. This determines how colors (and * color control codes) are used in the output. * * Returns: The #ChafaCanvasMode. **/ ChafaCanvasMode chafa_canvas_config_get_canvas_mode (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_CANVAS_MODE_TRUECOLOR); g_return_val_if_fail (config->refs > 0, CHAFA_CANVAS_MODE_TRUECOLOR); return config->canvas_mode; } /** * chafa_canvas_config_set_canvas_mode: * @config: A #ChafaCanvasConfig * @mode: A #ChafaCanvasMode * * Sets @config's stored #ChafaCanvasMode to @mode. This determines how * colors (and color control codes) are used in the output. **/ void chafa_canvas_config_set_canvas_mode (ChafaCanvasConfig *config, ChafaCanvasMode mode) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (mode < CHAFA_CANVAS_MODE_MAX); config->canvas_mode = mode; } /** * chafa_canvas_config_get_color_extractor: * @config: A #ChafaCanvasConfig * * Returns @config's #ChafaColorExtractor. This determines how colors are * approximated in character symbol output. * * Returns: The #ChafaColorExtractor. * * Since: 1.4 **/ ChafaColorExtractor chafa_canvas_config_get_color_extractor (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_COLOR_EXTRACTOR_AVERAGE); g_return_val_if_fail (config->refs > 0, CHAFA_COLOR_EXTRACTOR_AVERAGE); return config->color_extractor; } /** * chafa_canvas_config_set_color_extractor: * @config: A #ChafaCanvasConfig * @color_extractor: A #ChafaColorExtractor * * Sets @config's stored #ChafaColorExtractor to @color_extractor. This * determines how colors are approximated in character symbol output. * * Since: 1.4 **/ void chafa_canvas_config_set_color_extractor (ChafaCanvasConfig *config, ChafaColorExtractor color_extractor) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (color_extractor < CHAFA_COLOR_EXTRACTOR_MAX); config->color_extractor = color_extractor; } /** * chafa_canvas_config_get_color_space: * @config: A #ChafaCanvasConfig * * Returns @config's #ChafaColorSpace. * * Returns: The #ChafaColorSpace. **/ ChafaColorSpace chafa_canvas_config_get_color_space (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_COLOR_SPACE_RGB); g_return_val_if_fail (config->refs > 0, CHAFA_COLOR_SPACE_RGB); return config->color_space; } /** * chafa_canvas_config_set_color_space: * @config: A #ChafaCanvasConfig * @color_space: A #ChafaColorSpace * * Sets @config's stored #ChafaColorSpace to @color_space. **/ void chafa_canvas_config_set_color_space (ChafaCanvasConfig *config, ChafaColorSpace color_space) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (color_space < CHAFA_COLOR_SPACE_MAX); config->color_space = color_space; } /** * chafa_canvas_config_peek_symbol_map: * @config: A #ChafaCanvasConfig * * Returns a pointer to the symbol map belonging to @config. * This can be inspected using the #ChafaSymbolMap getter * functions, but not changed. * * Returns: A pointer to the config's immutable symbol map **/ const ChafaSymbolMap * chafa_canvas_config_peek_symbol_map (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, NULL); g_return_val_if_fail (config->refs > 0, NULL); return &config->symbol_map; } /** * chafa_canvas_config_set_symbol_map: * @config: A #ChafaCanvasConfig * @symbol_map: A #ChafaSymbolMap * * Assigns a copy of @symbol_map to @config. **/ void chafa_canvas_config_set_symbol_map (ChafaCanvasConfig *config, const ChafaSymbolMap *symbol_map) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); chafa_symbol_map_deinit (&config->symbol_map); chafa_symbol_map_copy_contents (&config->symbol_map, symbol_map); } /** * chafa_canvas_config_peek_fill_symbol_map: * @config: A #ChafaCanvasConfig * * Returns a pointer to the fill symbol map belonging to @config. * This can be inspected using the #ChafaSymbolMap getter * functions, but not changed. * * Fill symbols are assigned according to their overall foreground to * background coverage, disregarding shape. * * Returns: A pointer to the config's immutable fill symbol map **/ const ChafaSymbolMap * chafa_canvas_config_peek_fill_symbol_map (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, NULL); g_return_val_if_fail (config->refs > 0, NULL); return &config->fill_symbol_map; } /** * chafa_canvas_config_set_fill_symbol_map: * @config: A #ChafaCanvasConfig * @fill_symbol_map: A #ChafaSymbolMap * * Assigns a copy of @fill_symbol_map to @config. **/ void chafa_canvas_config_set_fill_symbol_map (ChafaCanvasConfig *config, const ChafaSymbolMap *fill_symbol_map) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); chafa_symbol_map_deinit (&config->fill_symbol_map); chafa_symbol_map_copy_contents (&config->fill_symbol_map, fill_symbol_map); } /** * chafa_canvas_config_get_transparency_threshold: * @config: A #ChafaCanvasConfig * * Returns the threshold above which full transparency will be used. * * Returns: The transparency threshold [0.0 - 1.0] **/ gfloat chafa_canvas_config_get_transparency_threshold (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, 0.0); g_return_val_if_fail (config->refs > 0, 0.0); return 1.0 - (config->alpha_threshold / 256.0); } /** * chafa_canvas_config_set_transparency_threshold: * @config: A #ChafaCanvasConfig * @alpha_threshold: The transparency threshold [0.0 - 1.0]. * * Sets the threshold above which full transparency will be used. **/ void chafa_canvas_config_set_transparency_threshold (ChafaCanvasConfig *config, gfloat alpha_threshold) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (alpha_threshold >= 0.0f); g_return_if_fail (alpha_threshold <= 1.0f); /* Invert the scale; internally it's more like an opacity threshold */ config->alpha_threshold = 256.0f * (1.0f - alpha_threshold); } /** * chafa_canvas_config_get_fg_color: * @config: A #ChafaCanvasConfig * * Gets the assumed foreground color of the output device. This is used to * determine how to apply the foreground pen in FGBG modes. * * Returns: Foreground color as packed RGB triplet **/ guint32 chafa_canvas_config_get_fg_color (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, 0); g_return_val_if_fail (config->refs > 0, 0); return config->fg_color_packed_rgb; } /** * chafa_canvas_config_set_fg_color: * @config: A #ChafaCanvasConfig * @fg_color_packed_rgb: Foreground color as packed RGB triplet * * Sets the assumed foreground color of the output device. This is used to * determine how to apply the foreground pen in FGBG modes. **/ void chafa_canvas_config_set_fg_color (ChafaCanvasConfig *config, guint32 fg_color_packed_rgb) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); config->fg_color_packed_rgb = fg_color_packed_rgb; } /** * chafa_canvas_config_get_bg_color: * @config: A #ChafaCanvasConfig * * Gets the assumed background color of the output device. This is used to * determine how to apply the background pen in FGBG modes. * * Returns: Background color as packed RGB triplet **/ guint32 chafa_canvas_config_get_bg_color (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, 0); g_return_val_if_fail (config->refs > 0, 0); return config->bg_color_packed_rgb; } /** * chafa_canvas_config_set_bg_color: * @config: A #ChafaCanvasConfig * @bg_color_packed_rgb: Background color as packed RGB triplet * * Sets the assumed background color of the output device. This is used to * determine how to apply the background and transparency pens in FGBG modes, * and will also be substituted for partial transparency. **/ void chafa_canvas_config_set_bg_color (ChafaCanvasConfig *config, guint32 bg_color_packed_rgb) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); config->bg_color_packed_rgb = bg_color_packed_rgb; } /** * chafa_canvas_config_get_work_factor: * @config: A #ChafaCanvasConfig * * Gets the work/quality tradeoff factor. A higher value means more time * and memory will be spent towards a higher quality output. * * Returns: The work factor [0.0 - 1.0] **/ gfloat chafa_canvas_config_get_work_factor (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, 1); g_return_val_if_fail (config->refs > 0, 1); return config->work_factor; } /** * chafa_canvas_config_set_work_factor: * @config: A #ChafaCanvasConfig * @work_factor: Work factor [0.0 - 1.0] * * Sets the work/quality tradeoff factor. A higher value means more time * and memory will be spent towards a higher quality output. **/ void chafa_canvas_config_set_work_factor (ChafaCanvasConfig *config, gfloat work_factor) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (work_factor >= 0.0f && work_factor <= 1.0f); config->work_factor = work_factor; } /** * chafa_canvas_config_get_preprocessing_enabled: * @config: A #ChafaCanvasConfig * * Queries whether automatic image preprocessing is enabled. This allows * Chafa to boost contrast and saturation in an attempt to improve * legibility. The type of preprocessing applied (if any) depends on the * canvas mode. * * Returns: Whether automatic preprocessing is enabled **/ gboolean chafa_canvas_config_get_preprocessing_enabled (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, FALSE); g_return_val_if_fail (config->refs > 0, FALSE); return config->preprocessing_enabled; } /** * chafa_canvas_config_set_preprocessing_enabled: * @config: A #ChafaCanvasConfig * @preprocessing_enabled: Whether automatic preprocessing should be enabled * * Indicates whether automatic image preprocessing should be enabled. This * allows Chafa to boost contrast and saturation in an attempt to improve * legibility. The type of preprocessing applied (if any) depends on the * canvas mode. **/ void chafa_canvas_config_set_preprocessing_enabled (ChafaCanvasConfig *config, gboolean preprocessing_enabled) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); config->preprocessing_enabled = preprocessing_enabled; } /** * chafa_canvas_config_get_dither_mode: * @config: A #ChafaCanvasConfig * * Returns @config's #ChafaDitherMode. * * Returns: The #ChafaDitherMode. * * Since: 1.2 **/ ChafaDitherMode chafa_canvas_config_get_dither_mode (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_DITHER_MODE_NONE); g_return_val_if_fail (config->refs > 0, CHAFA_DITHER_MODE_NONE); return config->dither_mode; } /** * chafa_canvas_config_set_dither_mode: * @config: A #ChafaCanvasConfig * @dither_mode: A #ChafaDitherMode * * Sets @config's stored #ChafaDitherMode to @dither_mode. * * Since: 1.2 **/ void chafa_canvas_config_set_dither_mode (ChafaCanvasConfig *config, ChafaDitherMode dither_mode) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (dither_mode < CHAFA_DITHER_MODE_MAX); config->dither_mode = dither_mode; } /** * chafa_canvas_config_get_dither_grain_size: * @config: A #ChafaCanvasConfig * @width_out: Pointer to a location to store grain width * @height_out: Pointer to a location to store grain height * * Returns @config's dither grain size in @width_out and @height_out. * * Since: 1.2 **/ void chafa_canvas_config_get_dither_grain_size (const ChafaCanvasConfig *config, gint *width_out, gint *height_out) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); if (width_out) *width_out = config->dither_grain_width; if (height_out) *height_out = config->dither_grain_height; } /** * chafa_canvas_config_set_dither_grain_size: * @config: A #ChafaCanvasConfig * @width: The desired grain width (1, 2, 4 or 8) * @height: The desired grain height (1, 2, 4 or 8) * * Sets @config's stored dither grain size to @width by @height pixels. These * values can be 1, 2, 4 or 8. 8 corresponds to the size of an entire * character cell. The default is 4 pixels by 4 pixels. * * Since: 1.2 **/ void chafa_canvas_config_set_dither_grain_size (ChafaCanvasConfig *config, gint width, gint height) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (width == 1 || width == 2 || width == 4 || width == 8); g_return_if_fail (height == 1 || height == 2 || height == 4 || height == 8); config->dither_grain_width = width; config->dither_grain_height = height; } /** * chafa_canvas_config_get_dither_intensity: * @config: A #ChafaCanvasConfig * * Returns the relative intensity of the dithering pattern applied during * image conversion. 1.0 is the default, corresponding to a moderate * intensity. * * Returns: The relative dithering intensity * * Since: 1.2 **/ gfloat chafa_canvas_config_get_dither_intensity (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, 1.0); g_return_val_if_fail (config->refs > 0, 1.0); return config->dither_intensity; } /** * chafa_canvas_config_set_dither_intensity: * @config: A #ChafaCanvasConfig * @intensity: Desired relative dithering intensity * * Sets @config's stored relative intensity of the dithering pattern applied * during image conversion. 1.0 is the default, corresponding to a moderate * intensity. Possible values range from 0.0 to infinity, but in practice, * values above 10.0 are rarely useful. * * Since: 1.2 **/ void chafa_canvas_config_set_dither_intensity (ChafaCanvasConfig *config, gfloat intensity) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (intensity >= 0.0f); config->dither_intensity = intensity; } /** * chafa_canvas_config_get_pixel_mode: * @config: A #ChafaCanvasConfig * * Returns @config's #ChafaPixelMode. * * Returns: The #ChafaPixelMode. This determines how pixel graphics are * rendered in the output. * * Since: 1.4 **/ ChafaPixelMode chafa_canvas_config_get_pixel_mode (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_PIXEL_MODE_SYMBOLS); g_return_val_if_fail (config->refs > 0, CHAFA_PIXEL_MODE_SYMBOLS); return config->pixel_mode; } /** * chafa_canvas_config_set_pixel_mode: * @config: A #ChafaCanvasConfig * @pixel_mode: A #ChafaPixelMode * * Sets @config's stored #ChafaPixelMode to @pixel_mode. This determines * how pixel graphics are rendered in the output. * * Since: 1.4 **/ void chafa_canvas_config_set_pixel_mode (ChafaCanvasConfig *config, ChafaPixelMode pixel_mode) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); g_return_if_fail (pixel_mode < CHAFA_PIXEL_MODE_MAX); config->pixel_mode = pixel_mode; } /** * chafa_canvas_config_get_optimizations: * @config: A #ChafaCanvasConfig * * Returns @config's optimization flags. When enabled, these may produce * more compact output at the cost of reduced compatibility and increased CPU * use. Output quality is unaffected. * * Returns: The #ChafaOptimizations flags. * * Since: 1.6 **/ ChafaOptimizations chafa_canvas_config_get_optimizations (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_OPTIMIZATION_NONE); g_return_val_if_fail (config->refs > 0, CHAFA_OPTIMIZATION_NONE); return config->optimizations; } /** * chafa_canvas_config_set_optimizations: * @config: A #ChafaCanvasConfig * @optimizations: A combination of #ChafaOptimizations flags * * Sets @config's stored optimization flags. When enabled, these may produce * more compact output at the cost of reduced compatibility and increased CPU * use. Output quality is unaffected. * * Since: 1.6 **/ void chafa_canvas_config_set_optimizations (ChafaCanvasConfig *config, ChafaOptimizations optimizations) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); config->optimizations = optimizations; } /** * chafa_canvas_config_get_fg_only_enabled: * @config: A #ChafaCanvasConfig * * Queries whether to use foreground colors only, leaving the background * unmodified in the canvas output. This is relevant only when the * #ChafaPixelMode is set to #CHAFA_PIXEL_MODE_SYMBOLS. * * When this is set, the canvas will emit escape codes to set the foreground * color only. * * Returns: %TRUE if using foreground colors only, %FALSE otherwise. * * Since: 1.8 **/ gboolean chafa_canvas_config_get_fg_only_enabled (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_OPTIMIZATION_NONE); g_return_val_if_fail (config->refs > 0, CHAFA_OPTIMIZATION_NONE); return config->fg_only_enabled; } /** * chafa_canvas_config_set_fg_only_enabled: * @config: A #ChafaCanvasConfig * @fg_only_enabled: Whether to use foreground colors only * * Indicates whether to use foreground colors only, leaving the background * unmodified in the canvas output. This is relevant only when the * #ChafaPixelMode is set to #CHAFA_PIXEL_MODE_SYMBOLS. * * When this is set, the canvas will emit escape codes to set the foreground * color only. * * Since: 1.8 **/ void chafa_canvas_config_set_fg_only_enabled (ChafaCanvasConfig *config, gboolean fg_only_enabled) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); config->fg_only_enabled = fg_only_enabled; } /** * chafa_canvas_config_get_passthrough: * @config: A #ChafaCanvasConfig * * Returns @config's #ChafaPassthrough setting. This defaults to * #CHAFA_PASSTHROUGH_NONE. * * Passthrough is needed to transmit certain escape codes to the outer terminal * when running in an inner terminal environment like tmux. When enabled, this * will happen automatically as needed, dictated by information contained in a * #ChafaTermInfo. * * Returns: The #ChafaPassthrough setting * * Since: 1.14 **/ ChafaPassthrough chafa_canvas_config_get_passthrough (const ChafaCanvasConfig *config) { g_return_val_if_fail (config != NULL, CHAFA_PASSTHROUGH_NONE); g_return_val_if_fail (config->refs > 0, CHAFA_PASSTHROUGH_NONE); return config->passthrough; } /** * chafa_canvas_config_set_passthrough: * @config: A #ChafaCanvasConfig * @passthrough: A #ChafaPassthrough value * * Indicates which passthrough mode to use. This defaults to * #CHAFA_PASSTHROUGH_NONE. * * Passthrough is needed to transmit certain escape codes to the outer terminal * when running in an inner terminal environment like tmux. When enabled, this * will happen automatically as needed, dictated by information contained in a * #ChafaTermInfo. * * Since: 1.14 **/ void chafa_canvas_config_set_passthrough (ChafaCanvasConfig *config, ChafaPassthrough passthrough) { g_return_if_fail (config != NULL); g_return_if_fail (config->refs > 0); config->passthrough = passthrough; } chafa-1.18.2/chafa/chafa-canvas-config.h000066400000000000000000000137301517447374300176610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_CANVAS_CONFIG_H__ #define __CHAFA_CANVAS_CONFIG_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif #include G_BEGIN_DECLS /* Canvas config */ typedef struct ChafaCanvasConfig ChafaCanvasConfig; CHAFA_AVAILABLE_IN_ALL ChafaCanvasConfig *chafa_canvas_config_new (void); CHAFA_AVAILABLE_IN_ALL ChafaCanvasConfig *chafa_canvas_config_copy (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_ref (ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_unref (ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_get_geometry (const ChafaCanvasConfig *config, gint *width_out, gint *height_out); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_geometry (ChafaCanvasConfig *config, gint width, gint height); CHAFA_AVAILABLE_IN_1_4 void chafa_canvas_config_get_cell_geometry (const ChafaCanvasConfig *config, gint *cell_width_out, gint *cell_height_out); CHAFA_AVAILABLE_IN_1_4 void chafa_canvas_config_set_cell_geometry (ChafaCanvasConfig *config, gint cell_width, gint cell_height); CHAFA_AVAILABLE_IN_ALL ChafaCanvasMode chafa_canvas_config_get_canvas_mode (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_canvas_mode (ChafaCanvasConfig *config, ChafaCanvasMode mode); CHAFA_AVAILABLE_IN_1_4 ChafaColorExtractor chafa_canvas_config_get_color_extractor (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_4 void chafa_canvas_config_set_color_extractor (ChafaCanvasConfig *config, ChafaColorExtractor color_extractor); CHAFA_AVAILABLE_IN_ALL ChafaColorSpace chafa_canvas_config_get_color_space (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_color_space (ChafaCanvasConfig *config, ChafaColorSpace color_space); CHAFA_AVAILABLE_IN_ALL const ChafaSymbolMap *chafa_canvas_config_peek_symbol_map (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_symbol_map (ChafaCanvasConfig *config, const ChafaSymbolMap *symbol_map); CHAFA_AVAILABLE_IN_ALL const ChafaSymbolMap *chafa_canvas_config_peek_fill_symbol_map (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_fill_symbol_map (ChafaCanvasConfig *config, const ChafaSymbolMap *fill_symbol_map); CHAFA_AVAILABLE_IN_ALL gfloat chafa_canvas_config_get_transparency_threshold (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_transparency_threshold (ChafaCanvasConfig *config, gfloat alpha_threshold); CHAFA_AVAILABLE_IN_ALL guint32 chafa_canvas_config_get_fg_color (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_fg_color (ChafaCanvasConfig *config, guint32 fg_color_packed_rgb); CHAFA_AVAILABLE_IN_ALL guint32 chafa_canvas_config_get_bg_color (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_bg_color (ChafaCanvasConfig *config, guint32 bg_color_packed_rgb); CHAFA_AVAILABLE_IN_ALL gfloat chafa_canvas_config_get_work_factor (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_work_factor (ChafaCanvasConfig *config, gfloat work_factor); CHAFA_AVAILABLE_IN_ALL gboolean chafa_canvas_config_get_preprocessing_enabled (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_config_set_preprocessing_enabled (ChafaCanvasConfig *config, gboolean preprocessing_enabled); CHAFA_AVAILABLE_IN_1_2 ChafaDitherMode chafa_canvas_config_get_dither_mode (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_2 void chafa_canvas_config_set_dither_mode (ChafaCanvasConfig *config, ChafaDitherMode dither_mode); CHAFA_AVAILABLE_IN_1_2 void chafa_canvas_config_get_dither_grain_size (const ChafaCanvasConfig *config, gint *width_out, gint *height_out); CHAFA_AVAILABLE_IN_1_2 void chafa_canvas_config_set_dither_grain_size (ChafaCanvasConfig *config, gint width, gint height); CHAFA_AVAILABLE_IN_1_2 gfloat chafa_canvas_config_get_dither_intensity (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_2 void chafa_canvas_config_set_dither_intensity (ChafaCanvasConfig *config, gfloat intensity); CHAFA_AVAILABLE_IN_1_4 ChafaPixelMode chafa_canvas_config_get_pixel_mode (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_4 void chafa_canvas_config_set_pixel_mode (ChafaCanvasConfig *config, ChafaPixelMode pixel_mode); CHAFA_AVAILABLE_IN_1_6 ChafaOptimizations chafa_canvas_config_get_optimizations (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_6 void chafa_canvas_config_set_optimizations (ChafaCanvasConfig *config, ChafaOptimizations optimizations); CHAFA_AVAILABLE_IN_1_8 gboolean chafa_canvas_config_get_fg_only_enabled (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_8 void chafa_canvas_config_set_fg_only_enabled (ChafaCanvasConfig *config, gboolean fg_only_enabled); CHAFA_AVAILABLE_IN_1_14 ChafaPassthrough chafa_canvas_config_get_passthrough (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_1_14 void chafa_canvas_config_set_passthrough (ChafaCanvasConfig *config, ChafaPassthrough passthrough); G_END_DECLS #endif /* __CHAFA_CANVAS_CONFIG_H__ */ chafa-1.18.2/chafa/chafa-canvas.c000066400000000000000000002332351517447374300164150ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include "chafa.h" #include "internal/chafa-batch.h" #include "internal/chafa-canvas-internal.h" #include "internal/chafa-canvas-printer.h" #include "internal/chafa-private.h" #include "internal/chafa-pixops.h" #include "internal/chafa-work-cell.h" #include "internal/smolscale/smolscale.h" /** * SECTION:chafa-canvas * @title: ChafaCanvas * @short_description: A canvas that renders to text * * A #ChafaCanvas is a canvas that can render its contents as text strings. * * To create a new #ChafaCanvas, use chafa_canvas_new (). If you want to * specify any parameters, like the geometry, color space and so on, you * must create a #ChafaCanvasConfig first. * * You can draw an image to the canvas using chafa_canvas_draw_all_pixels () * and create an ANSI text (or sixel) representation of the canvas' current * contents using chafa_canvas_build_ansi (). **/ /* Used for cell initialization. May be added up over multiple cells, so a * low multiple needs to fit in an integer. */ #define SYMBOL_ERROR_MAX (G_MAXINT / 8) /* Max candidates to consider in pick_symbol_and_colors_fast(). This is also * limited by a similar constant in chafa-symbol-map.c */ #define N_CANDIDATES_MAX 8 /* Dithering */ #define DITHER_BASE_INTENSITY_FGBG 1.0 #define DITHER_BASE_INTENSITY_8C 0.5 #define DITHER_BASE_INTENSITY_16C 0.25 #define DITHER_BASE_INTENSITY_256C 0.1 typedef struct { ChafaColorPair colors; gint error; } SymbolEval; typedef struct { ChafaColorPair colors; gint error [2]; } SymbolEval2; static ChafaColor threshold_alpha (ChafaColor col, gint alpha_threshold) { col.ch [3] = col.ch [3] < alpha_threshold ? 0 : 255; return col; } static gint color_to_rgb (const ChafaCanvas *canvas, ChafaColor col) { col = threshold_alpha (col, canvas->config.alpha_threshold); if (col.ch [3] == 0) return -1; return ((gint) col.ch [0] << 16) | ((gint) col.ch [1] << 8) | (gint) col.ch [2]; } static gint packed_rgba_to_rgb (const ChafaCanvas *canvas, guint32 rgba) { ChafaColor col; chafa_unpack_color (rgba, &col); return color_to_rgb (canvas, col); } static ChafaColor packed_rgb_to_color (gint rgb) { ChafaColor col; if (rgb < 0) { col.ch [0] = 0x80; col.ch [1] = 0x80; col.ch [2] = 0x80; col.ch [3] = 0x00; } else { col.ch [0] = (rgb >> 16) & 0xff; col.ch [1] = (rgb >> 8) & 0xff; col.ch [2] = rgb & 0xff; col.ch [3] = 0xff; } return col; } static guint32 packed_rgb_to_rgba (gint rgb) { ChafaColor col; col = packed_rgb_to_color (rgb); return chafa_pack_color (&col); } static gint16 packed_rgb_to_index (const ChafaPalette *palette, ChafaColorSpace cs, gint rgb) { ChafaColorCandidates ccand; ChafaColor col; if (rgb < 0) return CHAFA_PALETTE_INDEX_TRANSPARENT; col = packed_rgb_to_color (rgb); chafa_palette_lookup_nearest (palette, cs, &col, &ccand); return ccand.index [0]; } static guint32 transparent_cell_color (ChafaCanvasMode canvas_mode) { if (canvas_mode == CHAFA_CANVAS_MODE_TRUECOLOR) { const ChafaColor col = { { 0x80, 0x80, 0x80, 0x00 } }; return chafa_pack_color (&col); } else { return CHAFA_PALETTE_INDEX_TRANSPARENT; } } static void eval_symbol_colors (ChafaCanvas *canvas, ChafaWorkCell *wcell, const ChafaSymbol *sym, SymbolEval *eval) { if (canvas->config.color_extractor == CHAFA_COLOR_EXTRACTOR_AVERAGE) chafa_work_cell_get_mean_colors_for_symbol (wcell, sym, &eval->colors); else chafa_work_cell_get_median_colors_for_symbol (wcell, sym, &eval->colors); } static void eval_symbol_colors_wide (ChafaCanvas *canvas, ChafaWorkCell *wcell_a, ChafaWorkCell *wcell_b, const ChafaSymbol *sym_a, const ChafaSymbol *sym_b, SymbolEval2 *eval) { SymbolEval part_eval [2]; eval_symbol_colors (canvas, wcell_a, sym_a, &part_eval [0]); eval_symbol_colors (canvas, wcell_b, sym_b, &part_eval [1]); eval->colors.colors [CHAFA_COLOR_PAIR_FG] = chafa_color_average_2 (part_eval [0].colors.colors [CHAFA_COLOR_PAIR_FG], part_eval [1].colors.colors [CHAFA_COLOR_PAIR_FG]); eval->colors.colors [CHAFA_COLOR_PAIR_BG] = chafa_color_average_2 (part_eval [0].colors.colors [CHAFA_COLOR_PAIR_BG], part_eval [1].colors.colors [CHAFA_COLOR_PAIR_BG]); } static gint calc_cell_error_plain (const ChafaPixel *block, const ChafaColorPair *color_pair, const guint8 *cov) { gint error = 0; gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { guint8 p = *cov++; const ChafaPixel *p0 = block++; error += chafa_color_diff_fast (&color_pair->colors [p], &p0->col); } return error; } static void eval_symbol_error (const ChafaWorkCell *wcell, const ChafaSymbol *sym, SymbolEval *eval, const ChafaPalette *fg_palette, const ChafaPalette *bg_palette, ChafaColorSpace color_space) { const guint8 *covp = (guint8 *) &sym->coverage [0]; ChafaColorPair pair; gint error; if (!bg_palette) bg_palette = fg_palette; if (!fg_palette) fg_palette = bg_palette; if (fg_palette) { pair.colors [CHAFA_COLOR_PAIR_FG] = *chafa_palette_get_color ( fg_palette, color_space, chafa_palette_lookup_nearest (fg_palette, color_space, &eval->colors.colors [CHAFA_COLOR_PAIR_FG], NULL)); pair.colors [CHAFA_COLOR_PAIR_BG] = *chafa_palette_get_color ( bg_palette, color_space, chafa_palette_lookup_nearest (bg_palette, color_space, &eval->colors.colors [CHAFA_COLOR_PAIR_BG], NULL)); } else { pair = eval->colors; } #ifdef HAVE_AVX2_INTRINSICS if (chafa_have_avx2 ()) error = chafa_calc_cell_error_avx2 (wcell->pixels, &pair, sym->mask_u32); else #endif #ifdef HAVE_SSE41_INTRINSICS if (chafa_have_sse41 ()) error = chafa_calc_cell_error_sse41 (wcell->pixels, &pair, covp); else #endif error = calc_cell_error_plain (wcell->pixels, &pair, covp); eval->error = error; } static void eval_symbol_error_wide (const ChafaWorkCell *wcell_a, const ChafaWorkCell *wcell_b, const ChafaSymbol2 *sym, SymbolEval2 *wide_eval, const ChafaPalette *fg_palette, const ChafaPalette *bg_palette, ChafaColorSpace color_space) { SymbolEval eval [2]; eval [0].colors = wide_eval->colors; eval [1].colors = wide_eval->colors; eval_symbol_error (wcell_a, &sym->sym [0], &eval [0], fg_palette, bg_palette, color_space); eval_symbol_error (wcell_b, &sym->sym [1], &eval [1], fg_palette, bg_palette, color_space); wide_eval->error [0] = eval [0].error; wide_eval->error [1] = eval [1].error; } static void eval_symbol (ChafaCanvas *canvas, ChafaWorkCell *wcell, gint sym_index, gint *best_sym_index_out, SymbolEval *best_eval_inout) { const ChafaSymbol *sym; SymbolEval eval; sym = &canvas->config.symbol_map.symbols [sym_index]; if (canvas->config.fg_only_enabled) { eval.colors = canvas->default_colors; } else { eval_symbol_colors (canvas, wcell, sym, &eval); } if (canvas->use_quantized_error) { eval_symbol_error (wcell, sym, &eval, &canvas->fg_palette, &canvas->bg_palette, canvas->config.color_space); } else { eval_symbol_error (wcell, sym, &eval, NULL, NULL, canvas->config.color_space); } if (eval.error < best_eval_inout->error) { *best_sym_index_out = sym_index; *best_eval_inout = eval; } } static void eval_symbol_wide (ChafaCanvas *canvas, ChafaWorkCell *wcell_a, ChafaWorkCell *wcell_b, gint sym_index, gint *best_sym_index_out, SymbolEval2 *best_eval_inout) { const ChafaSymbol2 *sym2; SymbolEval2 eval; sym2 = &canvas->config.symbol_map.symbols2 [sym_index]; if (canvas->config.fg_only_enabled) { eval.colors = canvas->default_colors; } else { eval_symbol_colors_wide (canvas, wcell_a, wcell_b, &sym2->sym [0], &sym2->sym [1], &eval); } if (canvas->use_quantized_error) { eval_symbol_error_wide (wcell_a, wcell_b, sym2, &eval, &canvas->fg_palette, &canvas->bg_palette, canvas->config.color_space); } else { eval_symbol_error_wide (wcell_a, wcell_b, sym2, &eval, NULL, NULL, canvas->config.color_space); } if (eval.error [0] + eval.error [1] < best_eval_inout->error [0] + best_eval_inout->error [1]) { *best_sym_index_out = sym_index; *best_eval_inout = eval; } } static void pick_symbol_and_colors_slow (ChafaCanvas *canvas, ChafaWorkCell *wcell, gunichar *sym_out, ChafaColorPair *color_pair_out, gint *error_out) { SymbolEval best_eval; gint best_symbol = -1; gint i; /* Find best symbol. All symbols are candidates. */ best_eval.error = SYMBOL_ERROR_MAX; for (i = 0; canvas->config.symbol_map.symbols [i].c != 0; i++) eval_symbol (canvas, wcell, i, &best_symbol, &best_eval); /* Output */ g_assert (best_symbol >= 0); if (canvas->extract_colors && canvas->config.fg_only_enabled) eval_symbol_colors (canvas, wcell, &canvas->config.symbol_map.symbols [best_symbol], &best_eval); *sym_out = canvas->config.symbol_map.symbols [best_symbol].c; *color_pair_out = best_eval.colors; if (error_out) *error_out = best_eval.error; } static void pick_symbol_and_colors_wide_slow (ChafaCanvas *canvas, ChafaWorkCell *wcell_a, ChafaWorkCell *wcell_b, gunichar *sym_out, ChafaColorPair *color_pair_out, gint *error_a_out, gint *error_b_out) { SymbolEval2 best_eval; gint best_symbol = -1; gint i; /* Find best symbol. All symbols are candidates. */ best_eval.error [0] = best_eval.error [1] = SYMBOL_ERROR_MAX; for (i = 0; canvas->config.symbol_map.symbols2 [i].sym [0].c != 0; i++) eval_symbol_wide (canvas, wcell_a, wcell_b, i, &best_symbol, &best_eval); /* Output */ g_assert (best_symbol >= 0); if (canvas->extract_colors && canvas->config.fg_only_enabled) eval_symbol_colors_wide (canvas, wcell_a, wcell_b, &canvas->config.symbol_map.symbols2 [best_symbol].sym [0], &canvas->config.symbol_map.symbols2 [best_symbol].sym [1], &best_eval); *sym_out = canvas->config.symbol_map.symbols2 [best_symbol].sym [0].c; *color_pair_out = best_eval.colors; if (error_a_out) *error_a_out = best_eval.error [0]; if (error_b_out) *error_b_out = best_eval.error [1]; } static void pick_symbol_and_colors_fast (ChafaCanvas *canvas, ChafaWorkCell *wcell, gunichar *sym_out, ChafaColorPair *color_pair_out, gint *error_out) { ChafaColorPair color_pair; guint64 bitmap; ChafaCandidate candidates [N_CANDIDATES_MAX]; gint n_candidates = 0; SymbolEval best_eval; gint best_symbol; gint i; /* Generate short list of candidates */ if (canvas->extract_colors && !canvas->config.fg_only_enabled) { chafa_work_cell_get_contrasting_color_pair (wcell, &color_pair); } else { color_pair = canvas->default_colors; } bitmap = chafa_work_cell_to_bitmap (wcell, &color_pair); n_candidates = CLAMP (canvas->work_factor_int, 1, N_CANDIDATES_MAX); chafa_symbol_map_find_candidates (&canvas->config.symbol_map, bitmap, canvas->consider_inverted, candidates, &n_candidates); g_assert (n_candidates > 0); /* Find best candidate */ best_symbol = -1; best_eval.error = SYMBOL_ERROR_MAX; for (i = 0; i < n_candidates; i++) eval_symbol (canvas, wcell, candidates [i].symbol_index, &best_symbol, &best_eval); /* Output */ g_assert (best_symbol >= 0); if (canvas->extract_colors && canvas->config.fg_only_enabled) eval_symbol_colors (canvas, wcell, &canvas->config.symbol_map.symbols [best_symbol], &best_eval); *sym_out = canvas->config.symbol_map.symbols [best_symbol].c; *color_pair_out = best_eval.colors; if (error_out) *error_out = best_eval.error; } static void pick_symbol_and_colors_wide_fast (ChafaCanvas *canvas, ChafaWorkCell *wcell_a, ChafaWorkCell *wcell_b, gunichar *sym_out, ChafaColorPair *color_pair_out, gint *error_a_out, gint *error_b_out) { ChafaColorPair color_pair; guint64 bitmaps [2]; ChafaCandidate candidates [N_CANDIDATES_MAX]; gint n_candidates = 0; SymbolEval2 best_eval; gint best_symbol; gint i; /* Generate short list of candidates */ if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG_BGFG) { color_pair = canvas->default_colors; } else { ChafaColorPair color_pair_part [2]; chafa_work_cell_get_contrasting_color_pair (wcell_a, &color_pair_part [0]); chafa_work_cell_get_contrasting_color_pair (wcell_b, &color_pair_part [1]); color_pair.colors [0] = chafa_color_average_2 (color_pair_part [0].colors [0], color_pair_part [1].colors [0]); color_pair.colors [1] = chafa_color_average_2 (color_pair_part [0].colors [1], color_pair_part [1].colors [1]); } bitmaps [0] = chafa_work_cell_to_bitmap (wcell_a, &color_pair); bitmaps [1] = chafa_work_cell_to_bitmap (wcell_b, &color_pair); n_candidates = CLAMP (canvas->work_factor_int, 1, N_CANDIDATES_MAX); chafa_symbol_map_find_wide_candidates (&canvas->config.symbol_map, bitmaps, canvas->consider_inverted, candidates, &n_candidates); g_assert (n_candidates > 0); /* Find best candidate */ best_symbol = -1; best_eval.error [0] = best_eval.error [1] = SYMBOL_ERROR_MAX; for (i = 0; i < n_candidates; i++) eval_symbol_wide (canvas, wcell_a, wcell_b, candidates [i].symbol_index, &best_symbol, &best_eval); /* Output */ g_assert (best_symbol >= 0); if (canvas->extract_colors && canvas->config.fg_only_enabled) eval_symbol_colors_wide (canvas, wcell_a, wcell_b, &canvas->config.symbol_map.symbols2 [best_symbol].sym [0], &canvas->config.symbol_map.symbols2 [best_symbol].sym [1], &best_eval); *sym_out = canvas->config.symbol_map.symbols2 [best_symbol].sym [0].c; *color_pair_out = best_eval.colors; if (error_a_out) *error_a_out = best_eval.error [0]; if (error_b_out) *error_b_out = best_eval.error [1]; } static const ChafaColor * get_palette_color_with_color_space (ChafaPalette *palette, gint index, ChafaColorSpace cs) { return chafa_palette_get_color (palette, cs, index); } static const ChafaColor * get_palette_color (ChafaCanvas *canvas, ChafaPalette *palette, gint index) { return get_palette_color_with_color_space (palette, index, canvas->config.color_space); } static void apply_fill_fg_only (ChafaCanvas *canvas, const ChafaWorkCell *wcell, ChafaCanvasCell *cell) { ChafaColor mean; ChafaColorCandidates ccand; gint fg_value, bg_value, mean_value; gint n_bits; ChafaCandidate sym_cand; gint n_sym_cands = 1; if (canvas->config.fill_symbol_map.n_symbols == 0) return; chafa_work_cell_calc_mean_color (wcell, &mean); if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_TRUECOLOR) { cell->fg_color = chafa_pack_color (&mean); } else { chafa_palette_lookup_nearest (&canvas->fg_palette, canvas->config.color_space, &mean, &ccand); cell->fg_color = ccand.index [0]; } cell->bg_color = transparent_cell_color (canvas->config.canvas_mode); /* FIXME: Do we care enough to weight channels properly here, or convert from DIN99d? * Output looks acceptable without. Would have to check if it makes a noticeable * difference. */ fg_value = (canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG].ch [0] + canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG].ch [1] + canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG].ch [2]) / 3; bg_value = (canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG].ch [0] + canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG].ch [1] + canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG].ch [2]) / 3; mean_value = (mean.ch [0] + mean.ch [1] + mean.ch [2]) / 3; n_bits = ((mean_value * 64) + 128) / 255; if (fg_value < bg_value) n_bits = 64 - n_bits; chafa_symbol_map_find_fill_candidates (&canvas->config.fill_symbol_map, n_bits, FALSE, &sym_cand, &n_sym_cands); cell->c = canvas->config.fill_symbol_map.symbols [sym_cand.symbol_index].c; } static void apply_fill (ChafaCanvas *canvas, const ChafaWorkCell *wcell, ChafaCanvasCell *cell) { ChafaColor mean; ChafaColor col [3]; ChafaColorCandidates ccand; ChafaCandidate sym_cand; gint n_sym_cands = 1; gint i, best_i = 0; gint error, best_error = G_MAXINT; if (canvas->config.fill_symbol_map.n_symbols == 0) return; chafa_work_cell_calc_mean_color (wcell, &mean); if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_TRUECOLOR) { cell->bg_color = cell->fg_color = chafa_pack_color (&mean); chafa_symbol_map_find_fill_candidates (&canvas->config.fill_symbol_map, 0, FALSE, /* Consider inverted? */ &sym_cand, &n_sym_cands); goto done; } else if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_256 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_240 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_16 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_8) { chafa_palette_lookup_nearest (&canvas->fg_palette, canvas->config.color_space, &mean, &ccand); } else if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_16_8) { ChafaColorCandidates ccand_bg; chafa_palette_lookup_nearest (&canvas->fg_palette, canvas->config.color_space, &mean, &ccand); chafa_palette_lookup_nearest (&canvas->bg_palette, canvas->config.color_space, &mean, &ccand_bg); if (ccand.index [0] != ccand_bg.index [0]) { if (ccand.index [1] == ccand_bg.index [0]) ccand.index [1] = ccand_bg.index [1]; ccand.index [0] = ccand_bg.index [0]; } } else if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG_BGFG || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG) { ccand.index [0] = CHAFA_PALETTE_INDEX_FG; ccand.index [1] = CHAFA_PALETTE_INDEX_BG; } else { g_assert_not_reached (); } col [0] = *get_palette_color (canvas, &canvas->fg_palette, ccand.index [0]); col [1] = *get_palette_color (canvas, &canvas->fg_palette, ccand.index [1]); /* In FGBG modes, background and transparency is the same thing. Make * sure we have two opaque colors for correct interpolation. */ if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG_BGFG || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG) col [1].ch [3] = 0xff; /* Make the primary color correspond to cell's BG pen, so mostly transparent * cells will get a transparent BG; terminals typically don't support * transparency in the FG pen. BG is also likely to cover a greater area. */ for (i = 0; i <= 64; i++) { col [2].ch [0] = (col [0].ch [0] * (64 - i) + col [1].ch [0] * i) / 64; col [2].ch [1] = (col [0].ch [1] * (64 - i) + col [1].ch [1] * i) / 64; col [2].ch [2] = (col [0].ch [2] * (64 - i) + col [1].ch [2] * i) / 64; col [2].ch [3] = (col [0].ch [3] * (64 - i) + col [1].ch [3] * i) / 64; error = chafa_color_diff_fast (&mean, &col [2]); if (error < best_error) { /* In FGBG mode there's no way to invert or set the BG color, so * assign the primary color to FG pen instead. */ best_i = (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG ? 64 - i : i); best_error = error; } } chafa_symbol_map_find_fill_candidates (&canvas->config.fill_symbol_map, best_i, canvas->consider_inverted && canvas->config.canvas_mode != CHAFA_CANVAS_MODE_INDEXED_16_8, &sym_cand, &n_sym_cands); /* If we end up with a featureless symbol (space or fill), make * FG color equal to BG. Don't do this in FGBG mode, as it does not permit * color manipulation. */ if (canvas->config.canvas_mode != CHAFA_CANVAS_MODE_FGBG && canvas->config.canvas_mode != CHAFA_CANVAS_MODE_INDEXED_16_8) { if (best_i == 0) ccand.index [1] = ccand.index [0]; else if (best_i == 64) ccand.index [0] = ccand.index [1]; } if (sym_cand.is_inverted) { cell->fg_color = ccand.index [0]; cell->bg_color = ccand.index [1]; } else { cell->fg_color = ccand.index [1]; cell->bg_color = ccand.index [0]; } done: cell->c = canvas->config.fill_symbol_map.symbols [sym_cand.symbol_index].c; } static void quantize_colors_for_cell_16_8 (ChafaCanvas *canvas, ChafaCanvasCell *cell, const ChafaColorPair *color_pair) { /* First pick both colors from FG palette to see if we should eliminate the FG/BG * distinction. This is necessary to prevent artifacts in solid color (fg-bg-fg-bg etc). */ /* TODO: Investigate if we could just force evaluation of the solid symbol instead. */ cell->fg_color = chafa_palette_lookup_nearest (&canvas->fg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_FG], NULL); cell->bg_color = chafa_palette_lookup_nearest (&canvas->fg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_BG], NULL); if (cell->fg_color == cell->bg_color && cell->fg_color >= 8 && cell->fg_color <= 15) { /* Chosen FG and BG colors should ideally be the same, but BG palette does not allow it. * Use the solid char with FG color if we have one, else fall back to using the closest * match from the BG palette for both FG and BG. */ if (canvas->solid_char) { cell->c = canvas->solid_char; cell->bg_color = chafa_palette_lookup_nearest (&canvas->bg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_FG], NULL); } else { cell->fg_color = cell->bg_color = chafa_palette_lookup_nearest (&canvas->bg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_FG], NULL); } } else { cell->bg_color = chafa_palette_lookup_nearest (&canvas->bg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_BG], NULL); } } static void update_cell_colors (ChafaCanvas *canvas, ChafaCanvasCell *cell_out, const ChafaColorPair *color_pair) { if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_256 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_240 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_16 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_8 || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG_BGFG || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG) { cell_out->fg_color = chafa_palette_lookup_nearest (&canvas->fg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_FG], NULL); cell_out->bg_color = chafa_palette_lookup_nearest (&canvas->bg_palette, canvas->config.color_space, &color_pair->colors [CHAFA_COLOR_PAIR_BG], NULL); } else if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_16_8) { quantize_colors_for_cell_16_8 (canvas, cell_out, color_pair); } else { cell_out->fg_color = chafa_pack_color (&color_pair->colors [CHAFA_COLOR_PAIR_FG]); cell_out->bg_color = chafa_pack_color (&color_pair->colors [CHAFA_COLOR_PAIR_BG]); } if (canvas->config.fg_only_enabled) cell_out->bg_color = transparent_cell_color (canvas->config.canvas_mode); } static gint update_cell (ChafaCanvas *canvas, ChafaWorkCell *work_cell, ChafaCanvasCell *cell_out) { gunichar sym = 0; ChafaColorPair color_pair; gint sym_error; if (canvas->config.symbol_map.n_symbols == 0) return SYMBOL_ERROR_MAX; if (canvas->work_factor_int >= 8) pick_symbol_and_colors_slow (canvas, work_cell, &sym, &color_pair, &sym_error); else pick_symbol_and_colors_fast (canvas, work_cell, &sym, &color_pair, &sym_error); cell_out->c = sym; update_cell_colors (canvas, cell_out, &color_pair); /* FIXME: It would probably be better to do the fgbg/bgfg blank symbol check * from emit_ansi_fgbg_bgfg() here. */ return sym_error; } static void update_cells_wide (ChafaCanvas *canvas, ChafaWorkCell *work_cell_a, ChafaWorkCell *work_cell_b, ChafaCanvasCell *cell_a_out, ChafaCanvasCell *cell_b_out, gint *error_a_out, gint *error_b_out) { gunichar sym = 0; ChafaColorPair color_pair; *error_a_out = *error_b_out = SYMBOL_ERROR_MAX; if (canvas->config.symbol_map.n_symbols2 == 0) return; if (canvas->work_factor_int >= 8) pick_symbol_and_colors_wide_slow (canvas, work_cell_a, work_cell_b, &sym, &color_pair, error_a_out, error_b_out); else pick_symbol_and_colors_wide_fast (canvas, work_cell_a, work_cell_b, &sym, &color_pair, error_a_out, error_b_out); cell_a_out->c = sym; cell_b_out->c = 0; update_cell_colors (canvas, cell_a_out, &color_pair); cell_b_out->fg_color = cell_a_out->fg_color; cell_b_out->bg_color = cell_a_out->bg_color; /* quantize_colors_for_cell_16_8() can revert the char to solid, and * the solid char is always narrow. Extend it to both cells. */ if (cell_a_out->c == canvas->solid_char) cell_b_out->c = cell_a_out->c; } /* Number of entries in our cell ring buffer. This allows us to do lookback * and replace single-cell symbols with double-cell ones if it improves * the error value. */ #define N_BUF_CELLS 4 /* Calculate index after positive or negative wraparound(s) */ #define buf_cell_index(i) (((i) + N_BUF_CELLS * 64) % N_BUF_CELLS) static void update_cells_row (ChafaCanvas *canvas, gint row) { ChafaCanvasCell *cells; ChafaWorkCell work_cells [N_BUF_CELLS]; gint cell_errors [N_BUF_CELLS]; gint cx, cy; cells = &canvas->cells [(gsize) row * (gsize) canvas->config.width]; cy = row; for (cx = 0; cx < canvas->config.width; cx++) { gint buf_index = cx % N_BUF_CELLS; ChafaWorkCell *wcell = &work_cells [buf_index]; ChafaCanvasCell wide_cells [2]; gint wide_cell_errors [2]; memset (&cells [cx], 0, sizeof (cells [cx])); cells [cx].c = ' '; chafa_work_cell_init (wcell, canvas->pixels, canvas->width_pixels, cx, cy); cell_errors [buf_index] = update_cell (canvas, wcell, &cells [cx]); /* Try wide symbol */ /* FIXME: If we're overlapping the rightmost half of a wide symbol, * try to revert it to two regular symbols and overwrite the rightmost * one. */ if (cx >= 1 && cells [cx - 1].c != 0) { gint wide_buf_index [2]; wide_buf_index [0] = buf_cell_index (cx - 1); wide_buf_index [1] = buf_index; update_cells_wide (canvas, &work_cells [wide_buf_index [0]], &work_cells [wide_buf_index [1]], &wide_cells [0], &wide_cells [1], &wide_cell_errors [0], &wide_cell_errors [1]); if (wide_cell_errors [0] + wide_cell_errors [1] < cell_errors [wide_buf_index [0]] + cell_errors [wide_buf_index [1]]) { cells [cx - 1] = wide_cells [0]; cells [cx] = wide_cells [1]; cell_errors [wide_buf_index [0]] = wide_cell_errors [0]; cell_errors [wide_buf_index [1]] = wide_cell_errors [1]; } } /* If we produced a featureless cell, try fill */ /* FIXME: Check popcount == 0 or == 64 instead of symbol char */ if (cells [cx].c != 0 && (cells [cx].c == ' ' || cells [cx].c == 0x2588 || cells [cx].fg_color == cells [cx].bg_color)) { if (canvas->config.fg_only_enabled) { apply_fill_fg_only (canvas, wcell, &cells [cx]); cells [cx].bg_color = transparent_cell_color (canvas->config.canvas_mode); } else { apply_fill (canvas, wcell, &cells [cx]); } } /* If cell is still featureless after fill, use blank_char consistently */ if (cells [cx].c != 0 && (cells [cx].c == ' ' || cells [cx].fg_color == cells [cx].bg_color)) { cells [cx].c = canvas->blank_char; /* Copy FG color from previous cell in order to avoid emitting * unnecessary control sequences changing it, but only if we're 100% * sure the "blank" char has no foreground features. It's safest to * permit this optimization only with ASCII space. */ if (canvas->blank_char == ' ' && cx > 0) { cells [cx].fg_color = cells [cx - 1].fg_color; /* We may use inverted colors when the foreground is transparent. * Some downstream tools don't handle this and will keep * modulating the wrong pen. In order to suppress long runs of * artifacts, make the (unused) foreground pen opaque (gh#108). */ if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_TRUECOLOR) cells [cx].fg_color |= 0xff000000; else if (cells [cx].fg_color == CHAFA_PALETTE_INDEX_TRANSPARENT) cells [cx].fg_color = CHAFA_PALETTE_INDEX_FG; } } } } static void cell_build_worker (ChafaBatchInfo *batch, ChafaCanvas *canvas) { gint i; for (i = 0; i < batch->n_rows; i++) { update_cells_row (canvas, batch->first_row + i); } } static void update_cells (ChafaCanvas *canvas) { chafa_process_batches (canvas, (GFunc) cell_build_worker, NULL, /* _post */ canvas->config.height, chafa_get_n_actual_threads (), 1); } static void differentiate_channel (guint8 *dest_channel, guint8 reference_channel, gint min_diff) { gint diff; diff = (gint) *dest_channel - (gint) reference_channel; if (diff >= -min_diff && diff <= 0) *dest_channel = MAX ((gint) reference_channel - min_diff, 0); else if (diff <= min_diff && diff >= 0) *dest_channel = MIN ((gint) reference_channel + min_diff, 255); } static void update_display_colors (ChafaCanvas *canvas) { ChafaColor fg_col; ChafaColor bg_col; chafa_unpack_color (canvas->config.fg_color_packed_rgb, &fg_col); chafa_unpack_color (canvas->config.bg_color_packed_rgb, &bg_col); if (canvas->config.color_space == CHAFA_COLOR_SPACE_DIN99D) { chafa_color_rgb_to_din99d (&fg_col, &canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG]); chafa_color_rgb_to_din99d (&bg_col, &canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG]); } else { canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG] = fg_col; canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG] = bg_col; } canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG].ch [3] = 0xff; canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG].ch [3] = 0x00; /* When holding the BG, we need to compare against a consistent * foreground color for symbol selection by outline. 50% gray * yields acceptable results as a stand-in average of all possible * colors. The BG color can't be too similar, so push it away a * little if needed. This should work with both bright and dark * background colors, and the background color doesn't have to * be precise. * * We don't need to do this for monochrome modes, as they use the * FG/BG colors directly. */ if (canvas->extract_colors && canvas->config.fg_only_enabled) { gint i; chafa_unpack_color (0xff7f7f7f, &canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG]); for (i = 0; i < 3; i++) { differentiate_channel (&canvas->default_colors.colors [CHAFA_COLOR_PAIR_BG].ch [i], canvas->default_colors.colors [CHAFA_COLOR_PAIR_FG].ch [i], 5); } } } static void maybe_clear (ChafaCanvas *canvas) { gsize i, n; if (!canvas->needs_clear) return; n = (gsize) canvas->config.width * (gsize) canvas->config.height; for (i = 0; i < n; i++) { ChafaCanvasCell *cell = &canvas->cells [i]; memset (cell, 0, sizeof (*cell)); cell->c = ' '; } } static void setup_palette (ChafaCanvas *canvas) { ChafaPaletteType fg_pal_type = CHAFA_PALETTE_TYPE_DYNAMIC_256; ChafaPaletteType bg_pal_type = CHAFA_PALETTE_TYPE_DYNAMIC_256; ChafaColor fg_col; ChafaColor bg_col; chafa_unpack_color (canvas->config.fg_color_packed_rgb, &fg_col); chafa_unpack_color (canvas->config.bg_color_packed_rgb, &bg_col); fg_col.ch [3] = 0xff; bg_col.ch [3] = 0x00; /* The repetition here kind of sucks, but it'll get better once the * palette refactoring is done and subtypes go away. */ switch (chafa_canvas_config_get_canvas_mode (&canvas->config)) { case CHAFA_CANVAS_MODE_TRUECOLOR: fg_pal_type = CHAFA_PALETTE_TYPE_DYNAMIC_256; bg_pal_type = CHAFA_PALETTE_TYPE_DYNAMIC_256; break; case CHAFA_CANVAS_MODE_INDEXED_256: fg_pal_type = CHAFA_PALETTE_TYPE_FIXED_256; bg_pal_type = CHAFA_PALETTE_TYPE_FIXED_256; break; case CHAFA_CANVAS_MODE_INDEXED_240: fg_pal_type = CHAFA_PALETTE_TYPE_FIXED_240; bg_pal_type = CHAFA_PALETTE_TYPE_FIXED_240; break; case CHAFA_CANVAS_MODE_INDEXED_16: fg_pal_type = CHAFA_PALETTE_TYPE_FIXED_16; bg_pal_type = CHAFA_PALETTE_TYPE_FIXED_16; break; case CHAFA_CANVAS_MODE_INDEXED_16_8: fg_pal_type = CHAFA_PALETTE_TYPE_FIXED_16; bg_pal_type = CHAFA_PALETTE_TYPE_FIXED_8; break; case CHAFA_CANVAS_MODE_INDEXED_8: fg_pal_type = CHAFA_PALETTE_TYPE_FIXED_8; bg_pal_type = CHAFA_PALETTE_TYPE_FIXED_8; break; case CHAFA_CANVAS_MODE_FGBG_BGFG: case CHAFA_CANVAS_MODE_FGBG: fg_pal_type = CHAFA_PALETTE_TYPE_FIXED_FGBG; bg_pal_type = CHAFA_PALETTE_TYPE_FIXED_FGBG; break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); } chafa_palette_init (&canvas->fg_palette, fg_pal_type); chafa_palette_set_color (&canvas->fg_palette, CHAFA_PALETTE_INDEX_FG, &fg_col); chafa_palette_set_color (&canvas->fg_palette, CHAFA_PALETTE_INDEX_BG, &bg_col); chafa_palette_set_alpha_threshold (&canvas->fg_palette, canvas->config.alpha_threshold); chafa_palette_set_transparent_index (&canvas->fg_palette, CHAFA_PALETTE_INDEX_TRANSPARENT); chafa_palette_init (&canvas->bg_palette, bg_pal_type); chafa_palette_set_color (&canvas->bg_palette, CHAFA_PALETTE_INDEX_FG, &fg_col); chafa_palette_set_color (&canvas->bg_palette, CHAFA_PALETTE_INDEX_BG, &bg_col); chafa_palette_set_alpha_threshold (&canvas->bg_palette, canvas->config.alpha_threshold); chafa_palette_set_transparent_index (&canvas->bg_palette, CHAFA_PALETTE_INDEX_TRANSPARENT); } static gunichar find_best_blank_char (ChafaCanvas *canvas) { ChafaCandidate candidates [N_CANDIDATES_MAX]; gint n_candidates; gunichar best_char = 0x20; /* Try space (0x20) first */ if (chafa_symbol_map_has_symbol (&canvas->config.symbol_map, 0x20) || chafa_symbol_map_has_symbol (&canvas->config.fill_symbol_map, 0x20)) return 0x20; n_candidates = N_CANDIDATES_MAX; chafa_symbol_map_find_fill_candidates (&canvas->config.fill_symbol_map, 0, FALSE, candidates, &n_candidates); if (n_candidates > 0) { best_char = canvas->config.fill_symbol_map.symbols [candidates [0].symbol_index].c; } else { n_candidates = N_CANDIDATES_MAX; chafa_symbol_map_find_candidates (&canvas->config.symbol_map, 0, FALSE, candidates, &n_candidates); if (n_candidates > 0) { best_char = canvas->config.symbol_map.symbols [candidates [0].symbol_index].c; } } return best_char; } static gunichar find_best_solid_char (ChafaCanvas *canvas) { ChafaCandidate candidates [N_CANDIDATES_MAX]; gint n_candidates; gunichar best_char = 0; /* Try solid block (0x2588) first */ if (chafa_symbol_map_has_symbol (&canvas->config.symbol_map, 0x2588) || chafa_symbol_map_has_symbol (&canvas->config.fill_symbol_map, 0x2588)) return 0x2588; n_candidates = N_CANDIDATES_MAX; chafa_symbol_map_find_fill_candidates (&canvas->config.fill_symbol_map, 64, FALSE, candidates, &n_candidates); if (n_candidates > 0 && candidates [0].hamming_distance <= 32) { best_char = canvas->config.fill_symbol_map.symbols [candidates [0].symbol_index].c; } else { n_candidates = N_CANDIDATES_MAX; chafa_symbol_map_find_candidates (&canvas->config.symbol_map, 0xffffffffffffffff, FALSE, candidates, &n_candidates); if (n_candidates > 0 && candidates [0].hamming_distance <= 32) { best_char = canvas->config.symbol_map.symbols [candidates [0].symbol_index].c; } } return best_char; } static void destroy_pixel_canvas (ChafaCanvas *canvas) { if (canvas->pixel_canvas) { if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SIXELS) chafa_sixel_canvas_destroy (canvas->pixel_canvas); else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_KITTY) chafa_kitty_canvas_destroy (canvas->pixel_canvas); else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_ITERM2) chafa_iterm2_canvas_destroy (canvas->pixel_canvas); canvas->pixel_canvas = NULL; } } static void draw_all_pixels (ChafaCanvas *canvas, ChafaPixelType src_pixel_type, const guint8 *src_pixels, gint src_width, gint src_height, gint src_rowstride) { ChafaColor bg_color; ChafaAlign halign = CHAFA_ALIGN_START, valign = CHAFA_ALIGN_START; ChafaTuck tuck = CHAFA_TUCK_STRETCH; if (src_width == 0 || src_height == 0) return; if (canvas->placement) { halign = chafa_placement_get_halign (canvas->placement); valign = chafa_placement_get_valign (canvas->placement); tuck = chafa_placement_get_tuck (canvas->placement); } if (canvas->pixels) { g_free (canvas->pixels); canvas->pixels = NULL; } destroy_pixel_canvas (canvas); if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_KITTY || canvas->config.pixel_mode == CHAFA_PIXEL_MODE_ITERM2) { chafa_unpack_color (canvas->config.bg_color_packed_rgb, &bg_color); bg_color.ch [3] = canvas->config.alpha_threshold < 1 ? 0x00 : 0xff; } if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) { /* Symbol mode */ /* FIXME: The allocation can fail if the canvas is ridiculously large. * Since there's no way to report an error from here, we'll silently * skip the update instead. * * We really shouldn't need this much temporary memory in the first place; * it'd be possible to process the image in cell_height strips and hand * each strip off to the update_cells() pass independently. The pipelining * would improve throughput too. */ canvas->pixels = g_try_new (ChafaPixel, (gsize) canvas->width_pixels * canvas->height_pixels); if (canvas->pixels) { chafa_prepare_pixel_data_for_symbols (&canvas->fg_palette, &canvas->dither, canvas->config.color_space, canvas->config.preprocessing_enabled, canvas->work_factor_int, src_pixel_type, src_pixels, src_width, src_height, src_rowstride, canvas->pixels, canvas->width_pixels, canvas->height_pixels, canvas->config.cell_width, canvas->config.cell_height, halign, valign, tuck); if (canvas->config.alpha_threshold == 0) canvas->have_alpha = FALSE; update_cells (canvas); canvas->needs_clear = FALSE; g_free (canvas->pixels); canvas->pixels = NULL; } else { #if 0 g_warning ("ChafaCanvas: Out of memory allocating %ux%u pixels.", canvas->width_pixels, canvas->height_pixels); #endif } } else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SIXELS) { /* Sixel mode */ canvas->fg_palette.alpha_threshold = canvas->config.alpha_threshold; canvas->pixel_canvas = chafa_sixel_canvas_new (canvas->width_pixels, canvas->height_pixels, canvas->config.color_space, &canvas->fg_palette, &canvas->dither); if (canvas->pixel_canvas) chafa_sixel_canvas_draw_all_pixels (canvas->pixel_canvas, src_pixel_type, src_pixels, src_width, src_height, src_rowstride, halign, valign, tuck, canvas->config.work_factor); } else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_KITTY) { /* Kitty mode */ canvas->fg_palette.alpha_threshold = canvas->config.alpha_threshold; canvas->pixel_canvas = chafa_kitty_canvas_new (canvas->width_pixels, canvas->height_pixels); if (canvas->pixel_canvas) chafa_kitty_canvas_draw_all_pixels (canvas->pixel_canvas, src_pixel_type, src_pixels, src_width, src_height, src_rowstride, bg_color, halign, valign, tuck); } else /* if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_ITERM2) */ { /* iTerm2 mode */ canvas->fg_palette.alpha_threshold = canvas->config.alpha_threshold; canvas->pixel_canvas = chafa_iterm2_canvas_new (canvas->width_pixels, canvas->height_pixels); if (canvas->pixel_canvas) chafa_iterm2_canvas_draw_all_pixels (canvas->pixel_canvas, src_pixel_type, src_pixels, src_width, src_height, src_rowstride, bg_color, halign, valign, tuck); } } /** * chafa_canvas_new: * @config: Configuration to use or %NULL for hardcoded defaults * * Creates a new canvas with the specified configuration. The * canvas makes a private copy of the configuration, so it will * not be affected by subsequent changes. * * Returns: The new canvas **/ ChafaCanvas * chafa_canvas_new (const ChafaCanvasConfig *config) { ChafaCanvas *canvas; gfloat dither_intensity = 1.0f; if (config) { g_return_val_if_fail (config->width > 0, NULL); g_return_val_if_fail (config->height > 0, NULL); } chafa_init (); canvas = g_new0 (ChafaCanvas, 1); if (config) chafa_canvas_config_copy_contents (&canvas->config, config); else chafa_canvas_config_init (&canvas->config); canvas->refs = 1; if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) { /* ANSI art */ canvas->width_pixels = canvas->config.width * CHAFA_SYMBOL_WIDTH_PIXELS; canvas->height_pixels = canvas->config.height * CHAFA_SYMBOL_HEIGHT_PIXELS; } else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SIXELS) { /* Sixels */ canvas->width_pixels = canvas->config.width * canvas->config.cell_width; canvas->height_pixels = canvas->config.height * canvas->config.cell_height; } else /* CHAFA_PIXEL_MODE_KITTY or CHAFA_PIXEL_MODE_ITERM2 */ { canvas->width_pixels = canvas->config.width * canvas->config.cell_width; canvas->height_pixels = canvas->config.height * canvas->config.cell_height; } canvas->pixels = NULL; canvas->cells = g_new (ChafaCanvasCell, (gsize) canvas->config.width * (gsize) canvas->config.height); canvas->work_factor_int = canvas->config.work_factor * 10 + 0.5f; canvas->needs_clear = TRUE; canvas->have_alpha = FALSE; canvas->placement = NULL; canvas->consider_inverted = !(canvas->config.fg_only_enabled || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG); canvas->extract_colors = !(canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG || canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG_BGFG); if (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_FGBG) canvas->config.fg_only_enabled = TRUE; canvas->use_quantized_error = (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_INDEXED_16_8 && !canvas->config.fg_only_enabled); chafa_symbol_map_prepare (&canvas->config.symbol_map); chafa_symbol_map_prepare (&canvas->config.fill_symbol_map); canvas->blank_char = find_best_blank_char (canvas); canvas->solid_char = find_best_solid_char (canvas); /* In truecolor mode we don't support any fancy color spaces for now, since * we'd have to convert back to RGB space when emitting control codes, and * the code for that has yet to be written. In palette modes we just use * the palette mappings. * * There is also no reason to dither in truecolor mode, _unless_ we're * producing sixels, which quantize to a dynamic palette. */ if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_KITTY || canvas->config.pixel_mode == CHAFA_PIXEL_MODE_ITERM2 || (canvas->config.canvas_mode == CHAFA_CANVAS_MODE_TRUECOLOR && canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS)) { canvas->config.color_space = CHAFA_COLOR_SPACE_RGB; canvas->config.dither_mode = CHAFA_DITHER_MODE_NONE; } if (canvas->config.dither_mode == CHAFA_DITHER_MODE_ORDERED) { switch (canvas->config.canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: dither_intensity = DITHER_BASE_INTENSITY_256C; break; case CHAFA_CANVAS_MODE_INDEXED_16: case CHAFA_CANVAS_MODE_INDEXED_16_8: dither_intensity = DITHER_BASE_INTENSITY_16C; break; case CHAFA_CANVAS_MODE_INDEXED_8: dither_intensity = DITHER_BASE_INTENSITY_8C; break; case CHAFA_CANVAS_MODE_FGBG: case CHAFA_CANVAS_MODE_FGBG_BGFG: dither_intensity = DITHER_BASE_INTENSITY_FGBG; break; default: g_assert_not_reached (); break; } } chafa_dither_init (&canvas->dither, canvas->config.dither_mode, dither_intensity * canvas->config.dither_intensity, canvas->config.dither_grain_width, canvas->config.dither_grain_height); update_display_colors (canvas); setup_palette (canvas); return canvas; } /** * chafa_canvas_new_similar: * @orig: Canvas to copy configuration from * * Creates a new canvas configured similarly to @orig. * * Returns: The new canvas **/ ChafaCanvas * chafa_canvas_new_similar (ChafaCanvas *orig) { ChafaCanvas *canvas; g_return_val_if_fail (orig != NULL, NULL); canvas = g_new (ChafaCanvas, 1); memcpy (canvas, orig, sizeof (*canvas)); canvas->refs = 1; chafa_canvas_config_copy_contents (&canvas->config, &orig->config); canvas->pixels = NULL; canvas->cells = g_new (ChafaCanvasCell, (gsize) canvas->config.width * (gsize) canvas->config.height); canvas->needs_clear = TRUE; chafa_dither_copy (&orig->dither, &canvas->dither); canvas->placement = NULL; return canvas; } /** * chafa_canvas_ref: * @canvas: Canvas to add a reference to * * Adds a reference to @canvas. **/ void chafa_canvas_ref (ChafaCanvas *canvas) { gint refs; g_return_if_fail (canvas != NULL); refs = g_atomic_int_get (&canvas->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&canvas->refs); } /** * chafa_canvas_unref: * @canvas: Canvas to remove a reference from * * Removes a reference from @canvas. When remaining references drops to * zero, the canvas is freed and can no longer be used. **/ void chafa_canvas_unref (ChafaCanvas *canvas) { gint refs; g_return_if_fail (canvas != NULL); refs = g_atomic_int_get (&canvas->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&canvas->refs)) { if (canvas->placement) chafa_placement_unref (canvas->placement); chafa_canvas_config_deinit (&canvas->config); destroy_pixel_canvas (canvas); chafa_dither_deinit (&canvas->dither); chafa_palette_deinit (&canvas->fg_palette); chafa_palette_deinit (&canvas->bg_palette); g_free (canvas->pixels); g_free (canvas->cells); g_free (canvas); } } /** * chafa_canvas_peek_config: * @canvas: Canvas whose configuration to inspect * * Returns a pointer to the configuration belonging to @canvas. * This can be inspected using the #ChafaCanvasConfig getter * functions, but not changed. * * Returns: A pointer to the canvas' immutable configuration **/ const ChafaCanvasConfig * chafa_canvas_peek_config (ChafaCanvas *canvas) { g_return_val_if_fail (canvas != NULL, NULL); g_return_val_if_fail (canvas->refs > 0, NULL); return &canvas->config; } /** * chafa_canvas_set_placement: * @canvas: Canvas to place the placement on * @placement: Placement to place * * Places @placement on @canvas, replacing the latter's content. The placement * will cover the entire canvas. * * The canvas will keep a reference to the placement until it is replaced or the * canvas itself is freed. * * Since: 1.14 */ void chafa_canvas_set_placement (ChafaCanvas *canvas, ChafaPlacement *placement) { ChafaImage *image; ChafaFrame *frame; g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); chafa_placement_ref (placement); if (canvas->placement) chafa_placement_unref (canvas->placement); canvas->placement = placement; image = placement->image; g_assert (image != NULL); frame = image->frame; if (!frame) return; draw_all_pixels (canvas, frame->pixel_type, frame->data, frame->width, frame->height, frame->rowstride); } /** * chafa_canvas_draw_all_pixels: * @canvas: Canvas whose pixel data to replace * @src_pixel_type: Pixel format of @src_pixels * @src_pixels: Pointer to the start of source pixel memory * @src_width: Width in pixels of source pixel data * @src_height: Height in pixels of source pixel data * @src_rowstride: Number of bytes between the start of each pixel row * * Replaces pixel data of @canvas with a copy of that found at @src_pixels, * which must be in one of the formats supported by #ChafaPixelType. * * Since: 1.2 **/ void chafa_canvas_draw_all_pixels (ChafaCanvas *canvas, ChafaPixelType src_pixel_type, const guint8 *src_pixels, gint src_width, gint src_height, gint src_rowstride) { g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); g_return_if_fail (src_pixel_type < CHAFA_PIXEL_MAX); g_return_if_fail (src_pixels != NULL); g_return_if_fail (src_width >= 0); g_return_if_fail (src_height >= 0); draw_all_pixels (canvas, src_pixel_type, src_pixels, src_width, src_height, src_rowstride); } /** * chafa_canvas_set_contents_rgba8: * @canvas: Canvas whose pixel data to replace * @src_pixels: Pointer to the start of source pixel memory * @src_width: Width in pixels of source pixel data * @src_height: Height in pixels of source pixel data * @src_rowstride: Number of bytes between the start of each pixel row * * Replaces pixel data of @canvas with a copy of that found at @src_pixels. * The source data must be in packed 8-bits-per-channel RGBA format. The * alpha value is expressed as opacity (0xff is opaque) and is not * premultiplied. * * Deprecated: 1.2: Use chafa_canvas_draw_all_pixels() instead. **/ void chafa_canvas_set_contents_rgba8 (ChafaCanvas *canvas, const guint8 *src_pixels, gint src_width, gint src_height, gint src_rowstride) { draw_all_pixels (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, src_pixels, src_width, src_height, src_rowstride); } /** * chafa_canvas_build_ansi: * @canvas: The canvas to generate an ANSI character representation of * * Builds a UTF-8 string of ANSI sequences and symbols representing * the canvas' current contents. This can e.g. be printed to a terminal. * The exact choice of escape sequences and symbols, dimensions, etc. is * determined by the configuration assigned to @canvas on its creation. * * All output lines except for the last one will end in a newline. * * Returns: A UTF-8 string of ANSI sequences and symbols * * Deprecated: 1.6: Use chafa_canvas_print() instead. **/ GString * chafa_canvas_build_ansi (ChafaCanvas *canvas) { g_return_val_if_fail (canvas != NULL, NULL); g_return_val_if_fail (canvas->refs > 0, NULL); return chafa_canvas_print (canvas, NULL); } /** * chafa_canvas_print: * @canvas: The canvas to generate a printable representation of * @term_info: Terminal to format for, or %NULL for fallback * * Builds a UTF-8 string of terminal control sequences and symbols * representing the canvas' current contents. This can be printed * to a terminal. The exact choice of escape sequences and symbols, * dimensions, etc. is determined by the configuration assigned to * @canvas on its creation. * * All output lines except for the last one will end in a newline. * * Returns: A UTF-8 string of terminal control sequences and symbols * * Since: 1.6 **/ GString * chafa_canvas_print (ChafaCanvas *canvas, ChafaTermInfo *term_info) { GString *str; g_return_val_if_fail (canvas != NULL, NULL); g_return_val_if_fail (canvas->refs > 0, NULL); if (term_info) chafa_term_info_ref (term_info); else term_info = chafa_term_db_get_fallback_info (chafa_term_db_get_default ()); if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) { maybe_clear (canvas); str = chafa_canvas_print_symbols (canvas, term_info); } else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SIXELS && chafa_term_info_get_seq (term_info, CHAFA_TERM_SEQ_BEGIN_SIXELS) && canvas->pixel_canvas) { /* Sixel mode */ str = g_string_new (""); chafa_sixel_canvas_build_ansi (canvas->pixel_canvas, term_info, str, canvas->config.passthrough); } else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_KITTY && chafa_term_info_get_seq (term_info, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1) && canvas->pixel_canvas) { /* Kitty mode */ str = g_string_new (""); chafa_kitty_canvas_build_ansi (canvas->pixel_canvas, term_info, str, canvas->config.width, canvas->config.height, canvas->placement ? canvas->placement->id : -1, canvas->config.passthrough); } else if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_ITERM2 && canvas->pixel_canvas) { /* iTerm2 mode */ str = g_string_new (""); chafa_iterm2_canvas_build_ansi (canvas->pixel_canvas, term_info, str, canvas->config.width, canvas->config.height); } else { str = g_string_new (""); } chafa_term_info_unref (term_info); return str; } /** * chafa_canvas_print_rows: * @canvas: The canvas to generate a printable representation of * @term_info: Terminal to format for, or %NULL for fallback * @array_out: Pointer to storage for resulting array pointer * @array_len_out: Pointer to storage for array's element count, or %NULL * * Builds an array of UTF-8 strings made up of terminal control sequences * and symbols representing the canvas' current contents. These can be * printed to a terminal. The exact choice of escape sequences and symbols, * dimensions, etc. is determined by the configuration assigned to * @canvas on its creation. * * The array will be %NULL-terminated. The element count does not include * the terminator. * * When the canvas' pixel mode is %CHAFA_PIXEL_MODE_SYMBOLS, each element * will hold the contents of exactly one symbol row. There will be no row * separators, newlines or control sequences to reposition the cursor between * rows. Row positioning is left to the caller. * * In other pixel modes, there may be one or more strings, but the splitting * criteria should not be relied on. They must be printed in sequence, exactly * as they appear. * * Since: 1.14 **/ void chafa_canvas_print_rows (ChafaCanvas *canvas, ChafaTermInfo *term_info, GString ***array_out, gint *array_len_out) { g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); g_return_if_fail (array_out != NULL); if (term_info) chafa_term_info_ref (term_info); else term_info = chafa_term_db_get_fallback_info (chafa_term_db_get_default ()); if (canvas->config.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) { maybe_clear (canvas); chafa_canvas_print_symbol_rows (canvas, term_info, array_out, array_len_out); } else { GString *gs = chafa_canvas_print (canvas, term_info); *array_out = g_new (GString *, 2); (*array_out) [0] = gs; (*array_out) [1] = NULL; if (array_len_out) *array_len_out = 1; } chafa_term_info_unref (term_info); } /** * chafa_canvas_print_rows_strv: * @canvas: The canvas to generate a printable representation of * @term_info: Terminal to format for, or %NULL for fallback * * Builds an array of UTF-8 strings made up of terminal control sequences * and symbols representing the canvas' current contents. These can be * printed to a terminal. The exact choice of escape sequences and symbols, * dimensions, etc. is determined by the configuration assigned to * @canvas on its creation. * * The array will be %NULL-terminated and can be freed with g_strfreev(). * * When the canvas' pixel mode is %CHAFA_PIXEL_MODE_SYMBOLS, each element * will hold the contents of exactly one symbol row. There will be no row * separators, newlines or control sequences to reposition the cursor between * rows. Row positioning is left to the caller. * * In other pixel modes, there may be one or more strings, but the splitting * criteria should not be relied on. They must be printed in sequence, exactly * as they appear. * * Returns: A %NULL-terminated array of string pointers * * Since: 1.14 **/ gchar ** chafa_canvas_print_rows_strv (ChafaCanvas *canvas, ChafaTermInfo *term_info) { GString **gsa; gint gsa_len; gchar **strv; gint i; g_return_val_if_fail (canvas != NULL, NULL); g_return_val_if_fail (canvas->refs > 0, NULL); chafa_canvas_print_rows (canvas, term_info, &gsa, &gsa_len); strv = g_new (gchar *, gsa_len + 1); for (i = 0; i < gsa_len; i++) { /* FIXME: Switch to g_string_free_and_steal() in 2025 */ strv [i] = g_string_free (gsa [i], FALSE); } strv [gsa_len] = NULL; g_free (gsa); return strv; } /** * chafa_canvas_get_char_at: * @canvas: The canvas to inspect * @x: Column of character cell to inspect * @y: Row of character cell to inspect * * Returns the character at cell (x, y). The coordinates are zero-indexed. For * double-width characters, the leftmost cell will contain the character * and the rightmost cell will contain 0. * * Returns: The character at (x, y) * * Since: 1.8 **/ gunichar chafa_canvas_get_char_at (ChafaCanvas *canvas, gint x, gint y) { g_return_val_if_fail (canvas != NULL, 0); g_return_val_if_fail (canvas->refs > 0, 0); g_return_val_if_fail (x >= 0 && x < canvas->config.width, 0); g_return_val_if_fail (y >= 0 && y < canvas->config.height, 0); return canvas->cells [(gsize) y * (gsize) canvas->config.width + x].c; } /** * chafa_canvas_set_char_at: * @canvas: The canvas to manipulate * @x: Column of character cell to manipulate * @y: Row of character cell to manipulate * @c: The character value to store * * Sets the character at cell (x, y). The coordinates are zero-indexed. For * double-width characters, the leftmost cell must contain the character * and the cell to the right of it will automatically be set to 0. * * If the character is a nonprintable or zero-width, no change will be * made. * * Returns: The number of cells output (0, 1 or 2) * * Since: 1.8 **/ gint chafa_canvas_set_char_at (ChafaCanvas *canvas, gint x, gint y, gunichar c) { ChafaCanvasCell *cell; gint cwidth = 1; g_return_val_if_fail (canvas != NULL, 0); g_return_val_if_fail (canvas->refs > 0, 0); g_return_val_if_fail (x >= 0 && x < canvas->config.width, 0); g_return_val_if_fail (y >= 0 && y < canvas->config.height, 0); if (!g_unichar_isprint (c) || g_unichar_iszerowidth (c)) return 0; if (g_unichar_iswide (c)) cwidth = 2; if (x + cwidth > canvas->config.width) return 0; cell = &canvas->cells [(gsize) y * (gsize) canvas->config.width + x]; cell [0].c = c; if (cwidth == 2) { cell [1].c = 0; cell [1].fg_color = cell [0].fg_color; cell [1].bg_color = cell [0].bg_color; } /* If we're overwriting the rightmost half of a wide character, * clear its leftmost half */ if (x > 0) { if (cell [-1].c != 0 && g_unichar_iswide (cell [-1].c)) cell [-1].c = canvas->blank_char; } return cwidth; } /** * chafa_canvas_get_colors_at: * @canvas: The canvas to inspect * @x: Column of character cell to inspect * @y: Row of character cell to inspect * @fg_out: Storage for foreground color * @bg_out: Storage for background color * * Gets the colors at cell (x, y). The coordinates are zero-indexed. For * double-width characters, both cells will contain the same colors. * * The colors will be -1 for transparency, packed 8bpc RGB otherwise, * i.e. 0x00RRGGBB hex. * * If the canvas is in an indexed mode, palette lookups will be made * for you. * * Since: 1.8 **/ void chafa_canvas_get_colors_at (ChafaCanvas *canvas, gint x, gint y, gint *fg_out, gint *bg_out) { const ChafaCanvasCell *cell; gint fg = -1, bg = -1; g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); g_return_if_fail (x >= 0 && x < canvas->config.width); g_return_if_fail (y >= 0 && y < canvas->config.height); cell = &canvas->cells [(gsize) y * (gsize) canvas->config.width + x]; switch (canvas->config.canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: fg = packed_rgba_to_rgb (canvas, cell->fg_color); bg = packed_rgba_to_rgb (canvas, cell->bg_color); break; case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: case CHAFA_CANVAS_MODE_INDEXED_16: case CHAFA_CANVAS_MODE_INDEXED_16_8: case CHAFA_CANVAS_MODE_INDEXED_8: case CHAFA_CANVAS_MODE_FGBG_BGFG: case CHAFA_CANVAS_MODE_FGBG: if (cell->fg_color == CHAFA_PALETTE_INDEX_BG || cell->fg_color == CHAFA_PALETTE_INDEX_TRANSPARENT) fg = -1; else fg = color_to_rgb (canvas, *get_palette_color_with_color_space (&canvas->fg_palette, cell->fg_color, CHAFA_COLOR_SPACE_RGB)); if (cell->bg_color == CHAFA_PALETTE_INDEX_BG || cell->bg_color == CHAFA_PALETTE_INDEX_TRANSPARENT) bg = -1; else bg = color_to_rgb (canvas, *get_palette_color_with_color_space (&canvas->bg_palette, cell->bg_color, CHAFA_COLOR_SPACE_RGB)); break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); break; } *fg_out = fg; *bg_out = bg; } /** * chafa_canvas_set_colors_at: * @canvas: The canvas to manipulate * @x: Column of character cell to manipulate * @y: Row of character cell to manipulate * @fg: Foreground color * @bg: Background color * * Sets the colors at cell (x, y). The coordinates are zero-indexed. For * double-width characters, both cells will be set to the same color. * * The colors must be -1 for transparency, packed 8bpc RGB otherwise, * i.e. 0x00RRGGBB hex. * * If the canvas is in an indexed mode, palette lookups will be made * for you. * * Since: 1.8 **/ void chafa_canvas_set_colors_at (ChafaCanvas *canvas, gint x, gint y, gint fg, gint bg) { ChafaCanvasCell *cell; g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); g_return_if_fail (x >= 0 && x < canvas->config.width); g_return_if_fail (y >= 0 && y < canvas->config.height); cell = &canvas->cells [(gsize) y * (gsize) canvas->config.width + x]; switch (canvas->config.canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: cell->fg_color = packed_rgb_to_rgba (fg); cell->bg_color = packed_rgb_to_rgba (bg); break; case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: case CHAFA_CANVAS_MODE_INDEXED_16: case CHAFA_CANVAS_MODE_INDEXED_16_8: case CHAFA_CANVAS_MODE_INDEXED_8: cell->fg_color = packed_rgb_to_index (&canvas->fg_palette, canvas->config.color_space, fg); cell->bg_color = packed_rgb_to_index (&canvas->bg_palette, canvas->config.color_space, bg); break; case CHAFA_CANVAS_MODE_FGBG_BGFG: cell->fg_color = fg >= 0 ? CHAFA_PALETTE_INDEX_FG : CHAFA_PALETTE_INDEX_TRANSPARENT; cell->bg_color = bg >= 0 ? CHAFA_PALETTE_INDEX_FG : CHAFA_PALETTE_INDEX_TRANSPARENT; break; case CHAFA_CANVAS_MODE_FGBG: cell->fg_color = fg >= 0 ? fg : CHAFA_PALETTE_INDEX_TRANSPARENT; break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); break; } /* If setting the color of half a wide char, set it for the other half too */ if (x > 0 && cell->c == 0) { cell [-1].fg_color = cell->fg_color; cell [-1].bg_color = cell->bg_color; } if (x < canvas->config.width - 1 && cell [1].c == 0) { cell [1].fg_color = cell->fg_color; cell [1].bg_color = cell->bg_color; } } /** * chafa_canvas_get_raw_colors_at: * @canvas: The canvas to inspect * @x: Column of character cell to inspect * @y: Row of character cell to inspect * @fg_out: Storage for foreground color * @bg_out: Storage for background color * * Gets the colors at cell (x, y). The coordinates are zero-indexed. For * double-width characters, both cells will contain the same colors. * * The colors will be -1 for transparency, packed 8bpc RGB, i.e. * 0x00RRGGBB hex in truecolor mode, or the raw pen value (0-255) in * indexed modes. * * It's the caller's responsibility to handle the color values correctly * according to the canvas mode (truecolor or indexed). * * Since: 1.8 **/ void chafa_canvas_get_raw_colors_at (ChafaCanvas *canvas, gint x, gint y, gint *fg_out, gint *bg_out) { const ChafaCanvasCell *cell; gint fg = -1, bg = -1; g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); g_return_if_fail (x >= 0 && x < canvas->config.width); g_return_if_fail (y >= 0 && y < canvas->config.height); cell = &canvas->cells [(gsize) y * (gsize) canvas->config.width + x]; switch (canvas->config.canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: fg = packed_rgba_to_rgb (canvas, cell->fg_color); bg = packed_rgba_to_rgb (canvas, cell->bg_color); break; case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: case CHAFA_CANVAS_MODE_INDEXED_16: case CHAFA_CANVAS_MODE_INDEXED_16_8: case CHAFA_CANVAS_MODE_INDEXED_8: fg = cell->fg_color < 256 ? (gint) cell->fg_color : -1; bg = cell->bg_color < 256 ? (gint) cell->bg_color : -1; break; case CHAFA_CANVAS_MODE_FGBG_BGFG: fg = cell->fg_color == CHAFA_PALETTE_INDEX_FG ? 0 : -1; bg = cell->bg_color == CHAFA_PALETTE_INDEX_FG ? 0 : -1; break; case CHAFA_CANVAS_MODE_FGBG: fg = 0; bg = -1; break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); break; } if (fg_out) *fg_out = fg; if (bg_out) *bg_out = bg; } /** * chafa_canvas_set_raw_colors_at: * @canvas: The canvas to manipulate * @x: Column of character cell to manipulate * @y: Row of character cell to manipulate * @fg: Foreground color * @bg: Background color * * Sets the colors at cell (x, y). The coordinates are zero-indexed. For * double-width characters, both cells will be set to the same color. * * The colors must be -1 for transparency, packed 8bpc RGB, i.e. * 0x00RRGGBB hex in truecolor mode, or the raw pen value (0-255) in * indexed modes. * * It's the caller's responsibility to handle the color values correctly * according to the canvas mode (truecolor or indexed). * * Since: 1.8 **/ void chafa_canvas_set_raw_colors_at (ChafaCanvas *canvas, gint x, gint y, gint fg, gint bg) { ChafaCanvasCell *cell; g_return_if_fail (canvas != NULL); g_return_if_fail (canvas->refs > 0); g_return_if_fail (x >= 0 && x < canvas->config.width); g_return_if_fail (y >= 0 && y < canvas->config.height); cell = &canvas->cells [(gsize) y * (gsize) canvas->config.width + x]; switch (canvas->config.canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: cell->fg_color = packed_rgb_to_rgba (fg); cell->bg_color = packed_rgb_to_rgba (bg); break; case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: case CHAFA_CANVAS_MODE_INDEXED_16: case CHAFA_CANVAS_MODE_INDEXED_16_8: case CHAFA_CANVAS_MODE_INDEXED_8: cell->fg_color = fg >= 0 ? fg : CHAFA_PALETTE_INDEX_TRANSPARENT; cell->bg_color = bg >= 0 ? bg : CHAFA_PALETTE_INDEX_TRANSPARENT; break; case CHAFA_CANVAS_MODE_FGBG_BGFG: cell->fg_color = fg >= 0 ? CHAFA_PALETTE_INDEX_FG : CHAFA_PALETTE_INDEX_TRANSPARENT; cell->bg_color = bg >= 0 ? CHAFA_PALETTE_INDEX_FG : CHAFA_PALETTE_INDEX_TRANSPARENT; break; case CHAFA_CANVAS_MODE_FGBG: cell->fg_color = fg >= 0 ? fg : CHAFA_PALETTE_INDEX_TRANSPARENT; break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); break; } /* If setting the color of half a wide char, set it for the other half too */ if (x > 0 && cell->c == 0) { cell [-1].fg_color = cell->fg_color; cell [-1].bg_color = cell->bg_color; } if (x < canvas->config.width - 1 && cell [1].c == 0) { cell [1].fg_color = cell->fg_color; cell [1].bg_color = cell->bg_color; } } chafa-1.18.2/chafa/chafa-canvas.h000066400000000000000000000065411517447374300164200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_CANVAS_H__ #define __CHAFA_CANVAS_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif #include G_BEGIN_DECLS typedef struct ChafaCanvas ChafaCanvas; CHAFA_AVAILABLE_IN_ALL ChafaCanvas *chafa_canvas_new (const ChafaCanvasConfig *config); CHAFA_AVAILABLE_IN_ALL ChafaCanvas *chafa_canvas_new_similar (ChafaCanvas *orig); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_ref (ChafaCanvas *canvas); CHAFA_AVAILABLE_IN_ALL void chafa_canvas_unref (ChafaCanvas *canvas); CHAFA_AVAILABLE_IN_ALL const ChafaCanvasConfig *chafa_canvas_peek_config (ChafaCanvas *canvas); CHAFA_AVAILABLE_IN_1_14 void chafa_canvas_set_placement (ChafaCanvas *canvas, ChafaPlacement *placement); CHAFA_AVAILABLE_IN_1_2 void chafa_canvas_draw_all_pixels (ChafaCanvas *canvas, ChafaPixelType src_pixel_type, const guint8 *src_pixels, gint src_width, gint src_height, gint src_rowstride); CHAFA_AVAILABLE_IN_1_6 GString *chafa_canvas_print (ChafaCanvas *canvas, ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_14 void chafa_canvas_print_rows (ChafaCanvas *canvas, ChafaTermInfo *term_info, GString ***array_out, gint *array_len_out); CHAFA_AVAILABLE_IN_1_14 gchar **chafa_canvas_print_rows_strv (ChafaCanvas *canvas, ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_8 gunichar chafa_canvas_get_char_at (ChafaCanvas *canvas, gint x, gint y); CHAFA_AVAILABLE_IN_1_8 gint chafa_canvas_set_char_at (ChafaCanvas *canvas, gint x, gint y, gunichar c); CHAFA_AVAILABLE_IN_1_8 void chafa_canvas_get_colors_at (ChafaCanvas *canvas, gint x, gint y, gint *fg_out, gint *bg_out); CHAFA_AVAILABLE_IN_1_8 void chafa_canvas_set_colors_at (ChafaCanvas *canvas, gint x, gint y, gint fg, gint bg); CHAFA_AVAILABLE_IN_1_8 void chafa_canvas_get_raw_colors_at (ChafaCanvas *canvas, gint x, gint y, gint *fg_out, gint *bg_out); CHAFA_AVAILABLE_IN_1_8 void chafa_canvas_set_raw_colors_at (ChafaCanvas *canvas, gint x, gint y, gint fg, gint bg); CHAFA_DEPRECATED_IN_1_2 void chafa_canvas_set_contents_rgba8 (ChafaCanvas *canvas, const guint8 *src_pixels, gint src_width, gint src_height, gint src_rowstride); CHAFA_DEPRECATED_IN_1_6 GString *chafa_canvas_build_ansi (ChafaCanvas *canvas); G_END_DECLS #endif /* __CHAFA_CANVAS_H__ */ chafa-1.18.2/chafa/chafa-common.h000066400000000000000000000175701517447374300164410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_COMMON_H__ #define __CHAFA_COMMON_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS /** * ChafaPixelType: * @CHAFA_PIXEL_RGBA8_PREMULTIPLIED: Premultiplied RGBA, 8 bits per channel. * @CHAFA_PIXEL_BGRA8_PREMULTIPLIED: Premultiplied BGRA, 8 bits per channel. * @CHAFA_PIXEL_ARGB8_PREMULTIPLIED: Premultiplied ARGB, 8 bits per channel. * @CHAFA_PIXEL_ABGR8_PREMULTIPLIED: Premultiplied ABGR, 8 bits per channel. * @CHAFA_PIXEL_RGBA8_UNASSOCIATED: Unassociated RGBA, 8 bits per channel. * @CHAFA_PIXEL_BGRA8_UNASSOCIATED: Unassociated BGRA, 8 bits per channel. * @CHAFA_PIXEL_ARGB8_UNASSOCIATED: Unassociated ARGB, 8 bits per channel. * @CHAFA_PIXEL_ABGR8_UNASSOCIATED: Unassociated ABGR, 8 bits per channel. * @CHAFA_PIXEL_RGB8: Packed RGB (no alpha), 8 bits per channel. * @CHAFA_PIXEL_BGR8: Packed BGR (no alpha), 8 bits per channel. * @CHAFA_PIXEL_MAX: Last supported pixel type, plus one. * * Pixel formats supported by #ChafaCanvas and #ChafaSymbolMap. * * Since: 1.4 **/ typedef enum { /* 32 bits per pixel */ CHAFA_PIXEL_RGBA8_PREMULTIPLIED, CHAFA_PIXEL_BGRA8_PREMULTIPLIED, CHAFA_PIXEL_ARGB8_PREMULTIPLIED, CHAFA_PIXEL_ABGR8_PREMULTIPLIED, CHAFA_PIXEL_RGBA8_UNASSOCIATED, CHAFA_PIXEL_BGRA8_UNASSOCIATED, CHAFA_PIXEL_ARGB8_UNASSOCIATED, CHAFA_PIXEL_ABGR8_UNASSOCIATED, /* 24 bits per pixel */ CHAFA_PIXEL_RGB8, CHAFA_PIXEL_BGR8, CHAFA_PIXEL_MAX } ChafaPixelType; /** * ChafaAlign: * @CHAFA_ALIGN_START: Align flush with beginning of the area (top or left in LTR locales). * @CHAFA_ALIGN_END: Align flush with end of the area (bottom or right in LTR locales). * @CHAFA_ALIGN_CENTER: Align in the middle of the area. * @CHAFA_ALIGN_MAX: Last supported alignment, plus one. * * Alignment options when placing an element within an area. * * Since: 1.14 **/ typedef enum { CHAFA_ALIGN_START, CHAFA_ALIGN_END, CHAFA_ALIGN_CENTER, CHAFA_ALIGN_MAX } ChafaAlign; /** * ChafaTuck: * @CHAFA_TUCK_STRETCH: Resize element to fit the area exactly, changing its aspect ratio. * @CHAFA_TUCK_FIT: Resize element to fit the area, preserving its aspect ratio by adding padding. * @CHAFA_TUCK_SHRINK_TO_FIT: Like @CHAFA_TUCK_FIT, but prohibit enlargement. * @CHAFA_TUCK_MAX: Last supported tucking policy, plus one. * * Resizing options when placing an element within an area. Usually used in conjunction * with #ChafaAlign to control the padding. * * Since: 1.14 **/ typedef enum { CHAFA_TUCK_STRETCH, CHAFA_TUCK_FIT, CHAFA_TUCK_SHRINK_TO_FIT, CHAFA_TUCK_MAX } ChafaTuck; /* Color extractor */ /** * ChafaColorExtractor: * @CHAFA_COLOR_EXTRACTOR_AVERAGE: Use the average colors of each symbol's coverage area. * @CHAFA_COLOR_EXTRACTOR_MEDIAN: Use the median colors of each symbol's coverage area. * @CHAFA_COLOR_EXTRACTOR_MAX: Last supported color extractor plus one. **/ typedef enum { CHAFA_COLOR_EXTRACTOR_AVERAGE, CHAFA_COLOR_EXTRACTOR_MEDIAN, CHAFA_COLOR_EXTRACTOR_MAX } ChafaColorExtractor; /* Color spaces */ /** * ChafaColorSpace: * @CHAFA_COLOR_SPACE_RGB: RGB color space. Fast but imprecise. * @CHAFA_COLOR_SPACE_DIN99D: DIN99d color space. Slower, but good perceptual color precision. * @CHAFA_COLOR_SPACE_MAX: Last supported color space plus one. **/ typedef enum { CHAFA_COLOR_SPACE_RGB, CHAFA_COLOR_SPACE_DIN99D, CHAFA_COLOR_SPACE_MAX } ChafaColorSpace; /* Dither modes */ /** * ChafaDitherMode: * @CHAFA_DITHER_MODE_NONE: No dithering. * @CHAFA_DITHER_MODE_ORDERED: Ordered dithering (Bayer or similar). * @CHAFA_DITHER_MODE_DIFFUSION: Error diffusion dithering (Floyd-Steinberg or similar). * @CHAFA_DITHER_MODE_NOISE: Noise pattern dithering (blue noise or similar). * @CHAFA_DITHER_MODE_MAX: Last supported dither mode plus one. **/ typedef enum { CHAFA_DITHER_MODE_NONE, CHAFA_DITHER_MODE_ORDERED, CHAFA_DITHER_MODE_DIFFUSION, CHAFA_DITHER_MODE_NOISE, CHAFA_DITHER_MODE_MAX } ChafaDitherMode; /* Sequence optimization flags. When enabled, these may produce more compact * output at the cost of reduced compatibility and increased CPU use. Output * quality is unaffected. */ /** * ChafaOptimizations: * @CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES: Suppress redundant SGR control sequences. * @CHAFA_OPTIMIZATION_SKIP_CELLS: Reserved for future use. * @CHAFA_OPTIMIZATION_REPEAT_CELLS: Use REP sequence to compress repeated runs of similar cells. * @CHAFA_OPTIMIZATION_NONE: All optimizations disabled. * @CHAFA_OPTIMIZATION_ALL: All optimizations enabled. **/ typedef enum { CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES = (1 << 0), CHAFA_OPTIMIZATION_SKIP_CELLS = (1 << 1), CHAFA_OPTIMIZATION_REPEAT_CELLS = (1 << 2), CHAFA_OPTIMIZATION_NONE = 0, CHAFA_OPTIMIZATION_ALL = 0x7fffffff } ChafaOptimizations; /* Canvas modes */ /** * ChafaCanvasMode: * @CHAFA_CANVAS_MODE_TRUECOLOR: Truecolor. * @CHAFA_CANVAS_MODE_INDEXED_256: 256 colors. * @CHAFA_CANVAS_MODE_INDEXED_240: 256 colors, but avoid using the lower 16 whose values vary between terminal environments. * @CHAFA_CANVAS_MODE_INDEXED_16: 16 colors using the aixterm ANSI extension. * @CHAFA_CANVAS_MODE_INDEXED_16_8: 16 FG colors (8 of which enabled with bold/bright) and 8 BG colors. * @CHAFA_CANVAS_MODE_INDEXED_8: 8 colors, compatible with original ANSI X3.64. * @CHAFA_CANVAS_MODE_FGBG_BGFG: Default foreground and background colors, plus inversion. * @CHAFA_CANVAS_MODE_FGBG: Default foreground and background colors. No ANSI codes will be used. * @CHAFA_CANVAS_MODE_MAX: Last supported canvas mode plus one. **/ typedef enum { CHAFA_CANVAS_MODE_TRUECOLOR, CHAFA_CANVAS_MODE_INDEXED_256, CHAFA_CANVAS_MODE_INDEXED_240, CHAFA_CANVAS_MODE_INDEXED_16, CHAFA_CANVAS_MODE_FGBG_BGFG, CHAFA_CANVAS_MODE_FGBG, CHAFA_CANVAS_MODE_INDEXED_8, CHAFA_CANVAS_MODE_INDEXED_16_8, CHAFA_CANVAS_MODE_MAX } ChafaCanvasMode; /* Pixel modes */ /** * ChafaPixelMode: * @CHAFA_PIXEL_MODE_SYMBOLS: Pixel data is approximated using character symbols ("ANSI art"). * @CHAFA_PIXEL_MODE_SIXELS: Pixel data is encoded as sixels. * @CHAFA_PIXEL_MODE_KITTY: Pixel data is encoded using the Kitty terminal protocol. * @CHAFA_PIXEL_MODE_ITERM2: Pixel data is encoded using the iTerm2 terminal protocol. * @CHAFA_PIXEL_MODE_MAX: Last supported pixel mode plus one. **/ typedef enum { CHAFA_PIXEL_MODE_SYMBOLS, CHAFA_PIXEL_MODE_SIXELS, CHAFA_PIXEL_MODE_KITTY, CHAFA_PIXEL_MODE_ITERM2, CHAFA_PIXEL_MODE_MAX } ChafaPixelMode; /* Passthrough modes */ /** * ChafaPassthrough: * @CHAFA_PASSTHROUGH_NONE: No passthrough guards will be used. * @CHAFA_PASSTHROUGH_SCREEN: Passthrough guards for GNU Screen will be used. * @CHAFA_PASSTHROUGH_TMUX: Passthrough guards for tmux will be used. * @CHAFA_PASSTHROUGH_MAX: Last supported passthrough mode plus one. **/ typedef enum { CHAFA_PASSTHROUGH_NONE, CHAFA_PASSTHROUGH_SCREEN, CHAFA_PASSTHROUGH_TMUX, CHAFA_PASSTHROUGH_MAX } ChafaPassthrough; G_END_DECLS #endif /* __CHAFA_COMMON_H__ */ chafa-1.18.2/chafa/chafa-features.c000066400000000000000000000157121517447374300167560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-private.h" /** * SECTION:chafa-features * @title: Features * @short_description: Platform-specific feature support * * Chafa supports a few platform-specific acceleration features. These * will be built in and used automatically when available. You can get * information about the available features through the function calls * documented in this section. **/ /** * ChafaFeatures: * @CHAFA_FEATURE_MMX: Flag indicating MMX support. * @CHAFA_FEATURE_SSE41: Flag indicating SSE 4.1 support. * @CHAFA_FEATURE_POPCNT: Flag indicating popcnt support. * @CHAFA_FEATURE_AVX2: Flag indicating AVX2 support. **/ /* The detected CPU count can approach 200 in realistic environments (64 on * UltraSparc T2, 192 on Ryzen Threadripper Pro), and mapped memory may be * limited to as little as 1.5GB (default RLIMIT_DATA on OpenBSD 7.8/sparc64 - * malloc's MAXDSIZ is set to 8GB). Keep a sensible thread limit to avoid * running out of memory. */ #define AUTO_THREAD_COUNT_MAX 24 static gboolean chafa_initialized; static gboolean have_mmx; static gboolean have_sse41; static gboolean have_popcnt; static gboolean have_avx2; static gint n_threads = -1; static void init_features (void) { #ifdef HAVE_GCC_X86_FEATURE_BUILTINS __builtin_cpu_init (); # ifdef HAVE_MMX_INTRINSICS if (__builtin_cpu_supports ("mmx")) have_mmx = TRUE; # endif # ifdef HAVE_SSE41_INTRINSICS if (__builtin_cpu_supports ("sse4.1")) have_sse41 = TRUE; # endif /* For popcnt, AMD does not appear to need the SSE 4.2 check, but the Intel * documentation[1] says the following in section 12.12.3: * * > Before an application attempts to use the POPCNT instruction, it * > must check that the processor supports Intel SSE4.2 (if * > CPUID.01H:ECX.SSE4_2[bit 20] = 1) and POPCNT (if * > CPUID.01H:ECX.POPCNT[bit 23] = 1). * * [1] https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4 * * So we check both. */ # ifdef HAVE_POPCNT_INTRINSICS if (__builtin_cpu_supports ("sse4.2") && __builtin_cpu_supports ("popcnt")) have_popcnt = TRUE; # endif # ifdef HAVE_AVX2_INTRINSICS if (__builtin_cpu_supports ("avx2")) have_avx2 = TRUE; # endif #endif } static gpointer init_once (G_GNUC_UNUSED gpointer data) { init_features (); chafa_init_palette (); chafa_init_symbols (); chafa_initialized = TRUE; return NULL; } void chafa_init (void) { static GOnce once = G_ONCE_INIT; g_once (&once, init_once, NULL); } gboolean chafa_have_mmx (void) { return have_mmx; } gboolean chafa_have_sse41 (void) { return have_sse41; } gboolean chafa_have_popcnt (void) { return have_popcnt; } gboolean chafa_have_avx2 (void) { return have_avx2; } /* Public API */ /** * chafa_get_builtin_features: * * Gets a list of the platform-specific features this library was built with. * * Returns: A set of flags indicating features present. **/ ChafaFeatures chafa_get_builtin_features (void) { ChafaFeatures features = 0; #ifdef HAVE_MMX_INTRINSICS features |= CHAFA_FEATURE_MMX; #endif #ifdef HAVE_SSE41_INTRINSICS features |= CHAFA_FEATURE_SSE41; #endif #ifdef HAVE_POPCNT_INTRINSICS features |= CHAFA_FEATURE_POPCNT; #endif #ifdef HAVE_AVX2_INTRINSICS features |= CHAFA_FEATURE_AVX2; #endif return features; } /** * chafa_get_supported_features: * * Gets a list of the platform-specific features that are built in and usable * on the runtime platform. * * Returns: A set of flags indicating usable features **/ ChafaFeatures chafa_get_supported_features (void) { chafa_init (); return (have_mmx ? CHAFA_FEATURE_MMX : 0) | (have_sse41 ? CHAFA_FEATURE_SSE41 : 0) | (have_popcnt ? CHAFA_FEATURE_POPCNT : 0) | (have_avx2 ? CHAFA_FEATURE_AVX2 : 0); } /** * chafa_describe_features: * @features: A set of flags representing features * * Takes a set of flags potentially returned from chafa_get_builtin_features () * or chafa_get_supported_features () and generates a human-readable ASCII * string descriptor. * * Returns: A string describing the features. This must be freed by caller. **/ gchar * chafa_describe_features (ChafaFeatures features) { GString *features_gstr = g_string_new (""); if (features & CHAFA_FEATURE_MMX) g_string_append (features_gstr, "mmx "); if (features & CHAFA_FEATURE_SSE41) g_string_append (features_gstr, "sse4.1 "); if (features & CHAFA_FEATURE_POPCNT) g_string_append (features_gstr, "popcnt "); if (features & CHAFA_FEATURE_AVX2) g_string_append (features_gstr, "avx2 "); if (features_gstr->len > 0 && features_gstr->str [features_gstr->len - 1] == ' ') g_string_truncate (features_gstr, features_gstr->len - 1); return g_string_free (features_gstr, FALSE); } /** * chafa_get_n_threads: * * Queries the maximum number of worker threads to use for parallel processing. * * Returns: The number of threads, or -1 if determined automatically **/ gint chafa_get_n_threads (void) { return g_atomic_int_get (&n_threads); } /** * chafa_set_n_threads: * @n: Number of threads * * Sets the maximum number of worker threads to use for parallel processing, * or -1 to determine this automatically. The default is -1. * * Setting this to 0 or 1 will avoid using thread pools and instead perform * all processing in the main thread. **/ void chafa_set_n_threads (gint n) { g_return_if_fail (n >= -1); g_atomic_int_set (&n_threads, n); } /** * chafa_get_n_actual_threads: * * Queries the number of worker threads that will actually be used for * parallel processing. * * Returns: Number of threads, always >= 1 **/ gint chafa_get_n_actual_threads (void) { gint n_actual_threads; n_actual_threads = chafa_get_n_threads (); if (n_actual_threads < 0) { n_actual_threads = g_get_num_processors (); n_actual_threads = MIN (n_actual_threads, AUTO_THREAD_COUNT_MAX); } if (n_actual_threads <= 0) n_actual_threads = 1; return n_actual_threads; } chafa-1.18.2/chafa/chafa-features.h000066400000000000000000000033021517447374300167530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_FEATURES_H__ #define __CHAFA_FEATURES_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS /* Features */ typedef enum { CHAFA_FEATURE_MMX = (1 << 0), CHAFA_FEATURE_SSE41 = (1 << 1), CHAFA_FEATURE_POPCNT = (1 << 2), CHAFA_FEATURE_AVX2 = (1 << 3) } ChafaFeatures; CHAFA_AVAILABLE_IN_ALL ChafaFeatures chafa_get_builtin_features (void); CHAFA_AVAILABLE_IN_ALL ChafaFeatures chafa_get_supported_features (void); CHAFA_AVAILABLE_IN_ALL gchar *chafa_describe_features (ChafaFeatures features); CHAFA_AVAILABLE_IN_1_10 gint chafa_get_n_threads (void); CHAFA_AVAILABLE_IN_1_10 void chafa_set_n_threads (gint n); CHAFA_AVAILABLE_IN_1_10 gint chafa_get_n_actual_threads (void); G_END_DECLS #endif /* __CHAFA_FEATURES_H__ */ chafa-1.18.2/chafa/chafa-frame.c000066400000000000000000000124101517447374300162220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-private.h" #include /** * SECTION:chafa-frame * @title: ChafaFrame * @short_description: A raster image frame that can be added to a ChafaImage * * A #ChafaFrame contains the specific of a single frame of image data. It can * be added to a #ChafaImage. **/ static ChafaFrame * new_frame (gpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride, gboolean data_is_owned) { ChafaFrame *frame; frame = g_new0 (ChafaFrame, 1); frame->refs = 1; frame->pixel_type = pixel_type; frame->width = width; frame->height = height; frame->rowstride = rowstride; frame->data = data; frame->data_is_owned = data_is_owned; return frame; } /** * chafa_frame_new: * @data: Pointer to an image data buffer to copy from * @pixel_type: The #ChafaPixelType of the source data * @width: Width of the image, in pixels * @height: Height of the image, in pixels * @rowstride: Number of bytes to advance from the start of one row to the next * * Creates a new #ChafaFrame containing a copy of the image data pointed to * by @data. * * Returns: The new frame * * Since: 1.14 **/ ChafaFrame * chafa_frame_new (gconstpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride) { gpointer owned_data; gsize data_size = (gsize) height * rowstride; owned_data = g_malloc (data_size); memcpy (owned_data, data, data_size); return new_frame (owned_data, pixel_type, width, height, rowstride, TRUE); } /** * chafa_frame_new_steal: * @data: Pointer to an image data buffer to assign * @pixel_type: The #ChafaPixelType of the buffer * @width: Width of the image, in pixels * @height: Height of the image, in pixels * @rowstride: Number of bytes to advance from the start of one row to the next * * Creates a new #ChafaFrame, which takes ownership of the @data buffer. The * buffer will be freed with #g_free() when the frame's reference count drops * to zero. * * Returns: The new frame * * Since: 1.14 **/ ChafaFrame * chafa_frame_new_steal (gpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride) { return new_frame (data, pixel_type, width, height, rowstride, TRUE); } /** * chafa_frame_new_borrow: * @data: Pointer to an image data buffer to assign * @pixel_type: The #ChafaPixelType of the buffer * @width: Width of the image, in pixels * @height: Height of the image, in pixels * @rowstride: Number of bytes to advance from the start of one row to the next * * Creates a new #ChafaFrame embedding the @data pointer. It's the caller's * responsibility to ensure the pointer remains valid for the lifetime of * the frame. The frame will not free the buffer when its reference count drops * to zero. * * THIS IS DANGEROUS API which should only be used when the life cycle of the * frame is short, stealing the buffer is impossible, and copying would cause * unacceptable performance degradation. * * Use #chafa_frame_new() instead. * * Returns: The new frame * * Since: 1.14 **/ ChafaFrame * chafa_frame_new_borrow (gconstpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride) { /* Suppress the warning we get with -Wcast-qual. We honor the constness * by tracking it with the data_is_owned flag. */ return new_frame ((gpointer)(uintptr_t) data, pixel_type, width, height, rowstride, FALSE); } /** * chafa_frame_ref: * @frame: Frame to add a reference to * * Adds a reference to @frame. * * Since: 1.14 **/ void chafa_frame_ref (ChafaFrame *frame) { gint refs; g_return_if_fail (frame != NULL); refs = g_atomic_int_get (&frame->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&frame->refs); } /** * chafa_frame_unref: * @frame: Frame to remove a reference from * * Removes a reference from @frame. When the reference count drops to zero, * the frame is freed and can no longer be used. * * Since: 1.14 **/ void chafa_frame_unref (ChafaFrame *frame) { gint refs; g_return_if_fail (frame != NULL); refs = g_atomic_int_get (&frame->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&frame->refs)) { if (frame->data_is_owned) g_free (frame->data); g_free (frame); } } chafa-1.18.2/chafa/chafa-frame.h000066400000000000000000000035551517447374300162410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_FRAME_H__ #define __CHAFA_FRAME_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS typedef struct ChafaFrame ChafaFrame; CHAFA_AVAILABLE_IN_1_14 ChafaFrame *chafa_frame_new (gconstpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride); CHAFA_AVAILABLE_IN_1_14 ChafaFrame *chafa_frame_new_steal (gpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride); CHAFA_AVAILABLE_IN_1_14 ChafaFrame *chafa_frame_new_borrow (gconstpointer data, ChafaPixelType pixel_type, gint width, gint height, gint rowstride); CHAFA_AVAILABLE_IN_1_14 void chafa_frame_ref (ChafaFrame *frame); CHAFA_AVAILABLE_IN_1_14 void chafa_frame_unref (ChafaFrame *frame); G_END_DECLS #endif /* __CHAFA_FRAME_H__ */ chafa-1.18.2/chafa/chafa-image.c000066400000000000000000000055731517447374300162260ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-private.h" /** * SECTION:chafa-image * @title: ChafaImage * @short_description: An image to be placed on a #ChafaCanvas * * A #ChafaImage represents a raster image for placement on a #ChafaCanvas. It * can currently hold a single #ChafaFrame. * * To place an image on a canvas, it must first be assigned to a #ChafaPlacement. **/ /** * chafa_image_new: * * Creates a new #ChafaImage. The image is initially transparent and dimensionless. * * Returns: The new image * * Since: 1.14 **/ ChafaImage * chafa_image_new (void) { ChafaImage *image; image = g_new0 (ChafaImage, 1); image->refs = 1; return image; } /** * chafa_image_ref: * @image: Image to add a reference to * * Adds a reference to @image. * * Since: 1.14 **/ void chafa_image_ref (ChafaImage *image) { gint refs; g_return_if_fail (image != NULL); refs = g_atomic_int_get (&image->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&image->refs); } /** * chafa_image_unref: * @image: Image to remove a reference from * * Removes a reference from @image. When the reference count drops to zero, * the image is freed and can no longer be used. * * Since: 1.14 **/ void chafa_image_unref (ChafaImage *image) { gint refs; g_return_if_fail (image != NULL); refs = g_atomic_int_get (&image->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&image->refs)) { if (image->frame) chafa_frame_unref (image->frame); g_free (image); } } /** * chafa_image_set_frame: * @image: Image to assign frame to * @frame: Frame to be assigned to image * * Assigns @frame as the content for @image. The image will keep its own * reference to the frame. * * Since: 1.14 **/ void chafa_image_set_frame (ChafaImage *image, ChafaFrame *frame) { g_return_if_fail (image != NULL); if (frame) chafa_frame_ref (frame); if (image->frame) chafa_frame_unref (image->frame); image->frame = frame; } chafa-1.18.2/chafa/chafa-image.h000066400000000000000000000026121517447374300162220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_IMAGE_H__ #define __CHAFA_IMAGE_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS typedef struct ChafaImage ChafaImage; CHAFA_AVAILABLE_IN_1_14 ChafaImage *chafa_image_new (void); CHAFA_AVAILABLE_IN_1_14 void chafa_image_ref (ChafaImage *image); CHAFA_AVAILABLE_IN_1_14 void chafa_image_unref (ChafaImage *image); CHAFA_AVAILABLE_IN_1_14 void chafa_image_set_frame (ChafaImage *image, ChafaFrame *frame); G_END_DECLS #endif /* __CHAFA_IMAGE_H__ */ chafa-1.18.2/chafa/chafa-placement.c000066400000000000000000000127641517447374300171140ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-private.h" /** * SECTION:chafa-placement * @title: ChafaPlacement * @short_description: Placement of a #ChafaImage on a #ChafaCanvas * * A #ChafaPlacement describes how an image is placed on a #ChafaCanvas. It * contains information about the image, its alignment and tucking policy. **/ /** * chafa_placement_new: * @image: The image to place on the canvas * @id: An ID to assign to the placement, or <= 0 to assign one automatically * * Creates a new #ChafaPlacement. * * Returns: The new placement * * Since: 1.14 **/ ChafaPlacement * chafa_placement_new (ChafaImage *image, gint id) { ChafaPlacement *placement; g_return_val_if_fail (image != NULL, NULL); if (id < 1) id = -1; placement = g_new0 (ChafaPlacement, 1); placement->refs = 1; chafa_image_ref (image); placement->image = image; placement->id = id; placement->halign = CHAFA_ALIGN_START; placement->valign = CHAFA_ALIGN_START; placement->tuck = CHAFA_TUCK_STRETCH; return placement; } /** * chafa_placement_ref: * @placement: Placement to add a reference to * * Adds a reference to @placement. * * Since: 1.14 **/ void chafa_placement_ref (ChafaPlacement *placement) { gint refs; g_return_if_fail (placement != NULL); refs = g_atomic_int_get (&placement->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&placement->refs); } /** * chafa_placement_unref: * @placement: Placement to remove a reference from * * Removes a reference from @placement. When remaining references drops to * zero, the placement is freed and can no longer be used. * * Since: 1.14 **/ void chafa_placement_unref (ChafaPlacement *placement) { gint refs; g_return_if_fail (placement != NULL); refs = g_atomic_int_get (&placement->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&placement->refs)) { chafa_image_unref (placement->image); g_free (placement); } } /** * chafa_placement_get_tuck: * @placement: A #ChafaPlacement * * Gets the tucking policy of @placement. This describes how the image is * resized to fit @placement's extents, and defaults to #CHAFA_TUCK_STRETCH. * * Returns: The tucking policy of @placement * * Since: 1.14 **/ ChafaTuck chafa_placement_get_tuck (ChafaPlacement *placement) { g_return_val_if_fail (placement != NULL, CHAFA_TUCK_FIT); return placement->tuck; } /** * chafa_placement_set_tuck: * @placement: A #ChafaPlacement * @tuck: Desired tucking policy * * Sets the tucking policy for @placement to @tuck. This describes how the image is * resized to fit @placement's extents, and defaults to #CHAFA_TUCK_STRETCH. * * Since: 1.14 **/ void chafa_placement_set_tuck (ChafaPlacement *placement, ChafaTuck tuck) { g_return_if_fail (placement != NULL); placement->tuck = tuck; } /** * chafa_placement_get_halign: * @placement: A #ChafaPlacement * * Gets the horizontal alignment of @placement. This determines how any * padding added by the tucking policy is distributed, and defaults to * #CHAFA_ALIGN_START. * * Returns: The horizontal alignment of @placement * * Since: 1.14 **/ ChafaAlign chafa_placement_get_halign (ChafaPlacement *placement) { g_return_val_if_fail (placement != NULL, CHAFA_ALIGN_START); return placement->halign; } /** * chafa_placement_set_halign: * @placement: A #ChafaPlacement * @align: Desired horizontal alignment * * Sets the horizontal alignment of @placement. This determines how any * padding added by the tucking policy is distributed, and defaults to * #CHAFA_ALIGN_START. * * Since: 1.14 **/ void chafa_placement_set_halign (ChafaPlacement *placement, ChafaAlign align) { g_return_if_fail (placement != NULL); placement->halign = align; } /** * chafa_placement_get_valign: * @placement: A #ChafaPlacement * * Gets the vertical alignment of @placement. This determines how any * padding added by the tucking policy is distributed, and defaults to * #CHAFA_ALIGN_START. * * Returns: The vertical alignment of @placement * * Since: 1.14 **/ ChafaAlign chafa_placement_get_valign (ChafaPlacement *placement) { g_return_val_if_fail (placement != NULL, CHAFA_ALIGN_START); return placement->valign; } /** * chafa_placement_set_valign: * @placement: A #ChafaPlacement * @align: Desired vertical alignment * * Sets the vertical alignment of @placement. This determines how any * padding added by the tucking policy is distributed. * * Since: 1.14 **/ void chafa_placement_set_valign (ChafaPlacement *placement, ChafaAlign align) { g_return_if_fail (placement != NULL); placement->valign = align; } chafa-1.18.2/chafa/chafa-placement.h000066400000000000000000000036721517447374300171170ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PLACEMENT_H__ #define __CHAFA_PLACEMENT_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS typedef struct ChafaPlacement ChafaPlacement; CHAFA_AVAILABLE_IN_1_14 ChafaPlacement *chafa_placement_new (ChafaImage *image, gint id); CHAFA_AVAILABLE_IN_1_14 void chafa_placement_ref (ChafaPlacement *placement); CHAFA_AVAILABLE_IN_1_14 void chafa_placement_unref (ChafaPlacement *placement); CHAFA_AVAILABLE_IN_1_14 ChafaTuck chafa_placement_get_tuck (ChafaPlacement *placement); CHAFA_AVAILABLE_IN_1_14 void chafa_placement_set_tuck (ChafaPlacement *placement, ChafaTuck tuck); CHAFA_AVAILABLE_IN_1_14 ChafaAlign chafa_placement_get_halign (ChafaPlacement *placement); CHAFA_AVAILABLE_IN_1_14 void chafa_placement_set_halign (ChafaPlacement *placement, ChafaAlign align); CHAFA_AVAILABLE_IN_1_14 ChafaAlign chafa_placement_get_valign (ChafaPlacement *placement); CHAFA_AVAILABLE_IN_1_14 void chafa_placement_set_valign (ChafaPlacement *placement, ChafaAlign align); G_END_DECLS #endif /* __CHAFA_PLACEMENT_H__ */ chafa-1.18.2/chafa/chafa-symbol-map.c000066400000000000000000001574331517447374300172270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* memset, memcpy */ #include /* qsort */ #include "chafa.h" #include "internal/chafa-private.h" #include "internal/smolscale/smolscale.h" /* Max number of candidates to return from chafa_symbol_map_find_candidates() */ #define N_CANDIDATES_MAX 8 typedef enum { SELECTOR_TAG, SELECTOR_RANGE } SelectorType; typedef struct { guint selector_type : 1; guint additive : 1; ChafaSymbolTags tags; /* First and last code points are inclusive */ gunichar first_code_point; gunichar last_code_point; } Selector; typedef struct { gunichar c; guint64 bitmap; } Glyph; /* Double-width glyphs */ typedef struct { gunichar c; guint64 bitmap [2]; } Glyph2; /** * CHAFA_SYMBOL_WIDTH_PIXELS: * * The width of an internal symbol pixel matrix. If you are prescaling * input graphics, you will get the best results when scaling to a * multiple of this value. **/ /** * CHAFA_SYMBOL_HEIGHT_PIXELS: * * The height of an internal symbol pixel matrix. If you are prescaling * input graphics, you will get the best results when scaling to a * multiple of this value. **/ /** * ChafaSymbolTags: * @CHAFA_SYMBOL_TAG_NONE: Special value meaning no symbols. * @CHAFA_SYMBOL_TAG_SPACE: Space. * @CHAFA_SYMBOL_TAG_SOLID: Solid (inverse of space). * @CHAFA_SYMBOL_TAG_STIPPLE: Stipple symbols. * @CHAFA_SYMBOL_TAG_BLOCK: Block symbols. * @CHAFA_SYMBOL_TAG_BORDER: Border symbols. * @CHAFA_SYMBOL_TAG_DIAGONAL: Diagonal border symbols. * @CHAFA_SYMBOL_TAG_DOT: Symbols that look like isolated dots (excluding Braille). * @CHAFA_SYMBOL_TAG_QUAD: Quadrant block symbols. * @CHAFA_SYMBOL_TAG_HHALF: Horizontal half block symbols. * @CHAFA_SYMBOL_TAG_VHALF: Vertical half block symbols. * @CHAFA_SYMBOL_TAG_HALF: Joint set of horizontal and vertical halves. * @CHAFA_SYMBOL_TAG_INVERTED: Symbols that are the inverse of simpler symbols. When two symbols complement each other, only one will have this tag. * @CHAFA_SYMBOL_TAG_BRAILLE: Braille symbols. * @CHAFA_SYMBOL_TAG_TECHNICAL: Miscellaneous technical symbols. * @CHAFA_SYMBOL_TAG_GEOMETRIC: Geometric shapes. * @CHAFA_SYMBOL_TAG_ASCII: Printable ASCII characters. * @CHAFA_SYMBOL_TAG_ALPHA: Letters. * @CHAFA_SYMBOL_TAG_DIGIT: Digits. * @CHAFA_SYMBOL_TAG_ALNUM: Joint set of letters and digits. * @CHAFA_SYMBOL_TAG_NARROW: Characters that are one cell wide. * @CHAFA_SYMBOL_TAG_WIDE: Characters that are two cells wide. * @CHAFA_SYMBOL_TAG_AMBIGUOUS: Characters of uncertain width. Always excluded unless specifically asked for. * @CHAFA_SYMBOL_TAG_UGLY: Characters that are generally undesired or unlikely to render well. Always excluded unless specifically asked for. * @CHAFA_SYMBOL_TAG_LEGACY: Legacy computer symbols, including sextants, wedges and more. * @CHAFA_SYMBOL_TAG_SEXTANT: Sextant 2x3 mosaics. * @CHAFA_SYMBOL_TAG_WEDGE: Wedge shapes that align with sextants. * @CHAFA_SYMBOL_TAG_LATIN: Latin and Latin-like symbols (superset of ASCII). * @CHAFA_SYMBOL_TAG_IMPORTED: Symbols for which glyphs were imported with chafa_symbol_map_add_glyph (). * @CHAFA_SYMBOL_TAG_OCTANT: Octant 2x4 mosaics. * @CHAFA_SYMBOL_TAG_EXTRA: Symbols not in any other category. * @CHAFA_SYMBOL_TAG_BAD: Joint set of ugly and ambiguous characters. Always excluded unless specifically asked for. * @CHAFA_SYMBOL_TAG_ALL: Special value meaning all supported symbols. **/ /** * SECTION:chafa-symbol-map * @title: ChafaSymbolMap * @short_description: Describes a selection of textual symbols * * A #ChafaSymbolMap describes a selection of the supported textual symbols * that can be used in building a printable output string from a #ChafaCanvas. * * To create a new #ChafaSymbolMap, use chafa_symbol_map_new (). You can then * add symbols to it using chafa_symbol_map_add_by_tags () before copying * it into a #ChafaCanvasConfig using chafa_canvas_config_set_symbol_map (). * * Note that some symbols match multiple tags, so it makes sense to e.g. * add symbols matching #CHAFA_SYMBOL_TAG_BORDER and then removing symbols * matching #CHAFA_SYMBOL_TAG_DIAGONAL. * * The number of available symbols is a significant factor in the speed of * #ChafaCanvas. For the fastest possible operation you could use a single * symbol -- #CHAFA_SYMBOL_TAG_VHALF works well by itself. **/ /* Private */ #if 0 static gint compare_symbols (const void *a, const void *b) { const ChafaSymbol *a_sym = a; const ChafaSymbol *b_sym = b; if (a_sym->c < b_sym->c) return -1; if (a_sym->c > b_sym->c) return 1; return 0; } #endif static guint8 * bitmap_to_bytes (guint64 bitmap) { guint8 *cov = g_malloc0 (CHAFA_SYMBOL_N_PIXELS); gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { cov [i] = (bitmap >> (CHAFA_SYMBOL_N_PIXELS - 1 - i)) & 1; } return cov; } /* Input format must always be RGBA8. old_format is just an indicator of how * the channel values are to be extracted. */ static void pixels_to_coverage (const guint8 *pixels_in, ChafaPixelType old_format, guint8 *pixels_out, gint n_pixels) { gint i; if (old_format == CHAFA_PIXEL_RGB8 || old_format == CHAFA_PIXEL_BGR8) { for (i = 0; i < n_pixels; i++) pixels_out [i] = (pixels_in [i * 4] + pixels_in [i * 4 + 1] + pixels_in [i * 4 + 2]) / 3; } else { for (i = 0; i < n_pixels; i++) pixels_out [i] = pixels_in [i * 4 + 3]; } } static void sharpen_coverage (const guint8 *cov_in, guint8 *cov_out, gint width, gint height) { gint k [3] [3] = { /* Sharpen + boost contrast */ { 0, -1, 0 }, { -1, 6, -1 }, { 0, -1, 0 } }; gint x, y; gint i, j; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { gint sum = 0; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { gint a = x + i - 1, b = y + j - 1; /* At edges, just clone the border pixels outwards */ a = CLAMP (a, 0, width - 1); b = CLAMP (b, 0, height - 1); sum += (gint) cov_in [a + b * width] * k [i] [j]; } } cov_out [x + y * width] = CLAMP (sum, 0, 255); } } } static guint64 coverage_to_bitmap (const guint8 *cov, gint rowstride) { guint64 bitmap = 0; gint x, y; for (y = 0; y < CHAFA_SYMBOL_HEIGHT_PIXELS; y++) { for (x = 0; x < CHAFA_SYMBOL_WIDTH_PIXELS; x++) { bitmap <<= 1; if (cov [y * rowstride + x] > 127) bitmap |= 1; } } return bitmap; } static void bitmap_to_argb (guint64 bitmap, guint8 *argb, gint rowstride) { guint8 *p; gint x, y; for (y = 0; y < CHAFA_SYMBOL_HEIGHT_PIXELS; y++) { p = argb + y * rowstride; for (x = 0; x < CHAFA_SYMBOL_WIDTH_PIXELS; x++) { guint32 *p32 = (guint32 *) p; /* Set = 0xffffffff, clear = 0x00000000 */ *p32 = ((guint32) -(gint64) ((bitmap >> 63) & 1)); p += 4; bitmap <<= 1; } } } static gpointer bitmap_to_argb_alloc (guint64 bitmap) { gpointer argb; argb = g_malloc (CHAFA_SYMBOL_N_PIXELS * 4); bitmap_to_argb (bitmap, argb, CHAFA_SYMBOL_WIDTH_PIXELS * 4); return argb; } static gpointer bitmap2_to_argb_alloc (guint64 bitmap_0, guint64 bitmap_1) { gpointer argb; argb = g_malloc (CHAFA_SYMBOL_N_PIXELS * 4 * 2); bitmap_to_argb (bitmap_0, argb, CHAFA_SYMBOL_WIDTH_PIXELS * 4 * 2); bitmap_to_argb (bitmap_1, ((guint8 *) argb) + CHAFA_SYMBOL_WIDTH_PIXELS * 4, CHAFA_SYMBOL_WIDTH_PIXELS * 4 * 2); return argb; } static guint64 glyph_to_bitmap (gint width, gint height, gint rowstride, ChafaPixelType pixel_format, gpointer pixels) { guint8 scaled_pixels [CHAFA_SYMBOL_N_PIXELS * 4]; guint8 cov [CHAFA_SYMBOL_N_PIXELS]; guint8 sharpened_cov [CHAFA_SYMBOL_N_PIXELS]; guint64 bitmap; /* Scale to cell dimensions */ smol_scale_simple (pixels, (SmolPixelType) pixel_format, width, height, rowstride, (gpointer) scaled_pixels, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* FIXME: Premul */ CHAFA_SYMBOL_WIDTH_PIXELS, CHAFA_SYMBOL_HEIGHT_PIXELS, CHAFA_SYMBOL_WIDTH_PIXELS * 4, SMOL_NO_FLAGS); /* Generate coverage map */ pixels_to_coverage (scaled_pixels, pixel_format, cov, CHAFA_SYMBOL_N_PIXELS); sharpen_coverage (cov, sharpened_cov, CHAFA_SYMBOL_WIDTH_PIXELS, CHAFA_SYMBOL_HEIGHT_PIXELS); bitmap = coverage_to_bitmap (sharpened_cov, CHAFA_SYMBOL_WIDTH_PIXELS); return bitmap; } static void glyph_to_bitmap_wide (gint width, gint height, gint rowstride, ChafaPixelType pixel_format, gpointer pixels, guint64 *left_bitmap_out, guint64 *right_bitmap_out) { guint8 scaled_pixels [CHAFA_SYMBOL_N_PIXELS * 2 * 4]; guint8 cov [CHAFA_SYMBOL_N_PIXELS * 2]; guint8 sharpened_cov [CHAFA_SYMBOL_N_PIXELS * 2]; /* Scale to cell dimensions */ smol_scale_simple (pixels, (SmolPixelType) pixel_format, width, height, rowstride, (gpointer) scaled_pixels, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* FIXME: Premul */ CHAFA_SYMBOL_WIDTH_PIXELS * 2, CHAFA_SYMBOL_HEIGHT_PIXELS, CHAFA_SYMBOL_WIDTH_PIXELS * 4 * 2, SMOL_NO_FLAGS); /* Generate coverage map */ pixels_to_coverage (scaled_pixels, pixel_format, cov, CHAFA_SYMBOL_N_PIXELS * 2); sharpen_coverage (cov, sharpened_cov, CHAFA_SYMBOL_WIDTH_PIXELS * 2, CHAFA_SYMBOL_HEIGHT_PIXELS); *left_bitmap_out = coverage_to_bitmap (sharpened_cov, CHAFA_SYMBOL_WIDTH_PIXELS * 2); *right_bitmap_out = coverage_to_bitmap (sharpened_cov + CHAFA_SYMBOL_WIDTH_PIXELS, CHAFA_SYMBOL_WIDTH_PIXELS * 2); } static gint compare_symbols_popcount (const void *a, const void *b) { const ChafaSymbol *a_sym = a; const ChafaSymbol *b_sym = b; if (a_sym->popcount < b_sym->popcount) return -1; if (a_sym->popcount > b_sym->popcount) return 1; return 0; } static gint compare_symbols2_popcount (const void *a, const void *b) { const ChafaSymbol2 *a_sym = a; const ChafaSymbol2 *b_sym = b; if (a_sym->sym [0].popcount + a_sym->sym [1].popcount < b_sym->sym [0].popcount + b_sym->sym [1].popcount) return -1; if (a_sym->sym [0].popcount + a_sym->sym [1].popcount > b_sym->sym [0].popcount + b_sym->sym [1].popcount) return 1; return 0; } static void compile_symbols (ChafaSymbolMap *symbol_map, GHashTable *desired_symbols) { GHashTableIter iter; gpointer key, value; gint i; for (i = 0; i < symbol_map->n_symbols; i++) { g_free (symbol_map->symbols [i].coverage); g_free (symbol_map->symbols [i].mask_u32); } g_free (symbol_map->symbols); g_free (symbol_map->packed_bitmaps); symbol_map->n_symbols = g_hash_table_size (desired_symbols); symbol_map->symbols = g_new (ChafaSymbol, symbol_map->n_symbols + 1); g_hash_table_iter_init (&iter, desired_symbols); i = 0; while (g_hash_table_iter_next (&iter, &key, &value)) { ChafaSymbol *sym = value; symbol_map->symbols [i] = *sym; symbol_map->symbols [i].coverage = g_memdup (symbol_map->symbols [i].coverage, CHAFA_SYMBOL_N_PIXELS); symbol_map->symbols [i].mask_u32 = bitmap_to_argb_alloc (symbol_map->symbols [i].bitmap); i++; } qsort (symbol_map->symbols, symbol_map->n_symbols, sizeof (ChafaSymbol), compare_symbols_popcount); /* Clear sentinel */ memset (&symbol_map->symbols [symbol_map->n_symbols], 0, sizeof (ChafaSymbol)); symbol_map->packed_bitmaps = g_new (guint64, symbol_map->n_symbols); for (i = 0; i < symbol_map->n_symbols; i++) symbol_map->packed_bitmaps [i] = symbol_map->symbols [i].bitmap; } static void compile_symbols_wide (ChafaSymbolMap *symbol_map, GHashTable *desired_symbols) { GHashTableIter iter; gpointer key, value; gint i; for (i = 0; i < symbol_map->n_symbols2; i++) { g_free (symbol_map->symbols2 [i].sym [0].coverage); g_free (symbol_map->symbols2 [i].sym [0].mask_u32); g_free (symbol_map->symbols2 [i].sym [1].coverage); g_free (symbol_map->symbols2 [i].sym [1].mask_u32); } g_free (symbol_map->symbols2); symbol_map->n_symbols2 = g_hash_table_size (desired_symbols); symbol_map->symbols2 = g_new (ChafaSymbol2, symbol_map->n_symbols2 + 1); g_hash_table_iter_init (&iter, desired_symbols); i = 0; while (g_hash_table_iter_next (&iter, &key, &value)) { ChafaSymbol2 *sym = value; symbol_map->symbols2 [i] = *sym; symbol_map->symbols2 [i].sym [0].coverage = g_memdup (symbol_map->symbols2 [i].sym [0].coverage, CHAFA_SYMBOL_N_PIXELS); symbol_map->symbols2 [i].sym [0].mask_u32 = bitmap_to_argb_alloc (symbol_map->symbols2 [i].sym [0].bitmap); symbol_map->symbols2 [i].sym [1].coverage = g_memdup (symbol_map->symbols2 [i].sym [1].coverage, CHAFA_SYMBOL_N_PIXELS); symbol_map->symbols2 [i].sym [1].mask_u32 = bitmap_to_argb_alloc (symbol_map->symbols2 [i].sym [1].bitmap); i++; } qsort (symbol_map->symbols2, symbol_map->n_symbols2, sizeof (ChafaSymbol2), compare_symbols2_popcount); /* Clear sentinel */ memset (&symbol_map->symbols2 [symbol_map->n_symbols2], 0, sizeof (ChafaSymbol2)); symbol_map->packed_bitmaps2 = g_new (guint64, symbol_map->n_symbols2 * 2); for (i = 0; i < symbol_map->n_symbols2; i++) { symbol_map->packed_bitmaps2 [i * 2] = symbol_map->symbols2 [i].sym [0].bitmap; symbol_map->packed_bitmaps2 [i * 2 + 1] = symbol_map->symbols2 [i].sym [1].bitmap; } } static gboolean char_is_selected (GArray *selectors, ChafaSymbolTags tags, gunichar c) { ChafaSymbolTags auto_exclude_tags = CHAFA_SYMBOL_TAG_BAD; GUnicodeScript script; gboolean is_selected = FALSE; gint i; /* Always exclude characters that would mangle the output */ if (!g_unichar_isprint (c) || g_unichar_iszerowidth (c) || c == '\t') return FALSE; /* We don't support RTL, so RTL characters will break the output. * * Ideally we'd exclude the R and AL bidi classes, but unfortunately we don't * have a convenient API available to us to determine the bidi class of a * character. So we just exclude a few scripts and hope for the best. * * A better implementation could extract directionality from the Unicode DB: * * https://www.unicode.org/reports/tr9/#Bidirectional_Character_Types * https://www.unicode.org/Public/UCD/latest/ucd/extracted/DerivedBidiClass.txt */ script = g_unichar_get_script (c); if (script == G_UNICODE_SCRIPT_ARABIC || script == G_UNICODE_SCRIPT_HEBREW || script == G_UNICODE_SCRIPT_THAANA || script == G_UNICODE_SCRIPT_SYRIAC) return FALSE; for (i = 0; i < (gint) selectors->len; i++) { const Selector *selector = &g_array_index (selectors, Selector, i); switch (selector->selector_type) { case SELECTOR_TAG: if (tags & selector->tags) { is_selected = selector->additive ? TRUE : FALSE; /* We exclude "bad" symbols unless the user explicitly refers * to them by tag. I.e. the selector string "0..fffff" will not * include matches for "ugly", but "-ugly+0..fffff" will. */ auto_exclude_tags &= ~((guint) selector->tags); } break; case SELECTOR_RANGE: if (c >= selector->first_code_point && c <= selector->last_code_point) is_selected = selector->additive ? TRUE : FALSE; break; } } if (tags & auto_exclude_tags) is_selected = FALSE; return is_selected; } static void free_symbol (gpointer sym_p) { ChafaSymbol *sym = sym_p; g_free (sym->coverage); g_free (sym->mask_u32); g_free (sym); } static void free_symbol_wide (gpointer sym_p) { ChafaSymbol2 *sym = sym_p; g_free (sym->sym [0].coverage); g_free (sym->sym [0].mask_u32); g_free (sym->sym [1].coverage); g_free (sym->sym [1].mask_u32); g_free (sym); } static void rebuild_symbols (ChafaSymbolMap *symbol_map) { GHashTable *desired_syms; GHashTable *desired_syms_wide; GHashTableIter iter; gpointer key, value; gint i; desired_syms = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_symbol); desired_syms_wide = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_symbol_wide); /* Pick built-in symbols */ if (symbol_map->use_builtin_glyphs) { for (i = 0; chafa_symbols [i].c != 0; i++) { if (char_is_selected (symbol_map->selectors, chafa_symbols [i].sc, chafa_symbols [i].c)) { ChafaSymbol *sym = g_new (ChafaSymbol, 1); *sym = chafa_symbols [i]; sym->coverage = g_memdup (sym->coverage, CHAFA_SYMBOL_N_PIXELS); g_hash_table_replace (desired_syms, GUINT_TO_POINTER (chafa_symbols [i].c), sym); } } } /* Pick built-in symbols (wide) */ if (symbol_map->use_builtin_glyphs) { for (i = 0; chafa_symbols2 [i].sym [0].c != 0; i++) { if (char_is_selected (symbol_map->selectors, chafa_symbols2 [i].sym [0].sc, chafa_symbols2 [i].sym [0].c)) { ChafaSymbol2 *sym = g_new (ChafaSymbol2, 1); *sym = chafa_symbols2 [i]; sym->sym [0].coverage = g_memdup (sym->sym [0].coverage, CHAFA_SYMBOL_N_PIXELS); sym->sym [1].coverage = g_memdup (sym->sym [1].coverage, CHAFA_SYMBOL_N_PIXELS); g_hash_table_replace (desired_syms_wide, GUINT_TO_POINTER (chafa_symbols2 [i].sym [0].c), sym); } } } /* Pick user glyph symbols */ g_hash_table_iter_init (&iter, symbol_map->glyphs); while (g_hash_table_iter_next (&iter, &key, &value)) { Glyph *glyph = value; ChafaSymbolTags tags = chafa_get_tags_for_char (glyph->c) | CHAFA_SYMBOL_TAG_IMPORTED; if (char_is_selected (symbol_map->selectors, tags, glyph->c)) { ChafaSymbol *sym = g_new0 (ChafaSymbol, 1); sym->sc = tags; sym->c = glyph->c; sym->bitmap = glyph->bitmap; sym->coverage = (gchar *) bitmap_to_bytes (glyph->bitmap); sym->popcount = chafa_population_count_u64 (glyph->bitmap); sym->fg_weight = sym->popcount; sym->bg_weight = CHAFA_SYMBOL_N_PIXELS - sym->popcount; g_hash_table_replace (desired_syms, GUINT_TO_POINTER (glyph->c), sym); } } compile_symbols (symbol_map, desired_syms); g_hash_table_destroy (desired_syms); /* Pick user glyph symbols (wide) */ g_hash_table_iter_init (&iter, symbol_map->glyphs2); while (g_hash_table_iter_next (&iter, &key, &value)) { Glyph2 *glyph = value; ChafaSymbolTags tags = chafa_get_tags_for_char (glyph->c) | CHAFA_SYMBOL_TAG_IMPORTED; if (char_is_selected (symbol_map->selectors, tags, glyph->c)) { ChafaSymbol2 *sym = g_new0 (ChafaSymbol2, 1); sym->sym [0].sc = tags; sym->sym [0].c = glyph->c; sym->sym [0].bitmap = glyph->bitmap [0]; sym->sym [0].coverage = (gchar *) bitmap_to_bytes (glyph->bitmap [0]); sym->sym [0].popcount = chafa_population_count_u64 (glyph->bitmap [0]); sym->sym [0].fg_weight = sym->sym [0].popcount; sym->sym [0].bg_weight = CHAFA_SYMBOL_N_PIXELS - sym->sym [0].popcount; sym->sym [1].sc = tags; sym->sym [1].c = glyph->c; sym->sym [1].bitmap = glyph->bitmap [1]; sym->sym [1].coverage = (gchar *) bitmap_to_bytes (glyph->bitmap [1]); sym->sym [1].popcount = chafa_population_count_u64 (glyph->bitmap [1]); sym->sym [1].fg_weight = sym->sym [1].popcount; sym->sym [1].bg_weight = CHAFA_SYMBOL_N_PIXELS - sym->sym [1].popcount; g_hash_table_replace (desired_syms_wide, GUINT_TO_POINTER (glyph->c), sym); } } compile_symbols_wide (symbol_map, desired_syms_wide); g_hash_table_destroy (desired_syms_wide); symbol_map->need_rebuild = FALSE; } static GHashTable * copy_glyph_table (GHashTable *src) { GHashTable *dest; GHashTableIter iter; gpointer key, value; dest = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); g_hash_table_iter_init (&iter, src); while (g_hash_table_iter_next (&iter, &key, &value)) { g_hash_table_insert (dest, key, g_memdup (value, sizeof (Glyph))); } return dest; } static GHashTable * copy_glyph2_table (GHashTable *src) { GHashTable *dest; GHashTableIter iter; gpointer key, value; dest = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); g_hash_table_iter_init (&iter, src); while (g_hash_table_iter_next (&iter, &key, &value)) { g_hash_table_insert (dest, key, g_memdup (value, sizeof (Glyph2))); } return dest; } static GArray * copy_selector_array (GArray *src) { GArray *dest; gint i; dest = g_array_new (FALSE, FALSE, sizeof (Selector)); for (i = 0; i < (gint) src->len; i++) { const Selector *s = &g_array_index (src, Selector, i); g_array_append_val (dest, *s); } return dest; } static void add_by_tags (GArray *selectors, ChafaSymbolTags tags) { Selector s = { 0 }; s.selector_type = SELECTOR_TAG; s.additive = TRUE; s.tags = tags; g_array_append_val (selectors, s); } static void remove_by_tags (GArray *selectors, ChafaSymbolTags tags) { Selector s = { 0 }; s.selector_type = SELECTOR_TAG; s.additive = FALSE; s.tags = tags; g_array_append_val (selectors, s); } static void add_by_range (GArray *selectors, gunichar first, gunichar last) { Selector s = { 0 }; s.selector_type = SELECTOR_RANGE; s.additive = TRUE; s.first_code_point = first; s.last_code_point = last; g_array_append_val (selectors, s); } static void remove_by_range (GArray *selectors, gunichar first, gunichar last) { Selector s = { 0 }; s.selector_type = SELECTOR_RANGE; s.additive = FALSE; s.first_code_point = first; s.last_code_point = last; g_array_append_val (selectors, s); } static gboolean parse_code_point (const gchar *str, gint len, gint *parsed_len_out, gunichar *c_out) { gint i = 0; gunichar code = 0; gboolean result = FALSE; if (len >= 1 && (str [0] == 'u' || str [0] == 'U')) i++; if (len >= 2 && str [0] == '0' && str [1] == 'x') i += 2; for ( ; i < len; i++) { gint c = (gint) str [i]; if (c - '0' >= 0 && c - '0' <= 9) { code *= 16; code += c - '0'; } else if (c - 'a' >= 0 && c - 'a' <= 5) { code *= 16; code += c - 'a' + 10; } else if (c - 'A' >= 0 && c - 'A' <= 5) { code *= 16; code += c - 'A' + 10; } else break; result = TRUE; } *parsed_len_out = i; *c_out = code; return result; } typedef struct { const gchar *name; ChafaSymbolTags sc; } SymMapping; static gboolean parse_symbol_tag (const gchar *name, gint len, SelectorType *sel_type_out, ChafaSymbolTags *sc_out, gunichar *first_out, gunichar *last_out, GError **error) { const SymMapping map [] = { { "all", CHAFA_SYMBOL_TAG_ALL }, { "none", CHAFA_SYMBOL_TAG_NONE }, { "space", CHAFA_SYMBOL_TAG_SPACE }, { "solid", CHAFA_SYMBOL_TAG_SOLID }, { "stipple", CHAFA_SYMBOL_TAG_STIPPLE }, { "block", CHAFA_SYMBOL_TAG_BLOCK }, { "border", CHAFA_SYMBOL_TAG_BORDER }, { "diagonal", CHAFA_SYMBOL_TAG_DIAGONAL }, { "dot", CHAFA_SYMBOL_TAG_DOT }, { "quad", CHAFA_SYMBOL_TAG_QUAD }, { "half", CHAFA_SYMBOL_TAG_HALF }, { "hhalf", CHAFA_SYMBOL_TAG_HHALF }, { "vhalf", CHAFA_SYMBOL_TAG_VHALF }, { "inverted", CHAFA_SYMBOL_TAG_INVERTED }, { "braille", CHAFA_SYMBOL_TAG_BRAILLE }, { "sextant", CHAFA_SYMBOL_TAG_SEXTANT }, { "wedge", CHAFA_SYMBOL_TAG_WEDGE }, { "technical", CHAFA_SYMBOL_TAG_TECHNICAL }, { "geometric", CHAFA_SYMBOL_TAG_GEOMETRIC }, { "ascii", CHAFA_SYMBOL_TAG_ASCII }, { "alpha", CHAFA_SYMBOL_TAG_ALPHA }, { "digit", CHAFA_SYMBOL_TAG_DIGIT }, { "narrow", CHAFA_SYMBOL_TAG_NARROW }, { "wide", CHAFA_SYMBOL_TAG_WIDE }, { "ambiguous", CHAFA_SYMBOL_TAG_AMBIGUOUS }, { "ugly", CHAFA_SYMBOL_TAG_UGLY }, { "extra", CHAFA_SYMBOL_TAG_EXTRA }, { "alnum", CHAFA_SYMBOL_TAG_ALNUM }, { "bad", CHAFA_SYMBOL_TAG_BAD }, { "legacy", CHAFA_SYMBOL_TAG_LEGACY }, { "latin", CHAFA_SYMBOL_TAG_LATIN }, { "import", CHAFA_SYMBOL_TAG_IMPORTED }, { "imported", CHAFA_SYMBOL_TAG_IMPORTED }, { "octant", CHAFA_SYMBOL_TAG_OCTANT }, { NULL, 0 } }; gint parsed_len; gint i; /* Tag? */ for (i = 0; map [i].name; i++) { if (!g_ascii_strncasecmp (map [i].name, name, len)) { *sc_out = map [i].sc; *sel_type_out = SELECTOR_TAG; return TRUE; } } /* Range? */ if (!parse_code_point (name, len, &parsed_len, first_out)) goto err; if (len - parsed_len > 0) { gint parsed_last_len; if (len - parsed_len < 3 || name [parsed_len] != '.' || name [parsed_len + 1] != '.' || !parse_code_point (name + parsed_len + 2, len - parsed_len - 2, &parsed_last_len, last_out) || parsed_len + 2 + parsed_last_len != len) goto err; } else { *last_out = *first_out; } *sel_type_out = SELECTOR_RANGE; return TRUE; err: /* Bad input */ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unrecognized symbol tag '%.*s'.", len, name); return FALSE; } static gboolean parse_selectors (ChafaSymbolMap *symbol_map, const gchar *selectors, GError **error) { const gchar *p0 = selectors; gboolean is_add = FALSE, is_remove = FALSE, do_clear = FALSE; gboolean result = FALSE; GArray *selector_array = g_array_new (FALSE, FALSE, sizeof (Selector)); while (*p0) { SelectorType sel_type; ChafaSymbolTags sc; gunichar first, last; gint n; p0 += strspn (p0, " ,"); if (!*p0) break; if (*p0 == '-') { is_add = FALSE; is_remove = TRUE; p0++; } else if (*p0 == '+') { is_add = TRUE; is_remove = FALSE; p0++; } p0 += strspn (p0, " "); if (!*p0) break; if (!is_add && !is_remove) { do_clear = TRUE; is_add = TRUE; } if (*p0 == '[') { gboolean escape = FALSE; p0++; for ( ; p0 && *p0; p0 = g_utf8_next_char (p0)) { gunichar c = g_utf8_get_char (p0); if (c == '\\' && !escape) { escape = TRUE; continue; } if (c == ']' && !escape) break; if (is_add) add_by_range (selector_array, c, c); else if (is_remove) remove_by_range (selector_array, c, c); escape = FALSE; } if (!p0 || *p0 != ']') { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Syntax error in symbol selector set."); goto out; } n = 1; } else if (!(n = strspn (p0, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789."))) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Syntax error in symbol tag selectors."); goto out; } else if (!parse_symbol_tag (p0, n, &sel_type, &sc, &first, &last, error)) { goto out; } else { if (sel_type == SELECTOR_TAG) { if (is_add) add_by_tags (selector_array, sc); else if (is_remove) remove_by_tags (selector_array, sc); } else { if (is_add) add_by_range (selector_array, first, last); else if (is_remove) remove_by_range (selector_array, first, last); } } p0 += n; } if (do_clear) g_array_set_size (symbol_map->selectors, 0); g_array_append_vals (symbol_map->selectors, selector_array->data, selector_array->len); symbol_map->need_rebuild = TRUE; result = TRUE; out: g_array_free (selector_array, TRUE); return result; } void chafa_symbol_map_init (ChafaSymbolMap *symbol_map) { g_return_if_fail (symbol_map != NULL); /* We need the global symbol table */ chafa_init (); memset (symbol_map, 0, sizeof (*symbol_map)); symbol_map->refs = 1; symbol_map->use_builtin_glyphs = TRUE; symbol_map->glyphs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); symbol_map->glyphs2 = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); symbol_map->selectors = g_array_new (FALSE, FALSE, sizeof (Selector)); } void chafa_symbol_map_deinit (ChafaSymbolMap *symbol_map) { gint i; g_return_if_fail (symbol_map != NULL); for (i = 0; i < symbol_map->n_symbols; i++) { g_free (symbol_map->symbols [i].coverage); g_free (symbol_map->symbols [i].mask_u32); } for (i = 0; i < symbol_map->n_symbols2; i++) { g_free (symbol_map->symbols2 [i].sym [0].coverage); g_free (symbol_map->symbols2 [i].sym [0].mask_u32); g_free (symbol_map->symbols2 [i].sym [1].coverage); g_free (symbol_map->symbols2 [i].sym [1].mask_u32); } g_hash_table_destroy (symbol_map->glyphs); g_hash_table_destroy (symbol_map->glyphs2); g_array_free (symbol_map->selectors, TRUE); g_free (symbol_map->symbols); g_free (symbol_map->symbols2); g_free (symbol_map->packed_bitmaps); g_free (symbol_map->packed_bitmaps2); } void chafa_symbol_map_copy_contents (ChafaSymbolMap *dest, const ChafaSymbolMap *src) { g_return_if_fail (dest != NULL); g_return_if_fail (src != NULL); memcpy (dest, src, sizeof (*dest)); dest->glyphs = copy_glyph_table (dest->glyphs); dest->glyphs2 = copy_glyph2_table (dest->glyphs2); dest->selectors = copy_selector_array (dest->selectors); dest->symbols = NULL; dest->n_symbols = 0; dest->symbols2 = NULL; dest->n_symbols2 = 0; dest->packed_bitmaps = NULL; dest->packed_bitmaps2 = NULL; dest->need_rebuild = TRUE; dest->refs = 1; if (!src->need_rebuild) chafa_symbol_map_prepare (dest); } void chafa_symbol_map_prepare (ChafaSymbolMap *symbol_map) { if (!symbol_map->need_rebuild) return; rebuild_symbols (symbol_map); } gboolean chafa_symbol_map_has_symbol (const ChafaSymbolMap *symbol_map, gunichar symbol) { gint i; g_return_val_if_fail (symbol_map != NULL, FALSE); /* FIXME: Use gunichars as keys in hash table instead */ for (i = 0; i < symbol_map->n_symbols; i++) { const ChafaSymbol *sym = &symbol_map->symbols [i]; if (sym->c == symbol) return TRUE; } for (i = 0; i < symbol_map->n_symbols2; i++) { const ChafaSymbol2 *sym = &symbol_map->symbols2 [i]; if (sym->sym [0].c == symbol) return TRUE; } return FALSE; } /* Only call this when you know the candidate should be inserted */ static void insert_candidate (ChafaCandidate *candidates, const ChafaCandidate *new_cand) { gint i; i = N_CANDIDATES_MAX - 1; while (i) { i--; if (new_cand->hamming_distance >= candidates [i].hamming_distance) { memmove (candidates + i + 2, candidates + i + 1, (N_CANDIDATES_MAX - 2 - i) * sizeof (ChafaCandidate)); candidates [i + 1] = *new_cand; return; } } memmove (candidates + 1, candidates, (N_CANDIDATES_MAX - 1) * sizeof (ChafaCandidate)); candidates [0] = *new_cand; } void chafa_symbol_map_find_candidates (const ChafaSymbolMap *symbol_map, guint64 bitmap, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout) { ChafaCandidate candidates [N_CANDIDATES_MAX] = { { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE } }; gint *ham_dist; gint i; g_return_if_fail (symbol_map != NULL); ham_dist = g_new (gint, symbol_map->n_symbols + 1); chafa_hamming_distance_vu64 (bitmap, symbol_map->packed_bitmaps, ham_dist, symbol_map->n_symbols); if (do_inverse) { for (i = 0; i < symbol_map->n_symbols; i++) { ChafaCandidate cand; gint hd = ham_dist [i]; if (hd < candidates [N_CANDIDATES_MAX - 1].hamming_distance) { cand.symbol_index = i; cand.hamming_distance = hd; cand.is_inverted = FALSE; insert_candidate (candidates, &cand); } hd = 64 - hd; if (hd < candidates [N_CANDIDATES_MAX - 1].hamming_distance) { cand.symbol_index = i; cand.hamming_distance = hd; cand.is_inverted = TRUE; insert_candidate (candidates, &cand); } } } else { for (i = 0; i < symbol_map->n_symbols; i++) { ChafaCandidate cand; gint hd = ham_dist [i]; if (hd < candidates [N_CANDIDATES_MAX - 1].hamming_distance) { cand.symbol_index = i; cand.hamming_distance = hd; cand.is_inverted = FALSE; insert_candidate (candidates, &cand); } } } for (i = 0; i < N_CANDIDATES_MAX; i++) { if (candidates [i].hamming_distance > 64) break; } i = *n_candidates_inout = MIN (i, *n_candidates_inout); memcpy (candidates_out, candidates, i * sizeof (ChafaCandidate)); g_free (ham_dist); } void chafa_symbol_map_find_wide_candidates (const ChafaSymbolMap *symbol_map, const guint64 *bitmaps, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout) { ChafaCandidate candidates [N_CANDIDATES_MAX] = { { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE } }; gint *ham_dist; gint i; g_return_if_fail (symbol_map != NULL); ham_dist = g_new (gint, symbol_map->n_symbols2 + 1); chafa_hamming_distance_2_vu64 (bitmaps, symbol_map->packed_bitmaps2, ham_dist, symbol_map->n_symbols2); if (do_inverse) { for (i = 0; i < symbol_map->n_symbols2; i++) { ChafaCandidate cand; gint hd = ham_dist [i]; if (hd < candidates [N_CANDIDATES_MAX - 1].hamming_distance) { cand.symbol_index = i; cand.hamming_distance = hd; cand.is_inverted = FALSE; insert_candidate (candidates, &cand); } hd = 128 - hd; if (hd < candidates [N_CANDIDATES_MAX - 1].hamming_distance) { cand.symbol_index = i; cand.hamming_distance = hd; cand.is_inverted = TRUE; insert_candidate (candidates, &cand); } } } else { for (i = 0; i < symbol_map->n_symbols2; i++) { ChafaCandidate cand; gint hd = ham_dist [i]; if (hd < candidates [N_CANDIDATES_MAX - 1].hamming_distance) { cand.symbol_index = i; cand.hamming_distance = hd; cand.is_inverted = FALSE; insert_candidate (candidates, &cand); } } } for (i = 0; i < N_CANDIDATES_MAX; i++) { if (candidates [i].hamming_distance > 128) break; } i = *n_candidates_inout = MIN (i, *n_candidates_inout); memcpy (candidates_out, candidates, i * sizeof (ChafaCandidate)); g_free (ham_dist); } /* Assumes symbols are sorted by ascending popcount */ static gint find_closest_popcount (const ChafaSymbolMap *symbol_map, gint popcount) { gint i, j; g_assert (symbol_map->n_symbols > 0); i = 0; j = symbol_map->n_symbols - 1; while (i < j) { gint k = (i + j + 1) / 2; if (popcount < symbol_map->symbols [k].popcount) j = k - 1; else if (popcount >= symbol_map->symbols [k].popcount) i = k; else i = j = k; } /* If we didn't find the exact popcount, the i+1'th element may be * a closer match. */ if (i < symbol_map->n_symbols - 1 && (abs (popcount - symbol_map->symbols [i + 1].popcount) < abs (popcount - symbol_map->symbols [i].popcount))) { i++; } return i; } /* Always returns zero or one candidates. We may want to do more in the future */ void chafa_symbol_map_find_fill_candidates (const ChafaSymbolMap *symbol_map, gint popcount, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout) { ChafaCandidate candidates [N_CANDIDATES_MAX] = { { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE }, { 0, 65, FALSE } }; gint sym, distance; gint i; g_return_if_fail (symbol_map != NULL); if (!*n_candidates_inout) return; if (symbol_map->n_symbols == 0) { *n_candidates_inout = 0; return; } sym = find_closest_popcount (symbol_map, popcount); candidates [0].symbol_index = sym; candidates [0].hamming_distance = abs (popcount - symbol_map->symbols [sym].popcount); candidates [0].is_inverted = FALSE; if (do_inverse && candidates [0].hamming_distance != 0) { sym = find_closest_popcount (symbol_map, 64 - popcount); distance = abs (64 - popcount - symbol_map->symbols [sym].popcount); if (distance < candidates [0].hamming_distance) { candidates [0].symbol_index = sym; candidates [0].hamming_distance = distance; candidates [0].is_inverted = TRUE; } } for (i = 0; i < N_CANDIDATES_MAX; i++) { if (candidates [i].hamming_distance > 64) break; } i = *n_candidates_inout = MIN (i, *n_candidates_inout); memcpy (candidates_out, candidates, i * sizeof (ChafaCandidate)); } /* Assumes symbols are sorted by ascending popcount */ static gint find_closest_popcount_wide (const ChafaSymbolMap *symbol_map, gint popcount) { gint i, j; g_assert (symbol_map->n_symbols2 > 0); i = 0; j = symbol_map->n_symbols2 - 1; while (i < j) { gint k = (i + j + 1) / 2; if (popcount < symbol_map->symbols2 [k].sym [0].popcount + symbol_map->symbols2 [k].sym [1].popcount) j = k - 1; else if (popcount >= symbol_map->symbols2 [k].sym [0].popcount + symbol_map->symbols2 [k].sym [1].popcount) i = k; else i = j = k; } /* If we didn't find the exact popcount, the i+1'th element may be * a closer match. */ if (i < symbol_map->n_symbols2 - 1 && (abs (popcount - (symbol_map->symbols2 [i + 1].sym [0].popcount + symbol_map->symbols2 [i + 1].sym [1].popcount)) < abs (popcount - (symbol_map->symbols2 [i].sym [0].popcount + symbol_map->symbols2 [i].sym [1].popcount)))) { i++; } return i; } /* Always returns zero or one candidates. We may want to do more in the future */ void chafa_symbol_map_find_wide_fill_candidates (const ChafaSymbolMap *symbol_map, gint popcount, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout) { ChafaCandidate candidates [N_CANDIDATES_MAX] = { { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE }, { 0, 129, FALSE } }; gint sym, distance; gint i; g_return_if_fail (symbol_map != NULL); if (!*n_candidates_inout) return; if (symbol_map->n_symbols2 == 0) { *n_candidates_inout = 0; return; } sym = find_closest_popcount_wide (symbol_map, popcount); candidates [0].symbol_index = sym; candidates [0].hamming_distance = abs (popcount - (symbol_map->symbols2 [sym].sym [0].popcount + symbol_map->symbols2 [sym].sym [1].popcount)); candidates [0].is_inverted = FALSE; if (do_inverse && candidates [0].hamming_distance != 0) { sym = find_closest_popcount (symbol_map, 128 - popcount); distance = abs (128 - popcount - (symbol_map->symbols2 [sym].sym [0].popcount + symbol_map->symbols2 [sym].sym [1].popcount)); if (distance < candidates [0].hamming_distance) { candidates [0].symbol_index = sym; candidates [0].hamming_distance = distance; candidates [0].is_inverted = TRUE; } } for (i = 0; i < N_CANDIDATES_MAX; i++) { if (candidates [i].hamming_distance > 128) break; } i = *n_candidates_inout = MIN (i, *n_candidates_inout); memcpy (candidates_out, candidates, i * sizeof (ChafaCandidate)); } /* Public */ /** * chafa_symbol_map_new: * * Creates a new #ChafaSymbolMap representing a set of Unicode symbols. The * symbol map starts out empty. * * Returns: The new symbol map **/ ChafaSymbolMap * chafa_symbol_map_new (void) { ChafaSymbolMap *symbol_map; symbol_map = g_new (ChafaSymbolMap, 1); chafa_symbol_map_init (symbol_map); return symbol_map; } /** * chafa_symbol_map_copy: * @symbol_map: A #ChafaSymbolMap to copy. * * Creates a new #ChafaSymbolMap that's a copy of @symbol_map. * * Returns: The new #ChafaSymbolMap **/ ChafaSymbolMap * chafa_symbol_map_copy (const ChafaSymbolMap *symbol_map) { ChafaSymbolMap *new_symbol_map; new_symbol_map = g_new (ChafaSymbolMap, 1); chafa_symbol_map_copy_contents (new_symbol_map, symbol_map); return new_symbol_map; } /** * chafa_symbol_map_ref: * @symbol_map: Symbol map to add a reference to * * Adds a reference to @symbol_map. **/ void chafa_symbol_map_ref (ChafaSymbolMap *symbol_map) { gint refs; g_return_if_fail (symbol_map != NULL); refs = g_atomic_int_get (&symbol_map->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&symbol_map->refs); } /** * chafa_symbol_map_unref: * @symbol_map: Symbol map to remove a reference from * * Removes a reference from @symbol_map. When remaining references drops to * zero, the symbol map is freed and can no longer be used. **/ void chafa_symbol_map_unref (ChafaSymbolMap *symbol_map) { gint refs; g_return_if_fail (symbol_map != NULL); refs = g_atomic_int_get (&symbol_map->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&symbol_map->refs)) { chafa_symbol_map_deinit (symbol_map); g_free (symbol_map); } } /** * chafa_symbol_map_add_by_tags: * @symbol_map: Symbol map to add symbols to * @tags: Selector tags for symbols to add * * Adds symbols matching the set of @tags to @symbol_map. **/ void chafa_symbol_map_add_by_tags (ChafaSymbolMap *symbol_map, ChafaSymbolTags tags) { g_return_if_fail (symbol_map != NULL); g_return_if_fail (symbol_map->refs > 0); add_by_tags (symbol_map->selectors, tags); symbol_map->need_rebuild = TRUE; } /** * chafa_symbol_map_remove_by_tags: * @symbol_map: Symbol map to remove symbols from * @tags: Selector tags for symbols to remove * * Removes symbols matching the set of @tags from @symbol_map. **/ void chafa_symbol_map_remove_by_tags (ChafaSymbolMap *symbol_map, ChafaSymbolTags tags) { g_return_if_fail (symbol_map != NULL); g_return_if_fail (symbol_map->refs > 0); remove_by_tags (symbol_map->selectors, tags); symbol_map->need_rebuild = TRUE; } /** * chafa_symbol_map_add_by_range: * @symbol_map: Symbol map to add symbols to * @first: First code point to add, inclusive * @last: Last code point to add, inclusive * * Adds symbols in the code point range starting with @first * and ending with @last to @symbol_map. * * Since: 1.4 **/ void chafa_symbol_map_add_by_range (ChafaSymbolMap *symbol_map, gunichar first, gunichar last) { g_return_if_fail (symbol_map != NULL); g_return_if_fail (symbol_map->refs > 0); add_by_range (symbol_map->selectors, first, last); symbol_map->need_rebuild = TRUE; } /** * chafa_symbol_map_remove_by_range: * @symbol_map: Symbol map to remove symbols from * @first: First code point to remove, inclusive * @last: Last code point to remove, inclusive * * Removes symbols in the code point range starting with @first * and ending with @last from @symbol_map. * * Since: 1.4 **/ void chafa_symbol_map_remove_by_range (ChafaSymbolMap *symbol_map, gunichar first, gunichar last) { g_return_if_fail (symbol_map != NULL); g_return_if_fail (symbol_map->refs > 0); remove_by_range (symbol_map->selectors, first, last); symbol_map->need_rebuild = TRUE; } /** * chafa_symbol_map_apply_selectors: * @symbol_map: Symbol map to apply selection to * @selectors: A string specifying selections * @error: Return location for an error, or %NULL * * Parses a string consisting of symbol tags separated by [+-,] and * applies the pattern to @symbol_map. If the string begins with + or -, * it's understood to be relative to the current set in @symbol_map, * otherwise the map is cleared first. * * The symbol tags are string versions of #ChafaSymbolTags, i.e. * [all, none, space, solid, stipple, block, border, diagonal, dot, * quad, half, hhalf, vhalf, braille, technical, geometric, ascii, * extra]. * * Examples: "block,border" sets map to contain symbols matching either * of those tags. "+block,border-dot,stipple" adds block and border * symbols then removes dot and stipple symbols. * * If there is a parse error, none of the changes are applied. * * Returns: %TRUE on success, %FALSE if there was a parse error **/ gboolean chafa_symbol_map_apply_selectors (ChafaSymbolMap *symbol_map, const gchar *selectors, GError **error) { g_return_val_if_fail (symbol_map != NULL, FALSE); g_return_val_if_fail (symbol_map->refs > 0, FALSE); return parse_selectors (symbol_map, selectors, error); } /* --- Glyphs --- */ /** * chafa_symbol_map_get_allow_builtin_glyphs: * @symbol_map: A symbol map * * Queries whether a symbol map is allowed to use built-in glyphs for * symbol selection. This can be turned off if you want to use your * own glyphs exclusively (see chafa_symbol_map_add_glyph()). * * Defaults to %TRUE. * * Returns: %TRUE if built-in glyphs are allowed * * Since: 1.4 **/ gboolean chafa_symbol_map_get_allow_builtin_glyphs (ChafaSymbolMap *symbol_map) { g_return_val_if_fail (symbol_map != NULL, FALSE); return symbol_map->use_builtin_glyphs; } /** * chafa_symbol_map_set_allow_builtin_glyphs: * @symbol_map: A symbol map * @use_builtin_glyphs: A boolean indicating whether to use built-in glyphs * * Controls whether a symbol map is allowed to use built-in glyphs for * symbol selection. This can be turned off if you want to use your * own glyphs exclusively (see chafa_symbol_map_add_glyph()). * * Defaults to %TRUE. * * Since: 1.4 **/ void chafa_symbol_map_set_allow_builtin_glyphs (ChafaSymbolMap *symbol_map, gboolean use_builtin_glyphs) { g_return_if_fail (symbol_map != NULL); /* Avoid unnecessary rebuild */ if (symbol_map->use_builtin_glyphs == use_builtin_glyphs) return; symbol_map->use_builtin_glyphs = use_builtin_glyphs; symbol_map->need_rebuild = TRUE; } /** * chafa_symbol_map_add_glyph: * @symbol_map: A symbol map * @code_point: The Unicode code point for this glyph * @pixel_format: Glyph pixel format of @pixels * @pixels: The glyph data * @width: Width of glyph, in pixels * @height: Height of glyph, in pixels * @rowstride: Offset from start of one row to the next, in bytes * * Assigns a rendered glyph to a Unicode code point. This tells Chafa what the * glyph looks like so the corresponding symbol can be used appropriately in * output. * * Assigned glyphs override built-in glyphs and any earlier glyph that may * have been assigned to the same code point. * * If the input is in a format with an alpha channel, the alpha channel will * be used for the shape. If not, an average of the color channels will be used. * * Since: 1.4 **/ void chafa_symbol_map_add_glyph (ChafaSymbolMap *symbol_map, gunichar code_point, ChafaPixelType pixel_format, gpointer pixels, gint width, gint height, gint rowstride) { g_return_if_fail (symbol_map != NULL); if (g_unichar_iswide (code_point)) { Glyph2 *glyph2; if (g_hash_table_size (symbol_map->glyphs2) >= G_MAXINT - 1) return; glyph2 = g_new (Glyph2, 1); glyph2->c = code_point; glyph_to_bitmap_wide (width, height, rowstride, pixel_format, pixels, &glyph2->bitmap [0], &glyph2->bitmap [1]); g_hash_table_insert (symbol_map->glyphs2, GUINT_TO_POINTER (code_point), glyph2); } else { Glyph *glyph; if (g_hash_table_size (symbol_map->glyphs) >= G_MAXINT - 1) return; glyph = g_new (Glyph, 1); glyph->c = code_point; glyph->bitmap = glyph_to_bitmap (width, height, rowstride, pixel_format, pixels); g_hash_table_insert (symbol_map->glyphs, GUINT_TO_POINTER (code_point), glyph); } symbol_map->need_rebuild = TRUE; } /** * chafa_symbol_map_get_glyph: * @symbol_map: A symbol map * @code_point: A Unicode code point * @pixel_format: Desired pixel format of @pixels_out * @pixels_out: Storage for a pointer to exported glyph data * @width_out: Storage for width of glyph, in pixels * @height_out: Storage for height of glyph, in pixels * @rowstride_out: Storage for offset from start of one row to the next, in bytes * * Returns data for the glyph corresponding to @code_point stored in @symbol_map. * Any of @pixels_out, @width_out, @height_out and @rowstride_out can be NULL, * in which case the corresponding data is not retrieved. * * If @pixels_out is not NULL, a pointer to freshly allocated memory containing * height * rowstride bytes in the pixel format specified by @pixel_format * will be stored at this address. It must be freed using g_free() when you're * done with it. * * Monochrome glyphs (the only kind currently supported) will be rendered as * opaque white on a transparent black background (0xffffffff for inked * pixels and 0x00000000 for uninked). * * Since: 1.12 **/ gboolean chafa_symbol_map_get_glyph (ChafaSymbolMap *symbol_map, gunichar code_point, ChafaPixelType pixel_format, gpointer *pixels_out, gint *width_out, gint *height_out, gint *rowstride_out) { gboolean success = FALSE; gint width, height, rowstride; g_return_val_if_fail (symbol_map != NULL, FALSE); if (g_unichar_iswide (code_point)) { Glyph2 *glyph2; glyph2 = g_hash_table_lookup (symbol_map->glyphs2, GUINT_TO_POINTER (code_point)); if (!glyph2) goto out; g_assert (glyph2->c == code_point); if (pixels_out) *pixels_out = bitmap2_to_argb_alloc (glyph2->bitmap [0], glyph2->bitmap [1]); width = CHAFA_SYMBOL_WIDTH_PIXELS * 2; height = CHAFA_SYMBOL_HEIGHT_PIXELS; rowstride = CHAFA_SYMBOL_WIDTH_PIXELS * 2 * 4; } else { Glyph *glyph; glyph = g_hash_table_lookup (symbol_map->glyphs, GUINT_TO_POINTER (code_point)); if (!glyph) goto out; g_assert (glyph->c == code_point); if (pixels_out) *pixels_out = bitmap_to_argb_alloc (glyph->bitmap); width = CHAFA_SYMBOL_WIDTH_PIXELS; height = CHAFA_SYMBOL_HEIGHT_PIXELS; rowstride = CHAFA_SYMBOL_WIDTH_PIXELS * 4; } if (width_out) *width_out = width; if (height_out) *height_out = height; if (rowstride_out) *rowstride_out = rowstride; if (pixels_out && pixel_format != CHAFA_PIXEL_ARGB8_PREMULTIPLIED) { gpointer temp_pixels = g_malloc (width * CHAFA_SYMBOL_HEIGHT_PIXELS * 4); /* Convert to desired pixel format */ smol_scale_simple (*pixels_out, SMOL_PIXEL_ARGB8_UNASSOCIATED, /* FIXME: Premul */ width, height, rowstride, temp_pixels, (SmolPixelType) pixel_format, width, height, rowstride, SMOL_NO_FLAGS); g_free (*pixels_out); *pixels_out = temp_pixels; } success = TRUE; out: return success; } chafa-1.18.2/chafa/chafa-symbol-map.h000066400000000000000000000117171517447374300172260ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_SYMBOL_MAP_H__ #define __CHAFA_SYMBOL_MAP_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS #define CHAFA_SYMBOL_WIDTH_PIXELS 8 #define CHAFA_SYMBOL_HEIGHT_PIXELS 8 typedef enum { CHAFA_SYMBOL_TAG_NONE = 0, CHAFA_SYMBOL_TAG_SPACE = (1 << 0), CHAFA_SYMBOL_TAG_SOLID = (1 << 1), CHAFA_SYMBOL_TAG_STIPPLE = (1 << 2), CHAFA_SYMBOL_TAG_BLOCK = (1 << 3), CHAFA_SYMBOL_TAG_BORDER = (1 << 4), CHAFA_SYMBOL_TAG_DIAGONAL = (1 << 5), CHAFA_SYMBOL_TAG_DOT = (1 << 6), CHAFA_SYMBOL_TAG_QUAD = (1 << 7), CHAFA_SYMBOL_TAG_HHALF = (1 << 8), CHAFA_SYMBOL_TAG_VHALF = (1 << 9), CHAFA_SYMBOL_TAG_HALF = ((CHAFA_SYMBOL_TAG_HHALF) | (CHAFA_SYMBOL_TAG_VHALF)), CHAFA_SYMBOL_TAG_INVERTED = (1 << 10), CHAFA_SYMBOL_TAG_BRAILLE = (1 << 11), CHAFA_SYMBOL_TAG_TECHNICAL = (1 << 12), CHAFA_SYMBOL_TAG_GEOMETRIC = (1 << 13), CHAFA_SYMBOL_TAG_ASCII = (1 << 14), CHAFA_SYMBOL_TAG_ALPHA = (1 << 15), CHAFA_SYMBOL_TAG_DIGIT = (1 << 16), CHAFA_SYMBOL_TAG_ALNUM = CHAFA_SYMBOL_TAG_ALPHA | CHAFA_SYMBOL_TAG_DIGIT, CHAFA_SYMBOL_TAG_NARROW = (1 << 17), CHAFA_SYMBOL_TAG_WIDE = (1 << 18), CHAFA_SYMBOL_TAG_AMBIGUOUS = (1 << 19), CHAFA_SYMBOL_TAG_UGLY = (1 << 20), CHAFA_SYMBOL_TAG_LEGACY = (1 << 21), CHAFA_SYMBOL_TAG_SEXTANT = (1 << 22), CHAFA_SYMBOL_TAG_WEDGE = (1 << 23), CHAFA_SYMBOL_TAG_LATIN = (1 << 24), CHAFA_SYMBOL_TAG_IMPORTED = (1 << 25), CHAFA_SYMBOL_TAG_OCTANT = (1 << 26), CHAFA_SYMBOL_TAG_EXTRA = (1 << 30), CHAFA_SYMBOL_TAG_BAD = CHAFA_SYMBOL_TAG_AMBIGUOUS | CHAFA_SYMBOL_TAG_UGLY, CHAFA_SYMBOL_TAG_ALL = ~(CHAFA_SYMBOL_TAG_EXTRA | CHAFA_SYMBOL_TAG_BAD) } ChafaSymbolTags; typedef struct ChafaSymbolMap ChafaSymbolMap; CHAFA_AVAILABLE_IN_ALL ChafaSymbolMap *chafa_symbol_map_new (void); CHAFA_AVAILABLE_IN_ALL ChafaSymbolMap *chafa_symbol_map_copy (const ChafaSymbolMap *symbol_map); CHAFA_AVAILABLE_IN_ALL void chafa_symbol_map_ref (ChafaSymbolMap *symbol_map); CHAFA_AVAILABLE_IN_ALL void chafa_symbol_map_unref (ChafaSymbolMap *symbol_map); /* --- Selectors --- */ CHAFA_AVAILABLE_IN_ALL void chafa_symbol_map_add_by_tags (ChafaSymbolMap *symbol_map, ChafaSymbolTags tags); CHAFA_AVAILABLE_IN_ALL void chafa_symbol_map_remove_by_tags (ChafaSymbolMap *symbol_map, ChafaSymbolTags tags); CHAFA_AVAILABLE_IN_1_4 void chafa_symbol_map_add_by_range (ChafaSymbolMap *symbol_map, gunichar first, gunichar last); CHAFA_AVAILABLE_IN_1_4 void chafa_symbol_map_remove_by_range (ChafaSymbolMap *symbol_map, gunichar first, gunichar last); CHAFA_AVAILABLE_IN_ALL gboolean chafa_symbol_map_apply_selectors (ChafaSymbolMap *symbol_map, const gchar *selectors, GError **error); /* --- Glyphs --- */ CHAFA_AVAILABLE_IN_1_4 gboolean chafa_symbol_map_get_allow_builtin_glyphs (ChafaSymbolMap *symbol_map); CHAFA_AVAILABLE_IN_1_4 void chafa_symbol_map_set_allow_builtin_glyphs (ChafaSymbolMap *symbol_map, gboolean use_builtin_glyphs); CHAFA_AVAILABLE_IN_1_4 void chafa_symbol_map_add_glyph (ChafaSymbolMap *symbol_map, gunichar code_point, ChafaPixelType pixel_format, gpointer pixels, gint width, gint height, gint rowstride); CHAFA_AVAILABLE_IN_1_12 gboolean chafa_symbol_map_get_glyph (ChafaSymbolMap *symbol_map, gunichar code_point, ChafaPixelType pixel_format, gpointer *pixels_out, gint *width_out, gint *height_out, gint *rowstride_out); G_END_DECLS #endif /* __CHAFA_SYMBOL_MAP_H__ */ chafa-1.18.2/chafa/chafa-term-db.c000066400000000000000000001313511517447374300164700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include /* strtoul */ #include /* strlen, strncmp, strcmp, memcpy */ /** * SECTION:chafa-term-db * @title: ChafaTermDb * @short_description: A database of terminal information * * A #ChafaTermDb contains information on terminals, and can be used to obtain * a suitable #ChafaTermInfo for a terminal environment. **/ struct ChafaTermDb { gint refs; }; /* ------- * * Helpers * * ------- */ static gint strcmp_wrap (const gchar *a, const gchar *b) { if (a == NULL && b == NULL) return 0; if (a == NULL) return 1; if (b == NULL) return -1; return strcmp (a, b); } /* ------------------------------ * * Definitions for terminal table * * ------------------------------ */ /* Sequence inheritance * -------------------- * * For inherited seqs: * * - If either inner or outer sequence is NULL, use outer sequence. * - Otherwise, use inner sequence. * The last rule is a special case that allows for using the inner term's * sequences while clearing them if the outer term does not support the * sequence at all. This is useful for muxers (e.g. fbterm supports 256 colors, * but with private seqs; we want to use the inner mux' corresponding seqs). * * For sequences not listed as inheritable: * * - Always pick the inner sequence. */ /* These make the table more readable */ #define VARIANT_NONE NULL #define VERSION_NONE NULL #define INHERIT_NONE NULL #define PIXEL_PT_NONE NULL #define QUIRKS_NONE 0 /* Common symbol capabilities */ #define LINUX_CONSOLE_SYMS (CHAFA_SYMBOL_TAG_ASCII) #define LINUX_DESKTOP_SYMS (CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_BORDER) #define WIN_TERMINAL_SYMS (CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_BORDER) typedef enum { TERM_TYPE_TERM, TERM_TYPE_MUX, TERM_TYPE_APP, TERM_TYPE_MAX } TermType; typedef enum { ENV_OP_INCL, /* Include if true */ ENV_OP_EXCL /* Exclude if not true */ } EnvOp; typedef enum { ENV_CMP_ISSET, ENV_CMP_EXACT, ENV_CMP_PREFIX, ENV_CMP_SUFFIX, ENV_CMP_VER_GE } EnvCmp; typedef struct { EnvOp op; EnvCmp cmp; const gchar *key; const gchar *value; gint priority; } EnvRule; typedef struct { ChafaTermSeq seq; const gchar *str; } SeqStr; typedef struct { ChafaPixelMode pixel_mode; gboolean need_passthrough; } PixelModePassthrough; #define ENV_RULE_MAX 8 #define SEQ_LIST_MAX 12 typedef struct { TermType type; const gchar *name; const gchar *variant; const gchar *version; const EnvRule env_rules [ENV_RULE_MAX]; const SeqStr *seqs [SEQ_LIST_MAX]; const ChafaTermSeq *inherit_seqs; ChafaPassthrough passthrough; const PixelModePassthrough *pixel_pt; ChafaTermQuirks quirks; ChafaSymbolTags safe_symbol_tags; } TermDef; static const SeqStr vt100_seqs [] = { { CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT, "\033[!p" }, { CHAFA_TERM_SEQ_RESET_TERMINAL_HARD, "\033c" }, { CHAFA_TERM_SEQ_RESET_ATTRIBUTES, "\033[0m" }, { CHAFA_TERM_SEQ_CLEAR, "\033[2J" }, { CHAFA_TERM_SEQ_ENABLE_BOLD, "\033[1m" }, { CHAFA_TERM_SEQ_INVERT_COLORS, "\033[7m" }, { CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT, "\033[0H" }, { CHAFA_TERM_SEQ_CURSOR_TO_BOTTOM_LEFT, "\033[9999;1H" }, { CHAFA_TERM_SEQ_CURSOR_TO_POS, "\033[%2;%1H" }, { CHAFA_TERM_SEQ_CURSOR_UP, "\033[%1A" }, { CHAFA_TERM_SEQ_CURSOR_UP_1, "\033[A" }, { CHAFA_TERM_SEQ_CURSOR_DOWN, "\033[%1B" }, { CHAFA_TERM_SEQ_CURSOR_DOWN_1, "\033[B" }, { CHAFA_TERM_SEQ_CURSOR_LEFT, "\033[%1D" }, { CHAFA_TERM_SEQ_CURSOR_LEFT_1, "\033[D" }, { CHAFA_TERM_SEQ_CURSOR_RIGHT, "\033[%1C" }, { CHAFA_TERM_SEQ_CURSOR_RIGHT_1, "\033[C" }, { CHAFA_TERM_SEQ_CURSOR_UP_SCROLL, "\033M" }, { CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL, "\033D" }, { CHAFA_TERM_SEQ_INSERT_CELLS, "\033[%1@" }, { CHAFA_TERM_SEQ_DELETE_CELLS, "\033[%1P" }, { CHAFA_TERM_SEQ_INSERT_ROWS, "\033[%1L" }, { CHAFA_TERM_SEQ_DELETE_ROWS, "\033[%1M" }, { CHAFA_TERM_SEQ_SET_SCROLLING_ROWS, "\033[%1;%2r" }, { CHAFA_TERM_SEQ_ENABLE_INSERT, "\033[4h" }, { CHAFA_TERM_SEQ_DISABLE_INSERT,"\033[4l" }, { CHAFA_TERM_SEQ_ENABLE_CURSOR, "\033[?25h" }, { CHAFA_TERM_SEQ_DISABLE_CURSOR, "\033[?25l" }, { CHAFA_TERM_SEQ_ENABLE_ECHO, "\033[12l" }, { CHAFA_TERM_SEQ_DISABLE_ECHO, "\033[12h" }, { CHAFA_TERM_SEQ_ENABLE_WRAP, "\033[?7h" }, { CHAFA_TERM_SEQ_DISABLE_WRAP, "\033[?7l" }, { CHAFA_TERM_SEQ_RESET_SCROLLING_ROWS, "\033[r" }, { CHAFA_TERM_SEQ_SAVE_CURSOR_POS, "\033[s" }, { CHAFA_TERM_SEQ_RESTORE_CURSOR_POS, "\033[u" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr vt220_seqs [] = { { CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT, "\033[!p" }, { CHAFA_TERM_SEQ_RESET_TERMINAL_HARD, "\033c" }, { CHAFA_TERM_SEQ_RESET_ATTRIBUTES, "\033[0m" }, { CHAFA_TERM_SEQ_CLEAR, "\033[2J" }, { CHAFA_TERM_SEQ_ENABLE_BOLD, "\033[1m" }, { CHAFA_TERM_SEQ_INVERT_COLORS, "\033[7m" }, { CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT, "\033[0H" }, { CHAFA_TERM_SEQ_CURSOR_TO_BOTTOM_LEFT, "\033[9999;1H" }, { CHAFA_TERM_SEQ_CURSOR_TO_POS, "\033[%2;%1H" }, { CHAFA_TERM_SEQ_CURSOR_UP, "\033[%1A" }, { CHAFA_TERM_SEQ_CURSOR_UP_1, "\033[A" }, { CHAFA_TERM_SEQ_CURSOR_DOWN, "\033[%1B" }, { CHAFA_TERM_SEQ_CURSOR_DOWN_1, "\033[B" }, { CHAFA_TERM_SEQ_CURSOR_LEFT, "\033[%1D" }, { CHAFA_TERM_SEQ_CURSOR_LEFT_1, "\033[D" }, { CHAFA_TERM_SEQ_CURSOR_RIGHT, "\033[%1C" }, { CHAFA_TERM_SEQ_CURSOR_RIGHT_1, "\033[C" }, { CHAFA_TERM_SEQ_CURSOR_UP_SCROLL, "\033M" }, { CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL, "\033D" }, { CHAFA_TERM_SEQ_INSERT_CELLS, "\033[%1@" }, { CHAFA_TERM_SEQ_DELETE_CELLS, "\033[%1P" }, { CHAFA_TERM_SEQ_INSERT_ROWS, "\033[%1L" }, { CHAFA_TERM_SEQ_DELETE_ROWS, "\033[%1M" }, { CHAFA_TERM_SEQ_SET_SCROLLING_ROWS, "\033[%1;%2r" }, { CHAFA_TERM_SEQ_ENABLE_INSERT, "\033[4h" }, { CHAFA_TERM_SEQ_DISABLE_INSERT,"\033[4l" }, { CHAFA_TERM_SEQ_ENABLE_CURSOR, "\033[?25h" }, { CHAFA_TERM_SEQ_DISABLE_CURSOR, "\033[?25l" }, { CHAFA_TERM_SEQ_ENABLE_ECHO, "\033[12l" }, { CHAFA_TERM_SEQ_DISABLE_ECHO, "\033[12h" }, { CHAFA_TERM_SEQ_ENABLE_WRAP, "\033[?7h" }, { CHAFA_TERM_SEQ_DISABLE_WRAP, "\033[?7l" }, { CHAFA_TERM_SEQ_RESET_SCROLLING_ROWS, "\033[r" }, { CHAFA_TERM_SEQ_SAVE_CURSOR_POS, "\033[s" }, { CHAFA_TERM_SEQ_RESTORE_CURSOR_POS, "\033[u" }, /* These are actually xterm seqs, but we'll allow it */ { CHAFA_TERM_SEQ_ENABLE_ALT_SCREEN, "\033[1049h" }, { CHAFA_TERM_SEQ_DISABLE_ALT_SCREEN, "\033[1049l" }, { CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES, "\033[0c" }, { CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES, "\033[?%vc" }, { CHAFA_TERM_SEQ_RESET_DEFAULT_FG, "\033]110\033\\" }, { CHAFA_TERM_SEQ_SET_DEFAULT_FG, "\033]10;rgb:%1/%2/%3\033\\" }, { CHAFA_TERM_SEQ_QUERY_DEFAULT_FG, "\033]10;?\033\\" }, { CHAFA_TERM_SEQ_RESET_DEFAULT_BG, "\033]111\033\\" }, { CHAFA_TERM_SEQ_SET_DEFAULT_BG, "\033]11;rgb:%1/%2/%3\033\\" }, { CHAFA_TERM_SEQ_QUERY_DEFAULT_BG, "\033]11;?\033\\" }, /* XTWINOPS */ { CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_CELLS, "\033[18t" }, { CHAFA_TERM_SEQ_TEXT_AREA_SIZE_CELLS, "\033[8;%1;%2t" }, { CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_PX, "\033[14t" }, { CHAFA_TERM_SEQ_TEXT_AREA_SIZE_PX, "\033[4;%1;%2t" }, { CHAFA_TERM_SEQ_QUERY_CELL_SIZE_PX, "\033[16t" }, { CHAFA_TERM_SEQ_CELL_SIZE_PX, "\033[6;%1;%2t" }, /* OSC 8 hyperlinks */ { CHAFA_TERM_SEQ_BEGIN_HYPERLINK, "\033]8;;" }, { CHAFA_TERM_SEQ_BEGIN_HYPERLINK_ANCHOR, "\033\\" }, { CHAFA_TERM_SEQ_END_HYPERLINK, "\033]8;;\033\\" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr rep_seqs [] = { { CHAFA_TERM_SEQ_REPEAT_CHAR, "\033[%1b" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr sixel_seqs [] = { { CHAFA_TERM_SEQ_BEGIN_SIXELS, "\033P%1;%2;%3q" }, { CHAFA_TERM_SEQ_END_SIXELS, "\033\\" }, { CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING, "\033[?80l" }, { CHAFA_TERM_SEQ_DISABLE_SIXEL_SCROLLING, "\033[?80h" }, { CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN, "\033[?8452l" }, { CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_RIGHT, "\033[?8452h" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr default_key_seqs [] = { { CHAFA_TERM_SEQ_RETURN_KEY, "\x0d" }, /* ASCII CR */ { CHAFA_TERM_SEQ_BACKSPACE_KEY, "\x7f" }, /* ASCII DEL */ { CHAFA_TERM_SEQ_TAB_KEY, "\x09" }, /* ASCII HT */ { CHAFA_TERM_SEQ_TAB_SHIFT_KEY, "\033[Z" }, { CHAFA_TERM_SEQ_UP_KEY, "\033[A" }, { CHAFA_TERM_SEQ_UP_CTRL_KEY, "\033[1;5A" }, { CHAFA_TERM_SEQ_UP_SHIFT_KEY, "\033[1;2A" }, { CHAFA_TERM_SEQ_DOWN_KEY, "\033[B" }, { CHAFA_TERM_SEQ_DOWN_CTRL_KEY, "\033[1;5B" }, { CHAFA_TERM_SEQ_DOWN_SHIFT_KEY, "\033[1;2B" }, { CHAFA_TERM_SEQ_LEFT_KEY, "\033[D" }, { CHAFA_TERM_SEQ_LEFT_CTRL_KEY, "\033[1;5D" }, { CHAFA_TERM_SEQ_LEFT_SHIFT_KEY, "\033[1;2D" }, { CHAFA_TERM_SEQ_RIGHT_KEY, "\033[C" }, { CHAFA_TERM_SEQ_RIGHT_CTRL_KEY, "\033[1;5C" }, { CHAFA_TERM_SEQ_RIGHT_SHIFT_KEY, "\033[1;2C" }, { CHAFA_TERM_SEQ_PAGE_UP_KEY, "\033[5~" }, { CHAFA_TERM_SEQ_PAGE_UP_CTRL_KEY, "\033[5;5~" }, { CHAFA_TERM_SEQ_PAGE_UP_SHIFT_KEY, "\033[5;2~" }, { CHAFA_TERM_SEQ_PAGE_DOWN_KEY, "\033[6~" }, { CHAFA_TERM_SEQ_PAGE_DOWN_CTRL_KEY, "\033[6;5~" }, { CHAFA_TERM_SEQ_PAGE_DOWN_SHIFT_KEY, "\033[6;2~" }, { CHAFA_TERM_SEQ_HOME_KEY, "\033[H" }, { CHAFA_TERM_SEQ_HOME_CTRL_KEY, "\033[1;5H" }, { CHAFA_TERM_SEQ_HOME_SHIFT_KEY, "\033[1;2H" }, { CHAFA_TERM_SEQ_END_KEY, "\033[F" }, { CHAFA_TERM_SEQ_END_CTRL_KEY, "\033[1;5F" }, { CHAFA_TERM_SEQ_END_SHIFT_KEY, "\033[1;2F" }, { CHAFA_TERM_SEQ_INSERT_KEY, "\033[2~" }, { CHAFA_TERM_SEQ_INSERT_CTRL_KEY, "\033[2;5~" }, { CHAFA_TERM_SEQ_INSERT_SHIFT_KEY, "\033[2;2~" }, { CHAFA_TERM_SEQ_DELETE_KEY, "\033[3~" }, { CHAFA_TERM_SEQ_DELETE_CTRL_KEY, "\033[3;5~" }, { CHAFA_TERM_SEQ_DELETE_SHIFT_KEY, "\033[3;2~" }, { CHAFA_TERM_SEQ_F1_KEY, "\033OP" }, { CHAFA_TERM_SEQ_F1_CTRL_KEY, "\033[1;5P" }, { CHAFA_TERM_SEQ_F1_SHIFT_KEY, "\033[1;2P" }, { CHAFA_TERM_SEQ_F2_KEY, "\033OQ" }, { CHAFA_TERM_SEQ_F2_CTRL_KEY, "\033[1;5Q" }, { CHAFA_TERM_SEQ_F2_SHIFT_KEY, "\033[1;2Q" }, { CHAFA_TERM_SEQ_F3_KEY, "\033R" }, { CHAFA_TERM_SEQ_F3_CTRL_KEY, "\033[1;5R" }, { CHAFA_TERM_SEQ_F3_SHIFT_KEY, "\033[1;2R" }, { CHAFA_TERM_SEQ_F4_KEY, "\033OS" }, { CHAFA_TERM_SEQ_F4_CTRL_KEY, "\033[1;5S" }, { CHAFA_TERM_SEQ_F4_SHIFT_KEY, "\033[1;2S" }, { CHAFA_TERM_SEQ_F5_KEY, "\033[15~" }, { CHAFA_TERM_SEQ_F5_CTRL_KEY, "\033[15;5~" }, { CHAFA_TERM_SEQ_F5_SHIFT_KEY, "\033[15;2~" }, { CHAFA_TERM_SEQ_F6_KEY, "\033[17~" }, { CHAFA_TERM_SEQ_F6_CTRL_KEY, "\033[17;5~" }, { CHAFA_TERM_SEQ_F6_SHIFT_KEY, "\033[17;2~" }, { CHAFA_TERM_SEQ_F7_KEY, "\033[18~" }, { CHAFA_TERM_SEQ_F7_CTRL_KEY, "\033[18;5~" }, { CHAFA_TERM_SEQ_F7_SHIFT_KEY, "\033[18;2~" }, { CHAFA_TERM_SEQ_F8_KEY, "\033[19~" }, { CHAFA_TERM_SEQ_F8_CTRL_KEY, "\033[19;5~" }, { CHAFA_TERM_SEQ_F8_SHIFT_KEY, "\033[19;2~" }, { CHAFA_TERM_SEQ_F9_KEY, "\033[20~" }, { CHAFA_TERM_SEQ_F9_CTRL_KEY, "\033[20;5~" }, { CHAFA_TERM_SEQ_F9_SHIFT_KEY, "\033[20;2~" }, { CHAFA_TERM_SEQ_F10_KEY, "\033[21~" }, { CHAFA_TERM_SEQ_F10_CTRL_KEY, "\033[21;5~" }, { CHAFA_TERM_SEQ_F10_SHIFT_KEY, "\033[21;2~" }, { CHAFA_TERM_SEQ_F11_KEY, "\033[23~" }, { CHAFA_TERM_SEQ_F11_CTRL_KEY, "\033[23;5~" }, { CHAFA_TERM_SEQ_F11_SHIFT_KEY, "\033[23;2~" }, { CHAFA_TERM_SEQ_F12_KEY, "\033[24~" }, { CHAFA_TERM_SEQ_F12_CTRL_KEY, "\033[24;5~" }, { CHAFA_TERM_SEQ_F12_SHIFT_KEY, "\033[24;2~" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr color_direct_seqs [] = { /* ISO 8613-6 */ { CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT, "\033[38;2;%1;%2;%3m" }, { CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT, "\033[48;2;%1;%2;%3m" }, { CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT, "\033[38;2;%1;%2;%3;48;2;%4;%5;%6m" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr color_256_seqs [] = { { CHAFA_TERM_SEQ_SET_COLOR_FG_256, "\033[38;5;%1m" }, { CHAFA_TERM_SEQ_SET_COLOR_BG_256, "\033[48;5;%1m" }, { CHAFA_TERM_SEQ_SET_COLOR_FGBG_256, "\033[38;5;%1;48;5;%2m" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr color_16_seqs [] = { { CHAFA_TERM_SEQ_SET_COLOR_FG_16, "\033[%1m" }, { CHAFA_TERM_SEQ_SET_COLOR_BG_16, "\033[%1m" }, { CHAFA_TERM_SEQ_SET_COLOR_FGBG_16, "\033[%1;%2m" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr color_8_seqs [] = { { CHAFA_TERM_SEQ_SET_COLOR_FG_8, "\033[%1m" }, { CHAFA_TERM_SEQ_SET_COLOR_BG_8, "\033[%1m" }, { CHAFA_TERM_SEQ_SET_COLOR_FGBG_8, "\033[%1;%2m" }, /* ECMA-48 3rd ed. March 1984 */ { CHAFA_TERM_SEQ_RESET_COLOR_FG, "\033[39m" }, { CHAFA_TERM_SEQ_RESET_COLOR_BG, "\033[49m" }, { CHAFA_TERM_SEQ_RESET_COLOR_FGBG, "\033[39;49m" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr color_fbterm_seqs [] = { { CHAFA_TERM_SEQ_SET_COLOR_FG_16, "\033[1;%1}" }, { CHAFA_TERM_SEQ_SET_COLOR_BG_16, "\033[2;%1}" }, { CHAFA_TERM_SEQ_SET_COLOR_FGBG_16, "\033[1;%1}\033[2;%2}" }, { CHAFA_TERM_SEQ_SET_COLOR_FG_256, "\033[1;%1}" }, { CHAFA_TERM_SEQ_SET_COLOR_BG_256, "\033[2;%1}" }, { CHAFA_TERM_SEQ_SET_COLOR_FGBG_256, "\033[1;%1}\033[2;%2}" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr kitty_seqs [] = { { CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1, "\033_Ga=T,f=%1,s=%2,v=%3,c=%4,r=%5,m=1,q=2\033\\" }, { CHAFA_TERM_SEQ_END_KITTY_IMAGE, "\033_Gm=0\033\\" }, { CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK, "\033_Gm=1;" }, { CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK, "\033\\" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr kitty_virt_seqs [] = { { CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1, "\033_Ga=T,U=1,q=2,f=%1,s=%2,v=%3,c=%4,r=%5,i=%6,m=1\033\\" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr iterm2_seqs [] = { { CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE, "\033]1337;File=inline=1;width=%1;height=%2;preserveAspectRatio=0:" }, { CHAFA_TERM_SEQ_END_ITERM2_IMAGE, "\a" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const SeqStr tmux_seqs [] = { { CHAFA_TERM_SEQ_BEGIN_TMUX_PASSTHROUGH, "\033Ptmux;" }, { CHAFA_TERM_SEQ_END_TMUX_PASSTHROUGH, "\033\\" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const ChafaTermSeq tmux_inherit_seqs [] = { CHAFA_TERM_SEQ_BEGIN_SIXELS, CHAFA_TERM_SEQ_END_SIXELS, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1, CHAFA_TERM_SEQ_END_KITTY_IMAGE, CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK, CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK, CHAFA_TERM_SEQ_MAX }; static const PixelModePassthrough tmux_pixel_pt [] = { { CHAFA_PIXEL_MODE_SIXELS, TRUE }, { CHAFA_PIXEL_MODE_KITTY, TRUE }, { CHAFA_PIXEL_MODE_ITERM2, TRUE }, { CHAFA_PIXEL_MODE_MAX, FALSE } }; static const PixelModePassthrough tmux_3_4_pixel_pt [] = { { CHAFA_PIXEL_MODE_SIXELS, FALSE }, { CHAFA_PIXEL_MODE_KITTY, TRUE }, { CHAFA_PIXEL_MODE_ITERM2, TRUE }, { CHAFA_PIXEL_MODE_MAX, FALSE } }; static const SeqStr screen_seqs [] = { { CHAFA_TERM_SEQ_BEGIN_SCREEN_PASSTHROUGH, "\033P" }, { CHAFA_TERM_SEQ_END_SCREEN_PASSTHROUGH, "\033\\" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const ChafaTermSeq screen_inherit_seqs [] = { CHAFA_TERM_SEQ_BEGIN_SIXELS, CHAFA_TERM_SEQ_END_SIXELS, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1, CHAFA_TERM_SEQ_END_KITTY_IMAGE, CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK, CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK, CHAFA_TERM_SEQ_MAX }; static const PixelModePassthrough screen_pixel_pt [] = { { CHAFA_PIXEL_MODE_SIXELS, TRUE }, { CHAFA_PIXEL_MODE_KITTY, TRUE }, { CHAFA_PIXEL_MODE_ITERM2, TRUE }, { CHAFA_PIXEL_MODE_MAX, CHAFA_PASSTHROUGH_MAX } }; static const SeqStr lf_seqs [] = { { CHAFA_TERM_SEQ_ENABLE_BOLD, "\033[1m" }, { CHAFA_TERM_SEQ_INVERT_COLORS, "\033[7m" }, { CHAFA_TERM_SEQ_MAX, NULL } }; static const ChafaTermSeq lf_inherit_seqs [] = { CHAFA_TERM_SEQ_RESET_ATTRIBUTES, CHAFA_TERM_SEQ_ENABLE_BOLD, CHAFA_TERM_SEQ_INVERT_COLORS, CHAFA_TERM_SEQ_RESET_DEFAULT_FG, CHAFA_TERM_SEQ_SET_DEFAULT_FG, CHAFA_TERM_SEQ_RESET_DEFAULT_BG, CHAFA_TERM_SEQ_SET_DEFAULT_BG, CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT, CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT, CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT, CHAFA_TERM_SEQ_SET_COLOR_FG_256, CHAFA_TERM_SEQ_SET_COLOR_BG_256, CHAFA_TERM_SEQ_SET_COLOR_FGBG_256, CHAFA_TERM_SEQ_SET_COLOR_FG_16, CHAFA_TERM_SEQ_SET_COLOR_BG_16, CHAFA_TERM_SEQ_SET_COLOR_FGBG_16, CHAFA_TERM_SEQ_SET_COLOR_FG_8, CHAFA_TERM_SEQ_SET_COLOR_BG_8, CHAFA_TERM_SEQ_SET_COLOR_FGBG_8, CHAFA_TERM_SEQ_RESET_COLOR_FG, CHAFA_TERM_SEQ_RESET_COLOR_BG, CHAFA_TERM_SEQ_RESET_COLOR_FGBG, CHAFA_TERM_SEQ_BEGIN_SIXELS, CHAFA_TERM_SEQ_END_SIXELS, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1, CHAFA_TERM_SEQ_END_KITTY_IMAGE, CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK, CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK, CHAFA_TERM_SEQ_MAX }; static const SeqStr *fallback_list [] = { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs, kitty_seqs, kitty_virt_seqs, iterm2_seqs, screen_seqs, tmux_seqs, NULL }; static const TermDef term_def [] = { /* Mainline alacritty doesn't support sixels, but there's a patch for it: * https://github.com/alacritty/alacritty/pull/4763 * It can only be detected interactively. It has the overshoot quirk. */ { TERM_TYPE_TERM, "alacritty", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "alacritty", 10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "apple", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "Apple_Terminal", 0 } }, { vt220_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "contour", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERMINAL_NAME", "contour", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "ctx", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "CTX_BACKEND", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, rep_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "eat", "truecolor", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "eat-truecolor", 10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "eat", "256color", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "eat-256color", 10 } }, { vt220_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "eat", "16color", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "eat-16color", 10 } }, { vt220_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "eat", "color", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "eat-color", 10 } }, { vt220_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "eat", "mono", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "eat-mono", 10 } }, { vt220_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "eat", "truecolor", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "EAT_SHELL_INTEGRATION_DIR", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* FbTerm can use 256 colors through a private extension; see fbterm(1) */ { TERM_TYPE_TERM, "fbterm", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "fbterm", 10 } }, { vt220_seqs, color_fbterm_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "foot", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "foot", 10 }, { ENV_OP_INCL, ENV_CMP_PREFIX, "TERM", "foot-", 10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "ghostty", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-ghostty", 10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "ghostty", 0 }, { ENV_OP_INCL, ENV_CMP_ISSET, "GHOSTTY_BIN_DIR", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, kitty_seqs, kitty_virt_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* GNU/Hurd console */ { TERM_TYPE_TERM, "hurd", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "hurd", 10 } }, { vt100_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_CONSOLE_SYMS }, { TERM_TYPE_TERM, "iterm", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "LC_TERMINAL", "iTerm2", 0 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "iTerm.app", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, iterm2_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "kitty", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-kitty", 10 }, { ENV_OP_INCL, ENV_CMP_ISSET, "KITTY_PID", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, kitty_seqs, kitty_virt_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "konsole", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "KONSOLE_VERSION", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "konsole", VARIANT_NONE, "220370", { { ENV_OP_INCL, ENV_CMP_ISSET, "KONSOLE_VERSION", NULL, 0 }, { ENV_OP_EXCL, ENV_CMP_VER_GE, "KONSOLE_VERSION", "220370", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, LINUX_DESKTOP_SYMS }, /* The 'lf' file browser will choke if there are extra sequences in front * of a sixel image, so we need to be polite to it. */ { TERM_TYPE_APP, "lf", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "LF_LEVEL", NULL, 0 } }, { lf_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, lf_inherit_seqs, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* If TERM is "linux", we're probably on the Linux console, which supports * 16 colors only. It also sets COLORTERM=1. * * https://github.com/torvalds/linux/commit/cec5b2a97a11ade56a701e83044d0a2a984c67b4 * * In theory we could emit directcolor codes and let the console remap, * but we get better results if we do the conversion ourselves, since we * can apply preprocessing and exotic color spaces. */ { TERM_TYPE_TERM, "linux", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "linux", 10 } }, { vt220_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_CONSOLE_SYMS }, { TERM_TYPE_TERM, "mintty", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "mintty", 10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "mintty", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, iterm2_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, WIN_TERMINAL_SYMS }, /* mlterm's truecolor support seems to be broken; it looks like a color * allocation issue. This affects character cells, but not sixels. */ { TERM_TYPE_TERM, "mlterm", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "mlterm", 10 }, { ENV_OP_INCL, ENV_CMP_ISSET, "MLTERM", NULL, 0 } }, { vt220_seqs, color_256_seqs, color_16_seqs, color_8_seqs, iterm2_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, LINUX_DESKTOP_SYMS }, { TERM_TYPE_APP, "neovim", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "NVIM", NULL, 0 } }, { vt220_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_APP, "neovim", "truecolor", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "COLORTERM", "truecolor", 0 }, { ENV_OP_INCL, ENV_CMP_EXACT, "NVIM_TUI_ENABLE_TRUE_COLOR", "1", 0 }, { ENV_OP_EXCL, ENV_CMP_ISSET, "NVIM", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "rio", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "rio", 10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "rio", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, iterm2_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, LINUX_DESKTOP_SYMS }, /* rxvtu seems to support directcolor, but the default 256-color palette * appears to be broken/unusual. */ { TERM_TYPE_TERM, "rxvt", "unicode", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "rxvt-unicode", 10 } }, { vt220_seqs, color_direct_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "rxvt", "unicode-256color", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "rxvt-unicode-256color", 10 } }, { vt220_seqs, color_direct_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* 'screen' does not like directcolor at all, but 256 colors works fine. * Sometimes we'll see the outer terminal appended to the TERM string, * like so: screen.xterm-256color */ { TERM_TYPE_MUX, "screen", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_PREFIX, "TERM", "screen", -5 } }, { vt220_seqs, color_256_seqs, color_16_seqs, color_8_seqs, screen_seqs }, screen_inherit_seqs, CHAFA_PASSTHROUGH_SCREEN, screen_pixel_pt, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "st", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "st-256color", 10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* 'tmux' sets TERM=screen or =screen-256color, but it supports directcolor * codes. You may have to add the following to .tmux.conf to prevent * remapping to 256 colors: * * tmux set-option -ga terminal-overrides ",screen-256color:Tc" * * tmux 3.4+ supports sixels natively. */ { TERM_TYPE_MUX, "tmux", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "TMUX", NULL, 0 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "tmux", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, tmux_seqs }, tmux_inherit_seqs, CHAFA_PASSTHROUGH_TMUX, tmux_pixel_pt, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, LINUX_DESKTOP_SYMS }, { TERM_TYPE_MUX, "tmux", VARIANT_NONE, "3.4", { { ENV_OP_INCL, ENV_CMP_ISSET, "TMUX", NULL, 0 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "tmux", 0 }, { ENV_OP_EXCL, ENV_CMP_VER_GE, "TERM_PROGRAM_VERSION", "3.4", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, tmux_seqs }, tmux_inherit_seqs, CHAFA_PASSTHROUGH_TMUX, tmux_3_4_pixel_pt, CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT, LINUX_DESKTOP_SYMS }, /* Fallback when TERM is set but unrecognized */ { TERM_TYPE_TERM, "vt220", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "TERM", NULL, -1000 } }, { vt220_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, CHAFA_SYMBOL_TAG_ASCII }, { TERM_TYPE_TERM, "vte", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "VTE_VERSION", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "vte", VARIANT_NONE, "5202", { { ENV_OP_INCL, ENV_CMP_ISSET, "VTE_VERSION", NULL, 0 }, { ENV_OP_EXCL, ENV_CMP_VER_GE, "VTE_VERSION", "5202", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, rep_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "warp", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "WarpTerminal", 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, kitty_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, WIN_TERMINAL_SYMS }, /* Note: WezTerm does not support Kitty virtual image placements yet. * See https://github.com/wez/wezterm/issues/986 */ { TERM_TYPE_TERM, "wezterm", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM_PROGRAM", "WezTerm", 0 }, { ENV_OP_INCL, ENV_CMP_ISSET, "WEZTERM_EXECUTABLE", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs, iterm2_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* The MS Windows 10 TH2 (v1511+) console supports ANSI escape codes, * including AIX and DirectColor sequences. */ { TERM_TYPE_TERM, "windows-console", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_SUFFIX, "ComSpec", "\\cmd.exe", -5 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, WIN_TERMINAL_SYMS }, { TERM_TYPE_TERM, "xterm", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_ISSET, "XTERM_VERSION", NULL, 0 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* Terminals that advertise xterm-256color usually support truecolor too, * (VTE, xterm) although some (xterm) may quantize to an indexed palette * regardless. */ { TERM_TYPE_TERM, "xterm", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm", -10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* Terminals that advertise xterm-256color usually support truecolor too, * (VTE, xterm) although some (xterm) may quantize to an indexed palette * regardless. */ { TERM_TYPE_TERM, "xterm", "256color", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-256color", -10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { TERM_TYPE_TERM, "xterm", "direct", VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-direct", -10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-direct2", -10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-direct16", -10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "xterm-direct256", -10 } }, { vt220_seqs, color_direct_seqs, color_256_seqs, color_16_seqs, color_8_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, /* yaft supports sixels and directcolor escape codes, but it remaps cell * colors to a 256-color palette. */ { TERM_TYPE_TERM, "yaft", VARIANT_NONE, VERSION_NONE, { { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "yaft-256color", 10 }, { ENV_OP_INCL, ENV_CMP_EXACT, "TERM", "yaft", 10 } }, { vt220_seqs, color_256_seqs, color_16_seqs, color_8_seqs, sixel_seqs }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, LINUX_DESKTOP_SYMS }, { 0, NULL, VARIANT_NONE, VERSION_NONE, { { 0, 0, NULL, NULL, 0 } }, { NULL }, INHERIT_NONE, CHAFA_PASSTHROUGH_NONE, PIXEL_PT_NONE, QUIRKS_NONE, 0 } }; /* Parse various version formats into a single integer for comparisons. * E.g. "1.2.3", "20240912", "XTerm(388)". */ static gint64 parse_version (const gchar *version_str) { gint64 ver = 0; gint i; if (!version_str) return -1; for (i = 0; version_str [i] && ver < G_MAXINT64 / 10 + 9; i++) { gint n = version_str [i] - (gint) '0'; if (n < 0 || n > 9) continue; ver = ver * 10 + n; } return ver; } static void add_seqs (ChafaTermInfo *ti, const SeqStr *seqstr) { gint i; if (!seqstr) return; for (i = 0; seqstr [i].str; i++) { chafa_term_info_set_seq (ti, seqstr [i].seq, seqstr [i].str, NULL); } } static void add_seq_list (ChafaTermInfo *ti, const SeqStr **seqlist) { gint i; if (!seqlist) return; for (i = 0; seqlist [i]; i++) { add_seqs (ti, seqlist [i]); } } static gboolean match_env_rule (const EnvRule *r, const gchar *value) { gboolean m = FALSE; switch (r->cmp) { case ENV_CMP_ISSET: m = value != NULL; break; case ENV_CMP_EXACT: m = value != NULL && (!g_ascii_strcasecmp (value, r->value)); break; case ENV_CMP_PREFIX: m = value != NULL && (!g_ascii_strncasecmp (value, r->value, strlen (r->value))); break; case ENV_CMP_SUFFIX: m = value != NULL && strlen (r->value) <= strlen (value) && !g_ascii_strncasecmp (value + strlen (value) - strlen (r->value), r->value, strlen (r->value)); break; case ENV_CMP_VER_GE: m = value != NULL && parse_version (value) >= parse_version (r->value); break; } return m; } static gint match_term_def (const TermDef *td, gchar **envp) { gint best_pri = G_MININT; gint i; for (i = 0; i < ENV_RULE_MAX && td->env_rules [i].key; i++) { const EnvRule *r = &td->env_rules [i]; const gchar *value; gboolean m = FALSE; value = g_environ_getenv (envp, r->key); /* TERM can be a series of names separated by '.'. GNU Screen does this, * e.g. TERM=screen.xterm-256color */ if (value != NULL && !g_ascii_strcasecmp (r->key, "TERM")) { gchar **subterms = g_strsplit (value, ".", -1); gint j; for (j = 0; subterms && subterms [j]; j++) m |= match_env_rule (r, subterms [j]); g_strfreev (subterms); } m |= match_env_rule (r, value); if (r->op == ENV_OP_EXCL) { if (!m) { best_pri = G_MININT; break; } } else if (m && r->priority >= best_pri) { best_pri = r->priority; } else { m = FALSE; } } return best_pri; } /* Terminal identifiers have three parts: name, variant and version. * Either or both of variant and version can be omitted. If version is * present but variant isn't, variant is replaced with a "*" placeholder. * * Examples of syntactically valid identifiers: * * vte * vte-256color * mlterm-*-3.9.3 * xterm-256color-XTerm(389) */ static gchar * term_def_to_name (const TermDef *def) { const gchar *parts [3]; parts [0] = def->name ? def->name : "unknown"; parts [1] = def->variant ? def->variant : (def->version ? "*" : NULL); parts [2] = def->version; return g_strjoin ("-", parts [0], parts [1], parts [2], NULL); } static ChafaTermInfo * new_term_info_from_def (const TermDef *def) { const SeqStr * const *seqs = def->seqs; ChafaTermInfo *ti; gchar *name; gint i; name = term_def_to_name (def); ti = chafa_term_info_new (); chafa_term_info_set_name (ti, name); chafa_term_info_set_quirks (ti, def->quirks); chafa_term_info_set_safe_symbol_tags (ti, def->safe_symbol_tags); for (i = 0; i < SEQ_LIST_MAX && seqs [i]; i++) { add_seqs (ti, seqs [i]); } for (i = 0; def->pixel_pt && def->pixel_pt [i].pixel_mode < CHAFA_PIXEL_MODE_MAX; i++) { chafa_term_info_set_is_pixel_passthrough_needed (ti, def->pixel_pt [i].pixel_mode, def->pixel_pt [i].need_passthrough); } for (i = 0; def->inherit_seqs && def->inherit_seqs [i] < CHAFA_TERM_SEQ_MAX; i++) { chafa_term_info_set_inherit_seq (ti, def->inherit_seqs [i], TRUE); } g_free (name); return ti; } static ChafaTermInfo * detect_term_of_type (TermType term_type, gchar **envp) { ChafaTermInfo *ti = NULL; gint best_def_i = -1; gint best_pri = G_MININT + 1; gint i; for (i = 0; term_def [i].name; i++) { gint pri; if (term_def [i].type != term_type) continue; /* Pick higher-priority solutions. If the priority is equal, allow * more specific and higher-version entries of the same TE to take precedence. */ pri = match_term_def (&term_def [i], envp); if (pri > best_pri || (pri == best_pri && !strcmp_wrap (term_def [i].name, term_def [best_def_i].name) && ((term_def [i].variant && !term_def [best_def_i].variant) || (!strcmp_wrap (term_def [i].variant, term_def [best_def_i].variant) && parse_version (term_def [i].version) > parse_version (term_def [best_def_i].version))))) { best_pri = pri; best_def_i = i; } } if (best_def_i != -1) { ti = new_term_info_from_def (&term_def [best_def_i]); } return ti; } static ChafaTermInfo * detect_capabilities (gchar **envp) { ChafaTermInfo *ret_ti = NULL; gint i; for (i = 0; i < TERM_TYPE_MAX; i++) { ChafaTermInfo *ti = detect_term_of_type (i, envp); if (!ti) continue; if (ret_ti) { ChafaTermInfo *chained = chafa_term_info_chain (ret_ti, ti); chafa_term_info_unref (ret_ti); ret_ti = chained; } else { chafa_term_info_ref (ti); ret_ti = ti; } chafa_term_info_unref (ti); } if (!ret_ti) { /* Fallback for when we're completely clueless. Plain ASCII output * with no seqs at all. */ ret_ti = chafa_term_info_new (); chafa_term_info_set_name (ret_ti, "dumb"); chafa_term_info_set_safe_symbol_tags (ret_ti, CHAFA_SYMBOL_TAG_ASCII); } return ret_ti; } static ChafaTermDb * instantiate_singleton (G_GNUC_UNUSED gpointer data) { return chafa_term_db_new (); } /* Public */ /** * chafa_term_db_new: * * Creates a new, blank #ChafaTermDb. * * Returns: The new #ChafaTermDb * * Since: 1.6 **/ ChafaTermDb * chafa_term_db_new (void) { ChafaTermDb *term_db; term_db = g_new0 (ChafaTermDb, 1); term_db->refs = 1; return term_db; } /** * chafa_term_db_copy: * @term_db: A #ChafaTermDb to copy. * * Creates a new #ChafaTermDb that's a copy of @term_db. * * Returns: The new #ChafaTermDb * * Since: 1.6 **/ ChafaTermDb * chafa_term_db_copy (const ChafaTermDb *term_db) { ChafaTermDb *new_term_db; new_term_db = g_new (ChafaTermDb, 1); memcpy (new_term_db, term_db, sizeof (ChafaTermDb)); new_term_db->refs = 1; return new_term_db; } /** * chafa_term_db_ref: * @term_db: #ChafaTermDb to add a reference to. * * Adds a reference to @term_db. * * Since: 1.6 **/ void chafa_term_db_ref (ChafaTermDb *term_db) { gint refs; g_return_if_fail (term_db != NULL); refs = g_atomic_int_get (&term_db->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&term_db->refs); } /** * chafa_term_db_unref: * @term_db: #ChafaTermDb to remove a reference from. * * Removes a reference from @term_db. * * Since: 1.6 **/ void chafa_term_db_unref (ChafaTermDb *term_db) { gint refs; g_return_if_fail (term_db != NULL); refs = g_atomic_int_get (&term_db->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&term_db->refs)) { g_free (term_db); } } /** * chafa_term_db_get_default: * * Gets the global #ChafaTermDb. This can normally be used safely * in a read-only capacity. The caller should not unref the * returned object. * * Returns: The global #ChafaTermDb * * Since: 1.6 **/ ChafaTermDb * chafa_term_db_get_default (void) { static GOnce my_once = G_ONCE_INIT; g_once (&my_once, (GThreadFunc) instantiate_singleton, NULL); return my_once.retval; } /** * chafa_term_db_detect: * @term_db: A #ChafaTermDb. * @envp: A strv of environment variables. * * Builds a new #ChafaTermInfo with capabilities implied by the provided * environment variables (principally the TERM variable, but also others). * * @envp can be gotten from g_get_environ(). * * Returns: A new #ChafaTermInfo. * * Since: 1.6 **/ ChafaTermInfo * chafa_term_db_detect (ChafaTermDb *term_db, gchar **envp) { g_return_val_if_fail (term_db != NULL, NULL); return detect_capabilities (envp); } /** * chafa_term_db_get_fallback_info: * @term_db: A #ChafaTermDb. * * Builds a new #ChafaTermInfo with fallback control sequences. This * can be used with unknown but presumably modern terminals, or to * supplement missing capabilities in a detected terminal. * * Fallback control sequences may cause unpredictable behavior and * should only be used as a last resort. * * Returns: A new #ChafaTermInfo. * * Since: 1.6 **/ ChafaTermInfo * chafa_term_db_get_fallback_info (ChafaTermDb *term_db) { ChafaTermInfo *ti; g_return_val_if_fail (term_db != NULL, NULL); ti = chafa_term_info_new (); add_seq_list (ti, fallback_list); return ti; } chafa-1.18.2/chafa/chafa-term-db.h000066400000000000000000000032721517447374300164750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_TERM_DB_H__ #define __CHAFA_TERM_DB_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif #include G_BEGIN_DECLS typedef struct ChafaTermDb ChafaTermDb; CHAFA_AVAILABLE_IN_1_6 ChafaTermDb *chafa_term_db_new (void); CHAFA_AVAILABLE_IN_1_6 ChafaTermDb *chafa_term_db_copy (const ChafaTermDb *term_db); CHAFA_AVAILABLE_IN_1_6 void chafa_term_db_ref (ChafaTermDb *term_db); CHAFA_AVAILABLE_IN_1_6 void chafa_term_db_unref (ChafaTermDb *term_db); CHAFA_AVAILABLE_IN_1_6 ChafaTermDb *chafa_term_db_get_default (void); CHAFA_AVAILABLE_IN_1_6 ChafaTermInfo *chafa_term_db_detect (ChafaTermDb *term_db, gchar **envp); CHAFA_AVAILABLE_IN_1_6 ChafaTermInfo *chafa_term_db_get_fallback_info (ChafaTermDb *term_db); G_END_DECLS #endif /* __CHAFA_TERM_DB_H__ */ chafa-1.18.2/chafa/chafa-term-info.c000066400000000000000000001770051517447374300170440ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chafa.h" #include "internal/chafa-private.h" #include "internal/chafa-string-util.h" /** * SECTION:chafa-term-info * @title: ChafaTermInfo * @short_description: Describes a particular terminal type * * A #ChafaTermInfo describes the characteristics of one particular kind * of display terminal. It stores control sequences that can be used to * move the cursor, change text attributes, mark the beginning and end of * sixel graphics data, etc. * * #ChafaTermInfo also implements an efficient low-level API for formatting * these sequences with marshaled arguments so they can be sent to the * terminal. **/ /** * ChafaTermSeq: * @CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT: Reset the terminal to configured defaults. * @CHAFA_TERM_SEQ_RESET_TERMINAL_HARD: Reset the terminal to factory defaults. * @CHAFA_TERM_SEQ_RESET_ATTRIBUTES: Reset active graphics rendition (colors and other attributes) to terminal defaults. * @CHAFA_TERM_SEQ_CLEAR: Clear the screen. * @CHAFA_TERM_SEQ_INVERT_COLORS: Invert foreground and background colors (disable with RESET_ATTRIBUTES). * @CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT: Move cursor to top left of screen. * @CHAFA_TERM_SEQ_CURSOR_TO_BOTTOM_LEFT: Move cursor to bottom left of screen. * @CHAFA_TERM_SEQ_CURSOR_TO_POS: Move cursor to specific position. * @CHAFA_TERM_SEQ_CURSOR_UP_1: Move cursor up one cell. * @CHAFA_TERM_SEQ_CURSOR_UP: Move cursor up N cells. * @CHAFA_TERM_SEQ_CURSOR_DOWN_1: Move cursor down one cell. * @CHAFA_TERM_SEQ_CURSOR_DOWN: Move cursor down N cells. * @CHAFA_TERM_SEQ_CURSOR_LEFT_1: Move cursor left one cell. * @CHAFA_TERM_SEQ_CURSOR_LEFT: Move cursor left N cells. * @CHAFA_TERM_SEQ_CURSOR_RIGHT_1: Move cursor right one cell. * @CHAFA_TERM_SEQ_CURSOR_RIGHT: Move cursor right N cells. * @CHAFA_TERM_SEQ_CURSOR_UP_SCROLL: Move cursor up one cell. Scroll area contents down when at the edge. * @CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL: Move cursor down one cell. Scroll area contents up when at the edge. * @CHAFA_TERM_SEQ_INSERT_CELLS: Insert blank cells at cursor position. * @CHAFA_TERM_SEQ_DELETE_CELLS: Delete cells at cursor position. * @CHAFA_TERM_SEQ_INSERT_ROWS: Insert rows at cursor position. * @CHAFA_TERM_SEQ_DELETE_ROWS: Delete rows at cursor position. * @CHAFA_TERM_SEQ_SET_SCROLLING_ROWS: Set scrolling area extents. * @CHAFA_TERM_SEQ_ENABLE_INSERT: Enable insert mode. * @CHAFA_TERM_SEQ_DISABLE_INSERT: Disable insert mode. * @CHAFA_TERM_SEQ_ENABLE_CURSOR: Show the cursor. * @CHAFA_TERM_SEQ_DISABLE_CURSOR: Hide the cursor. * @CHAFA_TERM_SEQ_ENABLE_ECHO: Make the terminal echo input locally. * @CHAFA_TERM_SEQ_DISABLE_ECHO: Don't echo input locally. * @CHAFA_TERM_SEQ_ENABLE_WRAP: Make cursor wrap around to the next row after output in the final column. * @CHAFA_TERM_SEQ_DISABLE_WRAP: Make cursor stay in place after output to the final column. * @CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT: Set foreground color (directcolor/truecolor). * @CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT: Set background color (directcolor/truecolor). * @CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT: Set foreground and background color (directcolor/truecolor). * @CHAFA_TERM_SEQ_SET_COLOR_FG_256: Set foreground color (256 colors). * @CHAFA_TERM_SEQ_SET_COLOR_BG_256: Set background color (256 colors). * @CHAFA_TERM_SEQ_SET_COLOR_FGBG_256: Set foreground and background colors (256 colors). * @CHAFA_TERM_SEQ_SET_COLOR_FG_16: Set foreground color (16 colors). * @CHAFA_TERM_SEQ_SET_COLOR_BG_16: Set background color (16 colors). * @CHAFA_TERM_SEQ_SET_COLOR_FGBG_16: Set foreground and background colors (16 colors). * @CHAFA_TERM_SEQ_BEGIN_SIXELS: Begin sixel image data. * @CHAFA_TERM_SEQ_END_SIXELS: End sixel image data. * @CHAFA_TERM_SEQ_REPEAT_CHAR: Repeat previous character N times. * @CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1: Begin upload of Kitty image for immediate display at cursor. * @CHAFA_TERM_SEQ_END_KITTY_IMAGE: End of Kitty image upload. * @CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK: Begin Kitty image data chunk. * @CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK: End Kitty image data chunk. * @CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE: Begin iTerm2 image data. * @CHAFA_TERM_SEQ_END_ITERM2_IMAGE: End of iTerm2 image data. * @CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING: Enable sixel scrolling. * @CHAFA_TERM_SEQ_DISABLE_SIXEL_SCROLLING: Disable sixel scrolling. * @CHAFA_TERM_SEQ_ENABLE_BOLD: Enable boldface (disable with RESET_ATTRIBUTES). * @CHAFA_TERM_SEQ_SET_COLOR_FG_8: Set foreground color (8 colors). * @CHAFA_TERM_SEQ_SET_COLOR_BG_8: Set background color (8 colors). * @CHAFA_TERM_SEQ_SET_COLOR_FGBG_8: Set foreground and background colors (8 colors). * @CHAFA_TERM_SEQ_RESET_DEFAULT_FG: Reset the default FG color to the terminal's default. * @CHAFA_TERM_SEQ_SET_DEFAULT_FG: Set the default FG to a specific RGB color. * @CHAFA_TERM_SEQ_QUERY_DEFAULT_FG: Query the default FG color. * @CHAFA_TERM_SEQ_RESET_DEFAULT_BG: Reset the default BG color to the terminal's default. * @CHAFA_TERM_SEQ_SET_DEFAULT_BG: Set the default BG to a specific RGB color. * @CHAFA_TERM_SEQ_QUERY_DEFAULT_BG: Query the default BG color. * @CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES: Query the primary device attributes. * @CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES: Indicate the primary device attributes. * @CHAFA_TERM_SEQ_QUERY_CELL_SIZE_PX: Query the character cell size in pixels. * @CHAFA_TERM_SEQ_CELL_SIZE_PX: Indicate the character cell size in pixels. * @CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_CELLS: Query the text area size in character cells. * @CHAFA_TERM_SEQ_TEXT_AREA_SIZE_CELLS: Indicate the text area size in character cells. * @CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_PX: Query the text area size in pixels. * @CHAFA_TERM_SEQ_TEXT_AREA_SIZE_PX: Indicate the text area size in pixels. * @CHAFA_TERM_SEQ_RETURN_KEY: Return key. * @CHAFA_TERM_SEQ_BACKSPACE_KEY: Backspace key. * @CHAFA_TERM_SEQ_TAB_KEY: Tab key. * @CHAFA_TERM_SEQ_TAB_SHIFT_KEY: Shift + tab key. * @CHAFA_TERM_SEQ_UP_KEY: Up key. * @CHAFA_TERM_SEQ_UP_CTRL_KEY: Ctrl + up key. * @CHAFA_TERM_SEQ_UP_SHIFT_KEY: Shift + up key. * @CHAFA_TERM_SEQ_DOWN_KEY: Down key. * @CHAFA_TERM_SEQ_DOWN_CTRL_KEY: Ctrl + down key. * @CHAFA_TERM_SEQ_DOWN_SHIFT_KEY: Shift + down key. * @CHAFA_TERM_SEQ_LEFT_KEY: Left key. * @CHAFA_TERM_SEQ_LEFT_CTRL_KEY: Ctrl + left key. * @CHAFA_TERM_SEQ_LEFT_SHIFT_KEY: Shift + left key. * @CHAFA_TERM_SEQ_RIGHT_KEY: Right key. * @CHAFA_TERM_SEQ_RIGHT_CTRL_KEY: Ctrl + right key. * @CHAFA_TERM_SEQ_RIGHT_SHIFT_KEY: Shift + right key. * @CHAFA_TERM_SEQ_PAGE_UP_KEY: Page up key. * @CHAFA_TERM_SEQ_PAGE_UP_CTRL_KEY: Ctrl + page up key. * @CHAFA_TERM_SEQ_PAGE_UP_SHIFT_KEY: Shift + page up key. * @CHAFA_TERM_SEQ_PAGE_DOWN_KEY: Page down key. * @CHAFA_TERM_SEQ_PAGE_DOWN_CTRL_KEY: Ctrl + page down key. * @CHAFA_TERM_SEQ_PAGE_DOWN_SHIFT_KEY: Shift + page down key. * @CHAFA_TERM_SEQ_HOME_KEY: Home key. * @CHAFA_TERM_SEQ_HOME_CTRL_KEY: Ctrl + home key. * @CHAFA_TERM_SEQ_HOME_SHIFT_KEY: Shift + home key. * @CHAFA_TERM_SEQ_END_KEY: End key. * @CHAFA_TERM_SEQ_END_CTRL_KEY: Ctrl + end key. * @CHAFA_TERM_SEQ_END_SHIFT_KEY: Shift + end key. * @CHAFA_TERM_SEQ_INSERT_KEY: Insert key. * @CHAFA_TERM_SEQ_INSERT_CTRL_KEY: Ctrl + insert key. * @CHAFA_TERM_SEQ_INSERT_SHIFT_KEY: Shift + insert key. * @CHAFA_TERM_SEQ_DELETE_KEY: Delete key. * @CHAFA_TERM_SEQ_DELETE_CTRL_KEY: Ctrl + delete key. * @CHAFA_TERM_SEQ_DELETE_SHIFT_KEY: Shift + delete key. * @CHAFA_TERM_SEQ_F1_KEY: F1 key. * @CHAFA_TERM_SEQ_F1_CTRL_KEY: Ctrl + F1 key. * @CHAFA_TERM_SEQ_F1_SHIFT_KEY: Shift + F1 key. * @CHAFA_TERM_SEQ_F2_KEY: F2 key. * @CHAFA_TERM_SEQ_F2_CTRL_KEY: Ctrl + F2 key. * @CHAFA_TERM_SEQ_F2_SHIFT_KEY: Shift + F2 key. * @CHAFA_TERM_SEQ_F3_KEY: F3 key. * @CHAFA_TERM_SEQ_F3_CTRL_KEY: Ctrl + F3 key. * @CHAFA_TERM_SEQ_F3_SHIFT_KEY: Shift + F3 key. * @CHAFA_TERM_SEQ_F4_KEY: F4 key. * @CHAFA_TERM_SEQ_F4_CTRL_KEY: Ctrl + F4 key. * @CHAFA_TERM_SEQ_F4_SHIFT_KEY: Shift + F4 key. * @CHAFA_TERM_SEQ_F5_KEY: F5 key. * @CHAFA_TERM_SEQ_F5_CTRL_KEY: Ctrl + F5 key. * @CHAFA_TERM_SEQ_F5_SHIFT_KEY: Shift + F5 key. * @CHAFA_TERM_SEQ_F6_KEY: F6 key. * @CHAFA_TERM_SEQ_F6_CTRL_KEY: Ctrl + F6 key. * @CHAFA_TERM_SEQ_F6_SHIFT_KEY: Shift + F6 key. * @CHAFA_TERM_SEQ_F7_KEY: F7 key. * @CHAFA_TERM_SEQ_F7_CTRL_KEY: Ctrl + F7 key. * @CHAFA_TERM_SEQ_F7_SHIFT_KEY: Shift + F7 key. * @CHAFA_TERM_SEQ_F8_KEY: F8 key. * @CHAFA_TERM_SEQ_F8_CTRL_KEY: Ctrl + F8 key. * @CHAFA_TERM_SEQ_F8_SHIFT_KEY: Shift + F8 key. * @CHAFA_TERM_SEQ_F9_KEY: F9 key. * @CHAFA_TERM_SEQ_F9_CTRL_KEY: Ctrl + F9 key. * @CHAFA_TERM_SEQ_F9_SHIFT_KEY: Shift + F9 key. * @CHAFA_TERM_SEQ_F10_KEY: F10 key. * @CHAFA_TERM_SEQ_F10_CTRL_KEY: Ctrl + F10 key. * @CHAFA_TERM_SEQ_F10_SHIFT_KEY: Shift + F10 key. * @CHAFA_TERM_SEQ_F11_KEY: F11 key. * @CHAFA_TERM_SEQ_F11_CTRL_KEY: Ctrl + F11 key. * @CHAFA_TERM_SEQ_F11_SHIFT_KEY: Shift + F11 key. * @CHAFA_TERM_SEQ_F12_KEY: F12 key. * @CHAFA_TERM_SEQ_F12_CTRL_KEY: Ctrl + F12 key. * @CHAFA_TERM_SEQ_F12_SHIFT_KEY: Shift + F12 key. * @CHAFA_TERM_SEQ_RESET_COLOR_FG: Reset foreground color to the default. * @CHAFA_TERM_SEQ_RESET_COLOR_BG: Reset background color to the default. * @CHAFA_TERM_SEQ_RESET_COLOR_FGBG: Reset foreground and background colors to the default. * @CHAFA_TERM_SEQ_RESET_SCROLLING_ROWS: Reset scrolling area extent to that of the entire screen. * @CHAFA_TERM_SEQ_SAVE_CURSOR_POS: Save the cursor's position. * @CHAFA_TERM_SEQ_RESTORE_CURSOR_POS: Move cursor to the last saved position. * @CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN: After showing a sixel image, leave cursor somewhere on the row below the image. * @CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_RIGHT: After showing a sixel image, leave cursor to the right of the last row. * @CHAFA_TERM_SEQ_ENABLE_ALT_SCREEN: Switch to the alternate screen buffer. * @CHAFA_TERM_SEQ_DISABLE_ALT_SCREEN: Switch back to the regular screen buffer. * @CHAFA_TERM_SEQ_BEGIN_SCREEN_PASSTHROUGH: Begins OSC passthrough for the GNU Screen multiplexer. * @CHAFA_TERM_SEQ_END_SCREEN_PASSTHROUGH: Ends OSC passthrough for the GNU Screen multiplexer. * @CHAFA_TERM_SEQ_BEGIN_TMUX_PASSTHROUGH: Begins OSC passthrough for the tmux multiplexer. * @CHAFA_TERM_SEQ_END_TMUX_PASSTHROUGH: Ends OSC passthrough for the tmux multiplexer. * @CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1: Begin upload of virtual Kitty image for immediate display at cursor. * @CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES: Queries the terminal for its primary device attributes. * @CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES: The terminal's primary device attributes. * @CHAFA_TERM_SEQ_BEGIN_HYPERLINK: Begins an OSC 8-style hyperlink. The URL follows this. * @CHAFA_TERM_SEQ_BEGIN_HYPERLINK_ANCHOR: Separates an OSC 8-style hyperlink URL from its anchor (label). The label follows this. * @CHAFA_TERM_SEQ_END_HYPERLINK: Ends an OSC 8-style hyperlink. Closes both the preceding #CHAFA_TERM_SEQ_BEGIN_HYPERLINK and #CHAFA_TERM_SEQ_BEGIN_HYPERLINK_ANCHOR. * @CHAFA_TERM_SEQ_MAX: Last control sequence plus one. * * An enumeration of the control sequences supported by #ChafaTermInfo. **/ #define ARG_INDEX_SENTINEL 255 typedef struct { guint8 is_varargs : 1; guint8 pre_len : 7; guint8 arg_index; } SeqArgInfo; struct ChafaTermInfo { gint refs; gchar *name; gchar seq_str [CHAFA_TERM_SEQ_MAX] [CHAFA_TERM_SEQ_LENGTH_MAX]; SeqArgInfo seq_args [CHAFA_TERM_SEQ_MAX] [CHAFA_TERM_SEQ_ARGS_MAX]; gchar *unparsed_str [CHAFA_TERM_SEQ_MAX]; guint8 pixel_passthrough_needed [CHAFA_PIXEL_MODE_MAX]; guint8 inherit_seq [CHAFA_TERM_SEQ_MAX]; ChafaTermQuirks quirks; ChafaSymbolTags safe_symbol_tags; }; typedef enum { SEQ_TYPE_FIXARGS, SEQ_TYPE_VARARGS } SeqType; typedef struct { guint seq_type : 8; guint n_args : 8; guint type_size : 8; } SeqMeta; static const SeqMeta seq_meta [CHAFA_TERM_SEQ_MAX] = { #define CHAFA_TERM_SEQ_DEF(name, NAME, n_args, arg_proc, arg_type, args) \ [CHAFA_TERM_SEQ_##NAME] = { SEQ_TYPE_FIXARGS, n_args, sizeof (arg_type) }, #define CHAFA_TERM_SEQ_DEF_VARARGS(name, NAME, arg_type) \ [CHAFA_TERM_SEQ_##NAME] = { SEQ_TYPE_VARARGS, CHAFA_TERM_SEQ_ARGS_MAX - 1, sizeof (arg_type) }, #include #undef CHAFA_TERM_SEQ_DEF #undef CHAFA_TERM_SEQ_DEF_VARARGS }; /* Avoid memcpy() because it inlines to a sizeable amount of code (it * doesn't know our strings are always short). We also take the liberty * of unconditionally copying a byte even if n=0. This simplifies the * generated assembly quite a bit. */ static inline void copy_bytes (gchar *out, const gchar *in, gint n) { gint i = 0; do { *(out++) = *(in++); i++; } while (i < n); } #if 0 static void clear_seq (ChafaTermInfo *ti, gint seq) { g_free (ti->unparsed_str [seq]); ti->unparsed_str [seq] = NULL; memset (&ti->seq_str [seq] [0], 0, CHAFA_TERM_SEQ_LENGTH_MAX); memset (&ti->seq_args [seq] [0], 0, CHAFA_TERM_SEQ_ARGS_MAX * sizeof (SeqArgInfo)); } #endif static void copy_seq (const ChafaTermInfo *src, ChafaTermInfo *dest, gint seq) { g_free (dest->unparsed_str [seq]); dest->unparsed_str [seq] = NULL; if (src->unparsed_str [seq]) dest->unparsed_str [seq] = g_strdup (src->unparsed_str [seq]); memcpy (&dest->seq_str [seq] [0], &src->seq_str [seq] [0], CHAFA_TERM_SEQ_LENGTH_MAX); memcpy (&dest->seq_args [seq] [0], &src->seq_args [seq] [0], CHAFA_TERM_SEQ_ARGS_MAX * sizeof (SeqArgInfo)); dest->inherit_seq [seq] = src->inherit_seq [seq]; } static gboolean parse_seq_args (gchar *out, SeqArgInfo *arg_info, const gchar *in, gint n_args, gint arg_len_max, GError **error) { gint i, j, k; gint pre_len = 0; gint result = FALSE; g_assert (n_args < CHAFA_TERM_SEQ_ARGS_MAX); for (k = 0; k < CHAFA_TERM_SEQ_ARGS_MAX; k++) { arg_info [k].is_varargs = FALSE; arg_info [k].pre_len = 0; arg_info [k].arg_index = ARG_INDEX_SENTINEL; } for (i = 0, j = 0, k = 0; j < CHAFA_TERM_SEQ_LENGTH_MAX && k < CHAFA_TERM_SEQ_ARGS_MAX && in [i]; i++) { gchar c = in [i]; if (c == '%') { i++; c = in [i]; if (c == '%') { /* "%%" -> literal "%" */ out [j++] = '%'; pre_len++; } else if (c >= '1' && c <= '7') /* arg # 0-6 */ { /* "%n" -> argument n-1 */ arg_info [k].arg_index = c - '1'; arg_info [k].pre_len = pre_len; if (arg_info [k].arg_index >= n_args) { /* Bad argument index (out of range) */ g_set_error (error, CHAFA_TERM_INFO_ERROR, CHAFA_TERM_INFO_ERROR_BAD_ARGUMENTS, "Control sequence had too many arguments."); goto out; } pre_len = 0; k++; } else if (c == 'v') { /* Variable number of arguments separated by ';' */ arg_info [k].is_varargs = TRUE; arg_info [k].arg_index = 0; /* FIXME: Should be highest seen + 1 */ arg_info [k].pre_len = pre_len; if (arg_info [k].arg_index >= CHAFA_TERM_SEQ_ARGS_MAX) { /* Bad argument index (out of range) */ g_set_error (error, CHAFA_TERM_INFO_ERROR, CHAFA_TERM_INFO_ERROR_BAD_ARGUMENTS, "Control sequence had too many arguments."); goto out; } pre_len = 0; k++; } else { /* Bad "%?" escape */ goto out; } } else { out [j++] = c; pre_len++; } } if (k == CHAFA_TERM_SEQ_ARGS_MAX) { /* Too many argument expansions */ g_set_error (error, CHAFA_TERM_INFO_ERROR, CHAFA_TERM_INFO_ERROR_BAD_ARGUMENTS, "Control sequence had too many arguments."); goto out; } /* Reserve an extra byte for copy_byte() and chafa_format_dec_u8() excess. */ if (j + k * arg_len_max + 1 > CHAFA_TERM_SEQ_LENGTH_MAX) { /* Formatted string may be too long */ g_set_error (error, CHAFA_TERM_INFO_ERROR, CHAFA_TERM_INFO_ERROR_SEQ_TOO_LONG, "Control sequence too long."); goto out; } arg_info [k].pre_len = pre_len; arg_info [k].arg_index = ARG_INDEX_SENTINEL; result = TRUE; out: return result; } #define EMIT_SEQ_DEF(name, inttype, intformatter) \ static gchar * \ emit_seq_##name (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, \ inttype *args, gint n_args) \ { \ const gchar *seq_str; \ const SeqArgInfo *seq_args; \ gint ofs = 0; \ gint i; \ \ seq_str = &term_info->seq_str [seq] [0]; \ seq_args = &term_info->seq_args [seq] [0]; \ \ if (seq_args [0].arg_index == ARG_INDEX_SENTINEL) \ return out; \ \ for (i = 0; i < n_args; i++) \ { \ copy_bytes (out, &seq_str [ofs], seq_args [i].pre_len); \ out += seq_args [i].pre_len; \ ofs += seq_args [i].pre_len; \ out = intformatter (out, args [seq_args [i].arg_index]); \ } \ \ copy_bytes (out, &seq_str [ofs], seq_args [i].pre_len); \ out += seq_args [i].pre_len; \ \ return out; \ } #define EMIT_VARARGS_SEQ_DEF(name, inttype, intformatter) \ static gchar * \ emit_seq_##name (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, \ inttype *args, gint n_args) \ { \ const gchar *seq_str; \ const SeqArgInfo *seq_args; \ gboolean found_varargs = FALSE; \ gint ofs = 0; \ gint i, j; \ \ seq_str = &term_info->seq_str [seq] [0]; \ seq_args = &term_info->seq_args [seq] [0]; \ \ if (seq_args [0].arg_index == ARG_INDEX_SENTINEL) \ return out; \ \ for (i = 0, j = 0; i + j < n_args; ) \ { \ if (found_varargs) \ { \ *(out++) = ';'; \ } \ else \ { \ if (seq_args [i].is_varargs) \ found_varargs = TRUE; \ copy_bytes (out, &seq_str [ofs], seq_args [i].pre_len); \ out += seq_args [i].pre_len; \ ofs += seq_args [i].pre_len; \ } \ \ out = intformatter (out, args [seq_args [i].arg_index + j]);\ \ if (found_varargs) \ j++; \ else \ i++; \ } \ \ if (found_varargs) \ i++; \ \ copy_bytes (out, &seq_str [ofs], seq_args [i].pre_len); \ out += seq_args [i].pre_len; \ \ return out; \ } EMIT_SEQ_DEF(guint, guint, chafa_format_dec_uint_0_to_9999) EMIT_SEQ_DEF(guint8, guint8, chafa_format_dec_u8) EMIT_SEQ_DEF(guint16_hex, guint16, chafa_format_dec_u16_hex) EMIT_VARARGS_SEQ_DEF(guint_varargs, guint, chafa_format_dec_uint_0_to_9999) static gchar * emit_seq_0_args_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq) { copy_bytes (out, &term_info->seq_str [seq] [0], term_info->seq_args [seq] [0].pre_len); return out + term_info->seq_args [seq] [0].pre_len; } static gchar * emit_seq_1_args_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint arg0) { return emit_seq_guint (term_info, out, seq, &arg0, 1); } static gchar * emit_seq_1_args_uint8 (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint8 arg0) { return emit_seq_guint8 (term_info, out, seq, &arg0, 1); } static gchar * emit_seq_2_args_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint arg0, guint arg1) { guint args [2]; args [0] = arg0; args [1] = arg1; return emit_seq_guint (term_info, out, seq, args, 2); } static gchar * emit_seq_2_args_uint8 (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint arg0, guint arg1) { guint8 args [2]; args [0] = arg0; args [1] = arg1; return emit_seq_guint8 (term_info, out, seq, args, 2); } static gchar * emit_seq_3_args_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint arg0, guint arg1, guint arg2) { guint args [3]; args [0] = arg0; args [1] = arg1; args [2] = arg2; return emit_seq_guint (term_info, out, seq, args, 3); } static gchar * emit_seq_5_args_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint arg0, guint arg1, guint arg2, guint arg3, guint arg4) { guint args [5]; args [0] = arg0; args [1] = arg1; args [2] = arg2; args [3] = arg3; args [4] = arg4; return emit_seq_guint (term_info, out, seq, args, 5); } static gchar * emit_seq_6_args_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint arg0, guint arg1, guint arg2, guint arg3, guint arg4, guint arg5) { guint args [6]; args [0] = arg0; args [1] = arg1; args [2] = arg2; args [3] = arg3; args [4] = arg4; args [5] = arg5; return emit_seq_guint (term_info, out, seq, args, 6); } static gchar * emit_seq_3_args_uint8 (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint8 arg0, guint8 arg1, guint8 arg2) { guint8 args [3]; args [0] = arg0; args [1] = arg1; args [2] = arg2; return emit_seq_guint8 (term_info, out, seq, args, 3); } static gchar * emit_seq_6_args_uint8 (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint8 arg0, guint8 arg1, guint8 arg2, guint8 arg3, guint8 arg4, guint8 arg5) { guint8 args [6]; args [0] = arg0; args [1] = arg1; args [2] = arg2; args [3] = arg3; args [4] = arg4; args [5] = arg5; return emit_seq_guint8 (term_info, out, seq, args, 6); } static gchar * emit_seq_3_args_uint16_hex (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint16 arg0, guint16 arg1, guint16 arg2) { guint16 args [3]; args [0] = arg0; args [1] = arg1; args [2] = arg2; return emit_seq_guint16_hex (term_info, out, seq, args, 3); } static gchar * emit_seq_varargs_uint (const ChafaTermInfo *term_info, gchar *out, ChafaTermSeq seq, guint *args, gint n_args) { return emit_seq_guint_varargs (term_info, out, seq, args, n_args); } /* Stream parsing */ static gint parse_dec (const gchar *in, gint in_len, guint *args_out) { gint i = 0; guint result = 0; while (in_len > 0 && *in >= '0' && *in <= '9') { result *= 10; result += *in - '0'; in++; in_len--; i++; } *args_out = result; return i; } static gint parse_hex4 (const gchar *in, gint in_len, guint *args_out) { gint i = 0; guint result = 0; while (in_len > 0) { gchar c = g_ascii_tolower (*in); if (c >= '0' && c <= '9') { result *= 16; result += c - '0'; } else if (c >= 'a' && c <= 'f') { result *= 16; result += c - 'a' + 10; } else break; in++; in_len--; i++; } *args_out = result; return i; } static ChafaParseResult try_parse_seq (const ChafaTermInfo *term_info, ChafaTermSeq seq, gchar **input, gint *input_len, guint *args_out, gint *n_args_out) { gchar *in = *input; gint in_len = *input_len; const gchar *seq_str; const SeqArgInfo *seq_args; gboolean parsed_varargs = FALSE; gint pofs = 0; guint i = 0; seq_str = &term_info->seq_str [seq] [0]; seq_args = &term_info->seq_args [seq] [0]; memset (args_out, 0, seq_meta [seq].n_args * sizeof (guint)); for ( ; ; i++) { gint len; guint j; if (memcmp (in, &seq_str [pofs], MIN (in_len, seq_args [i].pre_len))) return CHAFA_PARSE_FAILURE; if (in_len < seq_args [i].pre_len) return CHAFA_PARSE_AGAIN; in += seq_args [i].pre_len; in_len -= seq_args [i].pre_len; pofs += seq_args [i].pre_len; if (parsed_varargs || i >= seq_meta [seq].n_args) break; if (seq_args [i].is_varargs) parsed_varargs = TRUE; for (j = 0; ; j++) { guint arg_ofs = seq_args [i].arg_index + j; if (arg_ofs > CHAFA_TERM_SEQ_ARGS_MAX - 1) return CHAFA_PARSE_FAILURE; if (in_len == 0) return CHAFA_PARSE_AGAIN; *n_args_out = arg_ofs + 1; if (seq_meta [seq].type_size == 1) len = parse_dec (in, in_len, args_out + arg_ofs); else if (seq_meta [seq].type_size == 2) len = parse_hex4 (in, in_len, args_out + arg_ofs); else len = parse_dec (in, in_len, args_out + arg_ofs); /* Blank args are interpreted to mean zero */ if (len == 0) *(args_out + arg_ofs) = 0; in += len; in_len -= len; if (!seq_args [i].is_varargs) break; if (in_len > 0) { if (*in != ';') break; in++; in_len--; } } } if (*input == in) return CHAFA_PARSE_FAILURE; *input = in; *input_len = in_len; return CHAFA_PARSE_SUCCESS; } /* Public */ G_DEFINE_QUARK (chafa-term-info-error-quark, chafa_term_info_error) /** * chafa_term_info_new: * * Creates a new, blank #ChafaTermInfo. * * Returns: The new #ChafaTermInfo * * Since: 1.6 **/ ChafaTermInfo * chafa_term_info_new (void) { ChafaTermInfo *term_info; gint i; term_info = g_new0 (ChafaTermInfo, 1); term_info->refs = 1; for (i = 0; i < CHAFA_TERM_SEQ_MAX; i++) { term_info->seq_args [i] [0].arg_index = ARG_INDEX_SENTINEL; } return term_info; } /** * chafa_term_info_copy: * @term_info: A #ChafaTermInfo to copy. * * Creates a new #ChafaTermInfo that's a copy of @term_info. * * Returns: The new #ChafaTermInfo * * Since: 1.6 **/ ChafaTermInfo * chafa_term_info_copy (const ChafaTermInfo *term_info) { ChafaTermInfo *new_term_info; gint i; g_return_val_if_fail (term_info != NULL, NULL); new_term_info = g_new (ChafaTermInfo, 1); memcpy (new_term_info, term_info, sizeof (ChafaTermInfo)); new_term_info->refs = 1; for (i = 0; i < CHAFA_TERM_SEQ_MAX; i++) { if (new_term_info->unparsed_str [i]) new_term_info->unparsed_str [i] = g_strdup (new_term_info->unparsed_str [i]); } new_term_info->name = g_strdup (new_term_info->name); return new_term_info; } /** * chafa_term_info_ref: * @term_info: #ChafaTermInfo to add a reference to. * * Adds a reference to @term_info. * * Since: 1.6 **/ void chafa_term_info_ref (ChafaTermInfo *term_info) { gint refs; g_return_if_fail (term_info != NULL); refs = g_atomic_int_get (&term_info->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&term_info->refs); } /** * chafa_term_info_unref: * @term_info: #ChafaTermInfo to remove a reference from. * * Removes a reference from @term_info. * * Since: 1.6 **/ void chafa_term_info_unref (ChafaTermInfo *term_info) { gint refs; g_return_if_fail (term_info != NULL); refs = g_atomic_int_get (&term_info->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&term_info->refs)) { gint i; for (i = 0; i < CHAFA_TERM_SEQ_MAX; i++) g_free (term_info->unparsed_str [i]); g_free (term_info->name); g_free (term_info); } } /** * chafa_term_info_get_name: * @term_info: A #ChafaTermInfo * * Gets the name associated with the @term_info. This may be NULL. * The returned string belongs to @term_info, and is only valid until the * next operation on this data structure. Make a copy using g_strdup() if * you need to keep it around. * * Returns: The name for this #ChafaTermInfo, or %NULL * * Since: 1.16 **/ const gchar * chafa_term_info_get_name (ChafaTermInfo *term_info) { g_return_val_if_fail (term_info != NULL, NULL); return term_info->name; } /** * chafa_term_info_set_name: * @term_info: A #ChafaTermInfo * @name: The new name for this #ChafaTermInfo, or %NULL * * Assigns a new name to @term_info. The name should be a short lowercase * ASCII string that uniquely identifies the terminal or program described * by @term_info. * * Since: 1.16 **/ void chafa_term_info_set_name (ChafaTermInfo *term_info, const gchar *name) { gchar *name_copy; g_return_if_fail (term_info != NULL); name_copy = name ? g_strdup (name) : NULL; g_free (term_info->name); term_info->name = name_copy; } /** * chafa_term_info_is_canvas_mode_supported: * @term_info: A #ChafaTermInfo * @canvas_mode: A #ChafaCanvasMode * * Checks if @term_info has terminal sequences that support @canvas_mode. * * Returns: %TRUE if @canvas_mode is supported, %FALSE otherwise. * * Since: 1.16 **/ gboolean chafa_term_info_is_canvas_mode_supported (ChafaTermInfo *term_info, ChafaCanvasMode canvas_mode) { gboolean result = FALSE; g_return_val_if_fail (term_info != NULL, FALSE); switch (canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT); break; case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FGBG_256) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FG_256) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_BG_256); break; case CHAFA_CANVAS_MODE_INDEXED_16: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FGBG_16) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FG_16) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_BG_16); break; case CHAFA_CANVAS_MODE_INDEXED_16_8: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FGBG_8) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FG_8) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_BG_8) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_ENABLE_BOLD) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_RESET_ATTRIBUTES); break; case CHAFA_CANVAS_MODE_INDEXED_8: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FGBG_8) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_FG_8) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_SET_COLOR_BG_8); break; case CHAFA_CANVAS_MODE_FGBG_BGFG: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_INVERT_COLORS) && chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_RESET_ATTRIBUTES); break; case CHAFA_CANVAS_MODE_FGBG: result = TRUE; break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); } return result ? TRUE : FALSE; } /** * chafa_term_info_get_best_canvas_mode: * @term_info: A #ChafaTermInfo * * Gets the optimal #ChafaCanvasMode supported by @term_info. * * Returns: A #ChafaCanvasMode * * Since: 1.16 **/ ChafaCanvasMode chafa_term_info_get_best_canvas_mode (ChafaTermInfo *term_info) { g_return_val_if_fail (term_info != NULL, CHAFA_CANVAS_MODE_FGBG); if (chafa_term_info_is_canvas_mode_supported (term_info, CHAFA_CANVAS_MODE_TRUECOLOR)) return CHAFA_CANVAS_MODE_TRUECOLOR; if (chafa_term_info_is_canvas_mode_supported (term_info, CHAFA_CANVAS_MODE_INDEXED_240)) return CHAFA_CANVAS_MODE_INDEXED_240; if (chafa_term_info_is_canvas_mode_supported (term_info, CHAFA_CANVAS_MODE_INDEXED_16)) return CHAFA_CANVAS_MODE_INDEXED_16; if (chafa_term_info_is_canvas_mode_supported (term_info, CHAFA_CANVAS_MODE_INDEXED_16_8)) return CHAFA_CANVAS_MODE_INDEXED_16_8; if (chafa_term_info_is_canvas_mode_supported (term_info, CHAFA_CANVAS_MODE_INDEXED_8)) return CHAFA_CANVAS_MODE_INDEXED_8; if (chafa_term_info_is_canvas_mode_supported (term_info, CHAFA_CANVAS_MODE_FGBG_BGFG)) return CHAFA_CANVAS_MODE_FGBG_BGFG; return CHAFA_CANVAS_MODE_FGBG; } /** * chafa_term_info_is_pixel_mode_supported: * @term_info: A #ChafaTermInfo * @pixel_mode: A #ChafaPixelMode * * Checks if @term_info has terminal sequences that support @pixel_mode. * * Returns: %TRUE if @pixel_mode is supported, %FALSE otherwise. * * Since: 1.16 **/ gboolean chafa_term_info_is_pixel_mode_supported (ChafaTermInfo *term_info, ChafaPixelMode pixel_mode) { gboolean result = FALSE; g_return_val_if_fail (term_info != NULL, FALSE); switch (pixel_mode) { case CHAFA_PIXEL_MODE_KITTY: result = chafa_term_info_get_passthrough_type (term_info) == CHAFA_PASSTHROUGH_NONE ? chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1) : chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1); break; case CHAFA_PIXEL_MODE_SIXELS: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_BEGIN_SIXELS); break; case CHAFA_PIXEL_MODE_ITERM2: result = chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE); break; case CHAFA_PIXEL_MODE_SYMBOLS: result = TRUE; break; case CHAFA_PIXEL_MODE_MAX: g_assert_not_reached (); } return result ? TRUE : FALSE; } /** * chafa_term_info_get_best_pixel_mode: * @term_info: A #ChafaTermInfo * * Gets the optimal #ChafaPixelMode supported by @term_info. * * Returns: A #ChafaPixelMode * * Since: 1.16 **/ ChafaPixelMode chafa_term_info_get_best_pixel_mode (ChafaTermInfo *term_info) { g_return_val_if_fail (term_info != NULL, CHAFA_PIXEL_MODE_SYMBOLS); if (chafa_term_info_is_pixel_mode_supported (term_info, CHAFA_PIXEL_MODE_KITTY)) return CHAFA_PIXEL_MODE_KITTY; if (chafa_term_info_is_pixel_mode_supported (term_info, CHAFA_PIXEL_MODE_SIXELS)) return CHAFA_PIXEL_MODE_SIXELS; if (chafa_term_info_is_pixel_mode_supported (term_info, CHAFA_PIXEL_MODE_ITERM2)) return CHAFA_PIXEL_MODE_ITERM2; return CHAFA_PIXEL_MODE_SYMBOLS; } /** * chafa_term_info_get_passthrough_type: * @term_info: A #ChafaTermInfo * * Gets the passthrough mode supported by @term_info. * * Returns: A #ChafaPassthrough * * Since: 1.16 **/ ChafaPassthrough chafa_term_info_get_passthrough_type (ChafaTermInfo *term_info) { g_return_val_if_fail (term_info != NULL, CHAFA_PASSTHROUGH_NONE); if (chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_BEGIN_TMUX_PASSTHROUGH)) return CHAFA_PASSTHROUGH_TMUX; if (chafa_term_info_have_seq (term_info, CHAFA_TERM_SEQ_BEGIN_SCREEN_PASSTHROUGH)) return CHAFA_PASSTHROUGH_SCREEN; return CHAFA_PASSTHROUGH_NONE; } /** * chafa_term_info_get_is_pixel_passthrough_needed: * @term_info: A #ChafaTermInfo * @pixel_mode: A #ChafaPixelMode * * Gets if passthrough should be used to convey images in @pixel_mode. * If needed, the passthrough type can be gotten from chafa_term_info_get_passthrough_type(). * * Returns: %TRUE if passthrough is needed, %FALSE otherwise. * * Since: 1.16 **/ gboolean chafa_term_info_get_is_pixel_passthrough_needed (ChafaTermInfo *term_info, ChafaPixelMode pixel_mode) { g_return_val_if_fail (term_info != NULL, FALSE); g_return_val_if_fail (pixel_mode < CHAFA_PIXEL_MODE_MAX, FALSE); return term_info->pixel_passthrough_needed [pixel_mode] ? TRUE : FALSE; } /** * chafa_term_info_set_is_pixel_passthrough_needed: * @term_info: A #ChafaTermInfo * @pixel_mode: A #ChafaPixelMode * @pixel_passthrough_needed: A boolean indicating whether passthrough is needed * * Specifies if passthrough should be used to convey images in @pixel_mode. * * Since: 1.16 **/ void chafa_term_info_set_is_pixel_passthrough_needed (ChafaTermInfo *term_info, ChafaPixelMode pixel_mode, gboolean pixel_passthrough_needed) { g_return_if_fail (term_info != NULL); g_return_if_fail (pixel_mode < CHAFA_PIXEL_MODE_MAX); term_info->pixel_passthrough_needed [pixel_mode] = pixel_passthrough_needed ? 1 : 0; } /** * chafa_term_info_get_quirks: * @term_info: A #ChafaTermInfo * * Gets the quirks associated with @term_info. * * Returns: The #ChafaTermQuirks flags * * Since: 1.16 **/ ChafaTermQuirks chafa_term_info_get_quirks (ChafaTermInfo *term_info) { g_return_val_if_fail (term_info != NULL, 0); return term_info->quirks; } /** * chafa_term_info_set_quirks: * @term_info: A #ChafaTermInfo * @quirks: A set of #ChafaTermQuirks flags * * Assigns a set of quirks to @term_info. * * Since: 1.16 **/ void chafa_term_info_set_quirks (ChafaTermInfo *term_info, ChafaTermQuirks quirks) { g_return_if_fail (term_info != NULL); term_info->quirks = quirks; } /** * chafa_term_info_get_safe_symbol_tags: * @term_info: A #ChafaTermInfo * * Gets the #ChafaSymbolTags that are likely safe to use with @term_info. The * #ChafaSymbolTags are a bitwise OR of flags from the enum. * * Returns: The #ChafaSymbolTags * * Since: 1.16 **/ ChafaSymbolTags chafa_term_info_get_safe_symbol_tags (ChafaTermInfo *term_info) { g_return_val_if_fail (term_info != NULL, CHAFA_SYMBOL_TAG_NONE); return term_info->safe_symbol_tags; } /** * chafa_term_info_set_safe_symbol_tags: * @term_info: A #ChafaTermInfo * @tags: A set of #ChafaSymbolTags * * Sets the #ChafaSymbolTags that are likely safe to use with @term_info. The * @tags are a bitwise OR of flags from the enum. * * Since: 1.16 **/ void chafa_term_info_set_safe_symbol_tags (ChafaTermInfo *term_info, ChafaSymbolTags tags) { g_return_if_fail (term_info != NULL); term_info->safe_symbol_tags = tags; } /** * chafa_term_info_have_seq: * @term_info: A #ChafaTermInfo. * @seq: A #ChafaTermSeq to query for. * * Checks if @term_info can emit @seq. * * Returns: %TRUE if @seq can be emitted, %FALSE otherwise * * Since: 1.6 **/ gboolean chafa_term_info_have_seq (const ChafaTermInfo *term_info, ChafaTermSeq seq) { g_return_val_if_fail (term_info != NULL, FALSE); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, FALSE); return term_info->unparsed_str [seq] ? TRUE : FALSE; } /** * chafa_term_info_get_seq: * @term_info: A #ChafaTermInfo. * @seq: A #ChafaTermSeq to query for. * * Gets the string equivalent of @seq stored in @term_info. * * Returns: An unformatted string sequence, or %NULL if not set. * * Since: 1.6 **/ const gchar * chafa_term_info_get_seq (ChafaTermInfo *term_info, ChafaTermSeq seq) { g_return_val_if_fail (term_info != NULL, NULL); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, NULL); return term_info->unparsed_str [seq]; } /** * chafa_term_info_set_seq: * @term_info: A #ChafaTermInfo. * @seq: A #ChafaTermSeq to query for. * @str: A control sequence string, or %NULL to clear. * @error: A return location for error details, or %NULL. * * Sets the control sequence string equivalent of @seq stored in @term_info to @str. * * The string may contain argument indexes to be substituted with integers on * formatting. The indexes are preceded by a percentage character and start at 1, * i.e. \%1, \%2, \%3, etc. * * The string's length after formatting must not exceed %CHAFA_TERM_SEQ_LENGTH_MAX * bytes. Each argument can add up to four digits, or three for those specified as * 8-bit integers. If the string could potentially exceed this length when * formatted, chafa_term_info_set_seq() will return %FALSE. * * If parsing fails or @str is too long, any previously existing sequence * will be left untouched. * * Passing %NULL for @str clears the corresponding control sequence. * * Returns: %TRUE if parsing succeeded, %FALSE otherwise * * Since: 1.6 **/ gboolean chafa_term_info_set_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, const gchar *str, GError **error) { gchar seq_str [CHAFA_TERM_SEQ_LENGTH_MAX]; SeqArgInfo seq_args [CHAFA_TERM_SEQ_ARGS_MAX]; gboolean result = FALSE; g_return_val_if_fail (term_info != NULL, FALSE); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, FALSE); if (!str) { term_info->seq_str [seq] [0] = '\0'; term_info->seq_args [seq] [0].pre_len = 0; term_info->seq_args [seq] [0].arg_index = ARG_INDEX_SENTINEL; g_free (term_info->unparsed_str [seq]); term_info->unparsed_str [seq] = NULL; result = TRUE; } else { result = parse_seq_args (&seq_str [0], &seq_args [0], str, seq_meta [seq].n_args, seq_meta [seq].type_size == 1 ? 3 : 4, error); if (result == TRUE) { memcpy (&term_info->seq_str [seq] [0], &seq_str [0], CHAFA_TERM_SEQ_LENGTH_MAX); memcpy (&term_info->seq_args [seq] [0], &seq_args [0], CHAFA_TERM_SEQ_ARGS_MAX * sizeof (SeqArgInfo)); g_free (term_info->unparsed_str [seq]); term_info->unparsed_str [seq] = g_strdup (str); } } return result; } /** * chafa_term_info_emit_seq: * @term_info: A #ChafaTermInfo * @seq: A #ChafaTermSeq to emit * @...: A list of int arguments to insert in @seq, terminated by -1 * * Formats the terminal sequence @seq, inserting positional arguments. The seq's * number of arguments must be supplied exactly. * * The argument list must be terminated by -1, or undefined behavior will result. * * If the wrong number of arguments is supplied, or an argument is out of range, * this function will return %NULL. Otherwise, it returns a zero-terminated string * that must be freed with g_free(). * * If you want compile-time validation of arguments, consider using one of the * specific chafa_term_info_emit_*() functions. They are also faster, but require * you to allocate at least CHAFA_TERM_SEQ_LENGTH_MAX bytes up front. * * Returns: A newly allocated, zero-terminated formatted string, or %NULL on error * * Since: 1.14 **/ gchar * chafa_term_info_emit_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, ...) { va_list args; gchar *result; g_return_val_if_fail (term_info != NULL, NULL); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, NULL); va_start (args, seq); result = chafa_term_info_emit_seq_valist (term_info, seq, &args); va_end (args); return result; } /** * chafa_term_info_emit_seq_valist: * @term_info: A #ChafaTermInfo * @seq: A #ChafaTermSeq to emit * @args: A #va_list of int arguments to insert in @seq * * Behaves like chafa_term_info_emit_seq(), but takes the arguments as a * #va_list. * * Returns: A newly allocated, zero-terminated formatted string, or %NULL on error * * Since: 1.16 **/ gchar * chafa_term_info_emit_seq_valist (ChafaTermInfo *term_info, ChafaTermSeq seq, va_list *args) { guint args_uint [CHAFA_TERM_SEQ_ARGS_MAX]; guint16 args_u16 [CHAFA_TERM_SEQ_ARGS_MAX]; guint8 args_u8 [CHAFA_TERM_SEQ_ARGS_MAX]; gchar buf [CHAFA_TERM_SEQ_LENGTH_MAX]; guint n_args = 0; gchar *p; gchar *result = NULL; g_return_val_if_fail (term_info != NULL, NULL); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, NULL); for (;;) { gint arg = va_arg (*args, gint); if (arg < 0) break; if (n_args == CHAFA_TERM_SEQ_ARGS_MAX || n_args == seq_meta [seq].n_args) goto out; if (seq_meta [seq].type_size == 1) { if (arg > 0xff) goto out; args_u8 [n_args] = arg; } else if (seq_meta [seq].type_size == 2) { if (arg > 0xffff) goto out; args_u16 [n_args] = arg; } else { args_uint [n_args] = arg; } n_args++; } if (seq_meta [seq].seq_type == SEQ_TYPE_FIXARGS && n_args != seq_meta [seq].n_args) goto out; /* 16-bit args are always hex for now. It has no other uses. */ if (seq_meta [seq].seq_type == SEQ_TYPE_VARARGS) p = emit_seq_varargs_uint (term_info, buf, seq, args_uint, n_args); else if (seq_meta [seq].n_args == 0) p = emit_seq_0_args_uint (term_info, buf, seq); else if (seq_meta [seq].type_size == 1) p = emit_seq_guint8 (term_info, buf, seq, args_u8, n_args); else if (seq_meta [seq].type_size == 2) p = emit_seq_guint16_hex (term_info, buf, seq, args_u16, n_args); else p = emit_seq_guint (term_info, buf, seq, args_uint, n_args); if (p == buf) goto out; result = g_strndup (buf, p - buf); out: return result; } /** * chafa_term_info_parse_seq: * @term_info: A #ChafaTermInfo * @seq: A #ChafaTermSeq to attempt to parse * @input: Pointer to pointer to input data * @input_len: Pointer to maximum input data length * @args_out: Pointer to parsed argument values * * Attempts to parse a terminal sequence from an input data array. If successful, * #CHAFA_PARSE_SUCCESS will be returned, the @input pointer will be advanced and * the parsed length will be subtracted from @input_len. * * Thus function can be used with seqs where the number of arguments is known * in advance, but since it doesn't return the number of arguments parsed, it can't * be used with variable-argument seqs. * * It is recommended to use chafa_term_info_parse_seq_varargs() in all cases * instead. * * Returns: A #ChafaParseResult indicating success, failure or insufficient input data * * Since: 1.14 * Deprecated: 1.16: Use chafa_term_info_parse_seq_varargs() instead. **/ ChafaParseResult chafa_term_info_parse_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, gchar **input, gint *input_len, guint *args_out) { guint dummy_args_out [CHAFA_TERM_SEQ_ARGS_MAX]; gint n_args_out; ChafaParseResult result; g_return_val_if_fail (term_info != NULL, CHAFA_PARSE_FAILURE); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, CHAFA_PARSE_FAILURE); g_return_val_if_fail (input != NULL, CHAFA_PARSE_FAILURE); g_return_val_if_fail (*input != NULL, CHAFA_PARSE_FAILURE); g_return_val_if_fail (input_len != NULL, CHAFA_PARSE_FAILURE); if (!chafa_term_info_have_seq (term_info, seq)) return CHAFA_PARSE_FAILURE; if (!args_out) args_out = dummy_args_out; result = try_parse_seq (term_info, seq, input, input_len, dummy_args_out, &n_args_out); if (result == CHAFA_PARSE_SUCCESS && args_out) { /* CHAFA_TERM_SEQ_ARGS_MAX was increased from 8 to 24 in version 1.16.0. * For ABI backwards compatibility, respect the legacy value in this legacy * function. */ n_args_out = MIN (n_args_out, 8); memcpy (args_out, dummy_args_out, n_args_out * sizeof (guint)); } return result; } /** * chafa_term_info_parse_seq_varargs: * @term_info: A #ChafaTermInfo * @seq: A #ChafaTermSeq to attempt to parse * @input: Pointer to pointer to input data * @input_len: Pointer to maximum input data length * @args_out: Pointer to parsed argument values * @n_args_out: Pointer to storage for argument count * * Attempts to parse a terminal sequence from an input data array. If successful, * #CHAFA_PARSE_SUCCESS will be returned, the @input pointer will be advanced and * the parsed length will be subtracted from @input_len. * * Any numeric parsed arguments are returned as an array starting at @args_out, * which must have room for up to #CHAFA_TERM_SEQ_ARGS_MAX elements. * * The number of parsed arguments is returned in @n_args_out. This is useful for * seqs with a variable number of arguments, like #CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES. * * Either or both of @args_out and @n_args_out can be %NULL, in which case * nothing is returned for that parameter. * * Returns: A #ChafaParseResult indicating success, failure or insufficient input data * * Since: 1.16 **/ ChafaParseResult chafa_term_info_parse_seq_varargs (ChafaTermInfo *term_info, ChafaTermSeq seq, gchar **input, gint *input_len, guint *args_out, gint *n_args_out) { guint dummy_args_out [CHAFA_TERM_SEQ_ARGS_MAX]; gint dummy_n_args_out; g_return_val_if_fail (term_info != NULL, CHAFA_PARSE_FAILURE); g_return_val_if_fail (seq >= 0 && seq < CHAFA_TERM_SEQ_MAX, CHAFA_PARSE_FAILURE); g_return_val_if_fail (input != NULL, CHAFA_PARSE_FAILURE); g_return_val_if_fail (*input != NULL, CHAFA_PARSE_FAILURE); g_return_val_if_fail (input_len != NULL, CHAFA_PARSE_FAILURE); if (!chafa_term_info_have_seq (term_info, seq)) return CHAFA_PARSE_FAILURE; if (!args_out) args_out = dummy_args_out; if (!n_args_out) n_args_out = &dummy_n_args_out; return try_parse_seq (term_info, seq, input, input_len, args_out, n_args_out); } /** * chafa_term_info_get_inherit_seq: * @term_info: A #ChafaTermInfo * @seq: A #ChafaTermSeq * * Gets whether @seq can be inherited from the outer #ChafaTermInfo * when chaining with chafa_term_info_chain(). * * Returns: Whether @seq gets inherited when chaining * * Since: 1.16 **/ gboolean chafa_term_info_get_inherit_seq (ChafaTermInfo *term_info, ChafaTermSeq seq) { g_return_val_if_fail (term_info != NULL, FALSE); g_return_val_if_fail (seq < CHAFA_TERM_SEQ_MAX, FALSE); return term_info->inherit_seq [seq]; } /** * chafa_term_info_set_inherit_seq: * @term_info: A #ChafaTermInfo * @seq: A #ChafaTermSeq * @inherit: A boolean indicating whether @seq should be inherited * * Sets whether @seq can be inherited from the outer #ChafaTermInfo * when chaining with chafa_term_info_chain(). * * Since: 1.16 **/ void chafa_term_info_set_inherit_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, gboolean inherit) { g_return_if_fail (term_info != NULL); g_return_if_fail (seq < CHAFA_TERM_SEQ_MAX); term_info->inherit_seq [seq] = inherit; } /** * chafa_term_info_supplement: * @term_info: A #ChafaTermInfo to supplement * @source: A #ChafaTermInfo to copy from * * Supplements missing sequences in @term_info with ones copied * from @source. * * Since: 1.6 **/ void chafa_term_info_supplement (ChafaTermInfo *term_info, ChafaTermInfo *source) { gint i; g_return_if_fail (term_info != NULL); g_return_if_fail (source != NULL); for (i = 0; i < CHAFA_TERM_SEQ_MAX; i++) { if (!term_info->unparsed_str [i] && source->unparsed_str [i]) { term_info->unparsed_str [i] = g_strdup (source->unparsed_str [i]); memcpy (&term_info->seq_str [i] [0], &source->seq_str [i] [0], CHAFA_TERM_SEQ_LENGTH_MAX); memcpy (&term_info->seq_args [i] [0], &source->seq_args [i] [0], CHAFA_TERM_SEQ_ARGS_MAX * sizeof (SeqArgInfo)); } } } /** * chafa_term_info_chain: * @outer: The #ChafaTermInfo for the outer terminal * @inner: The #ChafaTermInfo for the inner terminal * * Terminal emulators and applications are often nested, with the inner * application's capabilities limiting, extending or modifying the outer's. * * Examples are terminal multiplexers like Screen and tmux, or terminal * emulators running inside editors like Emacs and vi. * * This merges the @outer and @inner sequences into a single #ChafaTermInfo * according to the following rules. * * For sequences marked as inherited in @inner: * * - If either @inner or @outer sequence is %NULL, pick the @outer sequence. * - Otherwise, pick @inner sequence. * * For sequences not marked as inherited, always use the @inner sequence. * * This allows for using the inner term's sequences while clearing them if the * outer term does not support the sequence at all. This is useful for muxers * (e.g. fbterm supports 256 colors, but with private seqs; we want to use the * inner mux' corresponding seqs). * * The merged #ChafaTermInfo is a new instance, with the initial reference * owned by the caller. * * This function can be used repeatedly to create chains that're arbitrarily * long, but is unlikely to be useful beyond three levels (terminal emulator, * multiplexer, application). * * Returns: The merged #ChafaTermInfo * * Since: 1.16 **/ ChafaTermInfo * chafa_term_info_chain (ChafaTermInfo *outer, ChafaTermInfo *inner) { ChafaTermInfo *chained; const gchar *outer_name, *inner_name; gchar *new_name; gint i; chained = chafa_term_info_copy (outer); for (i = 0; i < CHAFA_TERM_SEQ_MAX; i++) { if (chafa_term_info_get_inherit_seq (inner, i)) { if (chained->unparsed_str [i] && inner->unparsed_str [i]) copy_seq (inner, chained, i); } else { copy_seq (inner, chained, i); } } for (i = 0; i < CHAFA_PIXEL_MODE_MAX; i++) chained->pixel_passthrough_needed [i] = inner->pixel_passthrough_needed [i] | outer->pixel_passthrough_needed [i]; chained->safe_symbol_tags |= inner->safe_symbol_tags & outer->safe_symbol_tags; chained->quirks = inner->quirks | outer->quirks; outer_name = chafa_term_info_get_name (outer); inner_name = chafa_term_info_get_name (inner); new_name = g_strjoin (":", inner_name ? inner_name : "unknown", outer_name ? outer_name : "unknown", NULL); chafa_term_info_set_name (chained, new_name); g_free (new_name); return chained; } #define DEFINE_EMIT_SEQ_0_none_char(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest) \ { return emit_seq_0_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name); } #define DEFINE_EMIT_SEQ_1_none_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint arg) \ { return emit_seq_1_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg); } #define DEFINE_EMIT_SEQ_1_none_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg) \ { return emit_seq_1_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg); } #define DEFINE_EMIT_SEQ_1_8fg_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg) \ { return emit_seq_1_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg + 30); } #define DEFINE_EMIT_SEQ_1_8bg_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg) \ { return emit_seq_1_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg + 40); } #define DEFINE_EMIT_SEQ_1_aix16fg_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg) \ { return emit_seq_1_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg + (arg < 8 ? 30 : (90 - 8))); } #define DEFINE_EMIT_SEQ_1_aix16bg_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg) \ { return emit_seq_1_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg + (arg < 8 ? 40 : (100 - 8))); } #define DEFINE_EMIT_SEQ_2_none_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint arg0, guint arg1) \ { return emit_seq_2_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1); } #define DEFINE_EMIT_SEQ_2_pos_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint arg0, guint arg1) \ { return emit_seq_2_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0 + 1, arg1 + 1); } #define DEFINE_EMIT_SEQ_2_none_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg0, guint8 arg1) \ { return emit_seq_2_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1); } #define DEFINE_EMIT_SEQ_2_8fgbg_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg0, guint8 arg1) \ { return emit_seq_2_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0 + 30, arg1 + 40); } #define DEFINE_EMIT_SEQ_2_aix16fgbg_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg0, guint8 arg1) \ { return emit_seq_2_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0 + (arg0 < 8 ? 30 : (90 - 8)), arg1 + (arg1 < 8 ? 40 : (100 - 8))); } #define DEFINE_EMIT_SEQ_3_none_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint arg0, guint arg1, guint arg2) \ { return emit_seq_3_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1, arg2); } #define DEFINE_EMIT_SEQ_5_none_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint arg0, guint arg1, guint arg2, guint arg3, guint arg4) \ { return emit_seq_5_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1, arg2, arg3, arg4); } #define DEFINE_EMIT_SEQ_6_none_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint arg0, guint arg1, guint arg2, guint arg3, guint arg4, guint arg5) \ { return emit_seq_6_args_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1, arg2, arg3, arg4, arg5); } #define DEFINE_EMIT_SEQ_3_none_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg0, guint8 arg1, guint8 arg2) \ { return emit_seq_3_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1, arg2); } #define DEFINE_EMIT_SEQ_6_none_guint8(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint8 arg0, guint8 arg1, guint8 arg2, guint8 arg3, guint8 arg4, guint8 arg5) \ { return emit_seq_6_args_uint8 (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1, arg2, arg3, arg4, arg5); } #define DEFINE_EMIT_SEQ_3_u16hex_guint16(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint16 arg0, guint16 arg1, guint16 arg2) \ { return emit_seq_3_args_uint16_hex (term_info, dest, CHAFA_TERM_SEQ_##seq_name, arg0, arg1, arg2); } #define DEFINE_EMIT_SEQ_VARARGS_guint(func_name, seq_name) \ gchar *chafa_term_info_emit_##func_name(const ChafaTermInfo *term_info, gchar *dest, guint *args, gint n_args) \ { return emit_seq_varargs_uint (term_info, dest, CHAFA_TERM_SEQ_##seq_name, args, n_args); } #define CHAFA_TERM_SEQ_DEF(name, NAME, n_args, arg_proc, arg_type, args) \ DEFINE_EMIT_SEQ_##n_args##_##arg_proc##_##arg_type(name, NAME) #define CHAFA_TERM_SEQ_DEF_VARARGS(name, NAME, arg_type) \ DEFINE_EMIT_SEQ_VARARGS_##arg_type(name, NAME) #include "chafa-term-seq-def.h" #undef CHAFA_TERM_SEQ_DEF #undef CHAFA_TERM_SEQ_DEF_VARARGS chafa-1.18.2/chafa/chafa-term-info.h000066400000000000000000000173371517447374300170520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_TERM_INFO_H__ #define __CHAFA_TERM_INFO_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS #define CHAFA_TERM_SEQ_LENGTH_MAX 96 /* Maximum number of arguments + 1 for sentinel */ #define CHAFA_TERM_SEQ_ARGS_MAX 24 #ifndef __GTK_DOC_IGNORE__ /* This declares the enum for CHAFA_TERM_SEQ_*. See chafa-term-seq-def.h * for more information, or look up the canonical documentation at * https://hpjansson.org/chafa/ref/ for verbose definitions. */ typedef enum { #define CHAFA_TERM_SEQ_DEF(name, NAME, n_args, arg_proc, arg_type, args) CHAFA_TERM_SEQ_##NAME, #define CHAFA_TERM_SEQ_DEF_VARARGS(name, NAME, arg_type) CHAFA_TERM_SEQ_##NAME, #include #undef CHAFA_TERM_SEQ_DEF #undef CHAFA_TERM_SEQ_DEF_VARARGS CHAFA_TERM_SEQ_MAX } ChafaTermSeq; #endif /* __GTK_DOC_IGNORE__ */ /** * ChafaTermQuirks: * @CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT: After printing a sixel image in advance-down * mode, terminal leaves the cursor below the final row instead of on top of it. * * Flags denoting various terminal quirks. **/ typedef enum { CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT = (1 << 0) } ChafaTermQuirks; typedef struct ChafaTermInfo ChafaTermInfo; /** * CHAFA_TERM_INFO_ERROR: * * Error domain for #ChafaTermInfo. Errors in this domain will * be from the #ChafaTermInfoError enumeration. See #GError for information on * error domains. **/ #define CHAFA_TERM_INFO_ERROR (chafa_term_info_error_quark ()) /** * ChafaTermInfoError: * @CHAFA_TERM_INFO_ERROR_SEQ_TOO_LONG: A control sequence could exceed * #CHAFA_TERM_SEQ_LENGTH_MAX bytes if formatted with maximum argument lengths. * @CHAFA_TERM_INFO_ERROR_BAD_ESCAPE: An illegal escape sequence was used. * @CHAFA_TERM_INFO_ERROR_BAD_ARGUMENTS: A control sequence specified * more than the maximum number of arguments, or an argument index was out * of range. * * Error codes returned by control sequence parsing. **/ typedef enum { CHAFA_TERM_INFO_ERROR_SEQ_TOO_LONG, CHAFA_TERM_INFO_ERROR_BAD_ESCAPE, CHAFA_TERM_INFO_ERROR_BAD_ARGUMENTS } ChafaTermInfoError; /** * ChafaParseResult: * @CHAFA_PARSE_SUCCESS: Parsed successfully * @CHAFA_PARSE_FAILURE: Data mismatch * @CHAFA_PARSE_AGAIN: Partial success, but not enough input * * An enumeration of the possible return values from the parsing function. **/ typedef enum { CHAFA_PARSE_SUCCESS, CHAFA_PARSE_FAILURE, CHAFA_PARSE_AGAIN } ChafaParseResult; CHAFA_AVAILABLE_IN_1_6 GQuark chafa_term_info_error_quark (void); CHAFA_AVAILABLE_IN_1_6 ChafaTermInfo *chafa_term_info_new (void); CHAFA_AVAILABLE_IN_1_6 ChafaTermInfo *chafa_term_info_copy (const ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_6 void chafa_term_info_ref (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_6 void chafa_term_info_unref (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 const gchar *chafa_term_info_get_name (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 void chafa_term_info_set_name (ChafaTermInfo *term_info, const gchar *name); CHAFA_AVAILABLE_IN_1_16 gboolean chafa_term_info_is_canvas_mode_supported (ChafaTermInfo *term_info, ChafaCanvasMode canvas_mode); CHAFA_AVAILABLE_IN_1_16 ChafaCanvasMode chafa_term_info_get_best_canvas_mode (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 gboolean chafa_term_info_is_pixel_mode_supported (ChafaTermInfo *term_info, ChafaPixelMode pixel_mode); CHAFA_AVAILABLE_IN_1_16 ChafaPixelMode chafa_term_info_get_best_pixel_mode (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 ChafaPassthrough chafa_term_info_get_passthrough_type (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 gboolean chafa_term_info_get_is_pixel_passthrough_needed (ChafaTermInfo *term_info, ChafaPixelMode pixel_mode); CHAFA_AVAILABLE_IN_1_16 void chafa_term_info_set_is_pixel_passthrough_needed (ChafaTermInfo *term_info, ChafaPixelMode pixel_mode, gboolean pixel_passthrough_needed); CHAFA_AVAILABLE_IN_1_16 ChafaTermQuirks chafa_term_info_get_quirks (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 void chafa_term_info_set_quirks (ChafaTermInfo *term_info, ChafaTermQuirks quirks); CHAFA_AVAILABLE_IN_1_16 ChafaSymbolTags chafa_term_info_get_safe_symbol_tags (ChafaTermInfo *term_info); CHAFA_AVAILABLE_IN_1_16 void chafa_term_info_set_safe_symbol_tags (ChafaTermInfo *term_info, ChafaSymbolTags tags); CHAFA_AVAILABLE_IN_1_6 const gchar *chafa_term_info_get_seq (ChafaTermInfo *term_info, ChafaTermSeq seq); CHAFA_AVAILABLE_IN_1_6 gint chafa_term_info_set_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, const gchar *str, GError **error); CHAFA_AVAILABLE_IN_1_6 gboolean chafa_term_info_have_seq (const ChafaTermInfo *term_info, ChafaTermSeq seq); CHAFA_AVAILABLE_IN_1_14 gchar *chafa_term_info_emit_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, ...); CHAFA_AVAILABLE_IN_1_16 gchar *chafa_term_info_emit_seq_valist (ChafaTermInfo *term_info, ChafaTermSeq seq, va_list *args); CHAFA_DEPRECATED_IN_1_16 ChafaParseResult chafa_term_info_parse_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, gchar **input, gint *input_len, guint *args_out); CHAFA_AVAILABLE_IN_1_16 ChafaParseResult chafa_term_info_parse_seq_varargs (ChafaTermInfo *term_info, ChafaTermSeq seq, gchar **input, gint *input_len, guint *args_out, gint *n_args_out); CHAFA_AVAILABLE_IN_1_16 gboolean chafa_term_info_get_inherit_seq (ChafaTermInfo *term_info, ChafaTermSeq seq); CHAFA_AVAILABLE_IN_1_16 void chafa_term_info_set_inherit_seq (ChafaTermInfo *term_info, ChafaTermSeq seq, gboolean inherit); CHAFA_AVAILABLE_IN_1_6 void chafa_term_info_supplement (ChafaTermInfo *term_info, ChafaTermInfo *source); CHAFA_AVAILABLE_IN_1_16 ChafaTermInfo *chafa_term_info_chain (ChafaTermInfo *outer, ChafaTermInfo *inner); /* This declares the prototypes for chafa_term_info_emit_*(). See * chafa-term-seq-def.h for more information, or look up the canonical * documentation at https://hpjansson.org/chafa/ref/ for verbose * function prototypes. */ #define CHAFA_TERM_SEQ_DEF(name, NAME, n_args, arg_proc, arg_type, args) \ CHAFA_TERM_SEQ_AVAILABILITY gchar * chafa_term_info_emit_##name args; #define CHAFA_TERM_SEQ_DEF_VARARGS(name, NAME, arg_type) \ CHAFA_TERM_SEQ_AVAILABILITY gchar * chafa_term_info_emit_##name(const ChafaTermInfo *term_info, gchar *dest, arg_type *args, gint n_args); #include #undef CHAFA_TERM_SEQ_DEF #undef CHAFA_TERM_SEQ_DEF_VARARGS G_END_DECLS #endif /* __CHAFA_TERM_INFO_H__ */ chafa-1.18.2/chafa/chafa-term-seq-def.h000066400000000000000000002561651517447374300174470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* Terminal sequence definitions * ----------------------------- * * This file is #included in various contexts with CHAFA_TERM_SEQ_DEF() * expanding to different things. It allows us to keep all the terminal * sequence metadata in one place. * * We process this file with 'cpp -CC' to let the docstrings through to * gtk-doc. * * The generator macro is invoked with the following arguments: * * CHAFA_TERM_SEQ_DEF (name, NAME, n_args, args_proc, args_type, ...) * * Sequences are grouped by the library version they became available in, * with CHAFA_TERM_SEQ_AVAILABILITY expanding to the appropriate version * macro in each case. * * The actual sequence strings are not defined here; they belong to the * individual terminal model definitions. * * References * ---------- * * VT220 sequences: https://vt100.net/docs/vt220-rm/chapter4.html * Sixels: https://vt100.net/docs/vt3xx-gp/chapter14.html */ /* For zero-argument functions, we use "char" as the argument type instead * of the more appropriate "void", since we need to be able to use it with * sizeof() and -Wpointer-arith. */ /* The sixth argument to CHAFA_TERM_SEQ_DEF() is the full prototype argument * list of chafa_term_info_emit_(), parenthesised. It always begins * with the (term_info, dest) prefix common to every emitter; we factor that * prefix out as CHAFA_TERM_SEQ_PFX so individual defs only spell out the * per-sequence tail. Carrying the full list as a single parenthesised token * lets us stay strictly C99-conformant (i.e. no variadic macros). */ #define CHAFA_TERM_SEQ_PFX const ChafaTermInfo *term_info, gchar *dest /* --- Available in 1.6+ --- */ #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_6 /** * chafa_term_info_emit_reset_terminal_soft: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(reset_terminal_soft, RESET_TERMINAL_SOFT, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_terminal_hard: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_TERMINAL_HARD. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(reset_terminal_hard, RESET_TERMINAL_HARD, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_attributes: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_ATTRIBUTES. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(reset_attributes, RESET_ATTRIBUTES, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_clear: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CLEAR. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(clear, CLEAR, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_invert_colors: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_INVERT_COLORS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(invert_colors, INVERT_COLORS, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /* Cursor movement. Cursor stops at margins. */ /** * chafa_term_info_emit_cursor_to_top_left: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_to_top_left, CURSOR_TO_TOP_LEFT, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_to_bottom_left: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_TO_BOTTOM_LEFT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_to_bottom_left, CURSOR_TO_BOTTOM_LEFT, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_to_pos: * @term_info: A #ChafaTermInfo * @dest: String destination * @x: Offset from left edge of display, zero-indexed * @y: Offset from top edge of display, zero-indexed * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_TO_POS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_to_pos, CURSOR_TO_POS, 2, pos, guint, (CHAFA_TERM_SEQ_PFX, guint x, guint y)) /** * chafa_term_info_emit_cursor_up_1: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_UP_1. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_up_1, CURSOR_UP_1, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_up: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Distance to move the cursor * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_UP. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_up, CURSOR_UP, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /** * chafa_term_info_emit_cursor_down_1: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_DOWN_1. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_down_1, CURSOR_DOWN_1, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_down: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Distance to move the cursor * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_DOWN. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_down, CURSOR_DOWN, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /** * chafa_term_info_emit_cursor_left_1: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_LEFT_1. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_left_1, CURSOR_LEFT_1, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_left: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Distance to move the cursor * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_LEFT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_left, CURSOR_LEFT, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /** * chafa_term_info_emit_cursor_right_1: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_RIGHT_1. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_right_1, CURSOR_RIGHT_1, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_right: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Distance to move the cursor * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_RIGHT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_right, CURSOR_RIGHT, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /* Cursor movement. Cursor crossing margin causes scrolling region to * scroll. */ /** * chafa_term_info_emit_cursor_up_scroll: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_UP_SCROLL. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_up_scroll, CURSOR_UP_SCROLL, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cursor_down_scroll: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(cursor_down_scroll, CURSOR_DOWN_SCROLL, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /* Cells will shift on insert. Cells shifted off the edge will be lost. */ /** * chafa_term_info_emit_insert_cells: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Number of cells to insert * * Prints the control sequence for #CHAFA_TERM_SEQ_INSERT_CELLS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(insert_cells, INSERT_CELLS, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /** * chafa_term_info_emit_delete_cells: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Number of cells to delete * * Prints the control sequence for #CHAFA_TERM_SEQ_DELETE_CELLS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(delete_cells, DELETE_CELLS, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /* Cursor must be inside scrolling region. Rows are shifted inside the * scrolling region. Rows shifted off the edge will be lost. The cursor * position is reset to the first column. */ /** * chafa_term_info_emit_insert_rows: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Number of rows to insert * * Prints the control sequence for #CHAFA_TERM_SEQ_INSERT_ROWS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(insert_rows, INSERT_ROWS, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /** * chafa_term_info_emit_delete_rows: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Number of rows to delete * * Prints the control sequence for #CHAFA_TERM_SEQ_DELETE_ROWS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(delete_rows, DELETE_ROWS, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /* Defines the scrolling region. */ /** * chafa_term_info_emit_set_scrolling_rows: * @term_info: A #ChafaTermInfo * @dest: String destination * @top: First row in scrolling area, zero-indexed * @bottom: Last row in scrolling area, zero-indexed * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_SCROLLING_ROWS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_scrolling_rows, SET_SCROLLING_ROWS, 2, pos, guint, (CHAFA_TERM_SEQ_PFX, guint top, guint bottom)) /* Indicates whether characters printed in the middle of a row should * cause subsequent cells to shift forwards. Cells shifted off the edge * will be lost. If disabled, cells at the cursor position will be * overwritten instead. */ /** * chafa_term_info_emit_enable_insert: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_INSERT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(enable_insert, ENABLE_INSERT, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_disable_insert: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DISABLE_INSERT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(disable_insert, DISABLE_INSERT, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_enable_cursor: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_CURSOR. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(enable_cursor, ENABLE_CURSOR, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_disable_cursor: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DISABLE_CURSOR. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(disable_cursor, DISABLE_CURSOR, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_enable_echo: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_ECHO. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(enable_echo, ENABLE_ECHO, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_disable_echo: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DISABLE_ECHO. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(disable_echo, DISABLE_ECHO, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /* When printing a character in the last column, indicates whether the * cursor should move to the next row and potentially cause scrolling. If * disabled, the cursor may still move to the first column. */ /** * chafa_term_info_emit_enable_wrap: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_WRAP. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(enable_wrap, ENABLE_WRAP, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_disable_wrap: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DISABLE_WRAP. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(disable_wrap, DISABLE_WRAP, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_set_color_fg_direct: * @term_info: A #ChafaTermInfo * @dest: String destination * @r: Red component, 0-255 * @g: Green component, 0-255 * @b: Blue component, 0-255 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_fg_direct, SET_COLOR_FG_DIRECT, 3, none, guint8, (CHAFA_TERM_SEQ_PFX, guint8 r, guint8 g, guint8 b)) /** * chafa_term_info_emit_set_color_bg_direct: * @term_info: A #ChafaTermInfo * @dest: String destination * @r: Red component, 0-255 * @g: Green component, 0-255 * @b: Blue component, 0-255 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_bg_direct, SET_COLOR_BG_DIRECT, 3, none, guint8, (CHAFA_TERM_SEQ_PFX, guint8 r, guint8 g, guint8 b)) /** * chafa_term_info_emit_set_color_fgbg_direct: * @term_info: A #ChafaTermInfo * @dest: String destination * @fg_r: Foreground red component, 0-255 * @fg_g: Foreground green component, 0-255 * @fg_b: Foreground blue component, 0-255 * @bg_r: Background red component, 0-255 * @bg_g: Background green component, 0-255 * @bg_b: Background blue component, 0-255 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_fgbg_direct, SET_COLOR_FGBG_DIRECT, 6, none, guint8, (CHAFA_TERM_SEQ_PFX, guint8 fg_r, guint8 fg_g, guint8 fg_b, guint8 bg_r, guint8 bg_g, guint8 bg_b)) /** * chafa_term_info_emit_set_color_fg_256: * @term_info: A #ChafaTermInfo * @dest: String destination * @pen: Pen number, 0-255 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FG_256. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_fg_256, SET_COLOR_FG_256, 1, none, guint8, (CHAFA_TERM_SEQ_PFX, guint8 pen)) /** * chafa_term_info_emit_set_color_bg_256: * @term_info: A #ChafaTermInfo * @dest: String destination * @pen: Pen number, 0-255 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_BG_256. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_bg_256, SET_COLOR_BG_256, 1, none, guint8, (CHAFA_TERM_SEQ_PFX, guint8 pen)) /** * chafa_term_info_emit_set_color_fgbg_256: * @term_info: A #ChafaTermInfo * @dest: String destination * @fg_pen: Foreground pen number, 0-255 * @bg_pen: Background pen number, 0-255 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FGBG_256. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_fgbg_256, SET_COLOR_FGBG_256, 2, none, guint8, (CHAFA_TERM_SEQ_PFX, guint8 fg_pen, guint8 bg_pen)) /** * chafa_term_info_emit_set_color_fg_16: * @term_info: A #ChafaTermInfo * @dest: String destination * @pen: Pen number, 0-15 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FG_16. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_fg_16, SET_COLOR_FG_16, 1, aix16fg, guint8, (CHAFA_TERM_SEQ_PFX, guint8 pen)) /** * chafa_term_info_emit_set_color_bg_16: * @term_info: A #ChafaTermInfo * @dest: String destination * @pen: Pen number, 0-15 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_BG_16. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_bg_16, SET_COLOR_BG_16, 1, aix16bg, guint8, (CHAFA_TERM_SEQ_PFX, guint8 pen)) /** * chafa_term_info_emit_set_color_fgbg_16: * @term_info: A #ChafaTermInfo * @dest: String destination * @fg_pen: Foreground pen number, 0-15 * @bg_pen: Background pen number, 0-15 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FGBG_16. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(set_color_fgbg_16, SET_COLOR_FGBG_16, 2, aix16fgbg, guint8, (CHAFA_TERM_SEQ_PFX, guint8 fg_pen, guint8 bg_pen)) /** * chafa_term_info_emit_begin_sixels: * @term_info: A #ChafaTermInfo * @dest: String destination * @p1: Pixel aspect selector * @p2: Background color selector * @p3: Horizontal grid selector * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_SIXELS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * All three parameters (@p1, @p2 and @p3) can normally be set to 0. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(begin_sixels, BEGIN_SIXELS, 3, none, guint, (CHAFA_TERM_SEQ_PFX, guint p1, guint p2, guint p3)) /** * chafa_term_info_emit_end_sixels: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_SIXELS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(end_sixels, END_SIXELS, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_repeat_char: * @term_info: A #ChafaTermInfo * @dest: String destination * @n: Number of repetitions * * Prints the control sequence for #CHAFA_TERM_SEQ_REPEAT_CHAR. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.6 **/ CHAFA_TERM_SEQ_DEF(repeat_char, REPEAT_CHAR, 1, none, guint, (CHAFA_TERM_SEQ_PFX, guint n)) /* --- Available in 1.8+ --- */ #undef CHAFA_TERM_SEQ_AVAILABILITY #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_8 /** * chafa_term_info_emit_begin_kitty_immediate_image_v1: * @term_info: A #ChafaTermInfo * @dest: String destination * @bpp: Bits per pixel * @width_pixels: Image width in pixels * @height_pixels: Image height in pixels * @width_cells: Target width in cells * @height_cells: Target height in cells * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_IMAGE_V1. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * @bpp must be set to either 24 for RGB data, 32 for RGBA, or 100 to embed a * PNG file. * * This sequence must be followed by zero or more paired sequences of * type #CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK and #CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK * with base-64 encoded image data between them. * * When the image data has been transferred, #CHAFA_TERM_SEQ_END_KITTY_IMAGE must * be emitted. * * Returns: Pointer to first byte after emitted string * * Since: 1.8 **/ CHAFA_TERM_SEQ_DEF(begin_kitty_immediate_image_v1, BEGIN_KITTY_IMMEDIATE_IMAGE_V1, 5, none, guint, (CHAFA_TERM_SEQ_PFX, guint bpp, guint width_pixels, guint height_pixels, guint width_cells, guint height_cells)) /** * chafa_term_info_emit_end_kitty_image: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_KITTY_IMAGE. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.8 **/ CHAFA_TERM_SEQ_DEF(end_kitty_image, END_KITTY_IMAGE, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_begin_kitty_image_chunk: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.8 **/ CHAFA_TERM_SEQ_DEF(begin_kitty_image_chunk, BEGIN_KITTY_IMAGE_CHUNK, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_kitty_image_chunk: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.8 **/ CHAFA_TERM_SEQ_DEF(end_kitty_image_chunk, END_KITTY_IMAGE_CHUNK, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_begin_iterm2_image: * @term_info: A #ChafaTermInfo * @dest: String destination * @width: Image width in character cells * @height: Image height in character cells * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_ITERM2_IMAGE. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * This sequence must be followed by base64-encoded image file data. The image * can be any format supported by MacOS, e.g. PNG, JPEG, TIFF, GIF. When the * image data has been transferred, #CHAFA_TERM_SEQ_END_ITERM2_IMAGE must be * emitted. * * Returns: Pointer to first byte after emitted string * * Since: 1.8 **/ CHAFA_TERM_SEQ_DEF(begin_iterm2_image, BEGIN_ITERM2_IMAGE, 2, none, guint, (CHAFA_TERM_SEQ_PFX, guint width, guint height)) /** * chafa_term_info_emit_end_iterm2_image: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_ITERM2_IMAGE. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.8 **/ CHAFA_TERM_SEQ_DEF(end_iterm2_image, END_ITERM2_IMAGE, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /* --- Available in 1.10+ --- */ #undef CHAFA_TERM_SEQ_AVAILABILITY #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_10 /** * chafa_term_info_emit_enable_sixel_scrolling: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.10 **/ CHAFA_TERM_SEQ_DEF(enable_sixel_scrolling, ENABLE_SIXEL_SCROLLING, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_disable_sixel_scrolling: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DISABLE_SIXEL_SCROLLING. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.10 **/ CHAFA_TERM_SEQ_DEF(disable_sixel_scrolling, DISABLE_SIXEL_SCROLLING, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /* --- Available in 1.12+ --- */ #undef CHAFA_TERM_SEQ_AVAILABILITY #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_12 /** * chafa_term_info_emit_enable_bold: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_BOLD. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.12 **/ CHAFA_TERM_SEQ_DEF(enable_bold, ENABLE_BOLD, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_set_color_fg_8: * @term_info: A #ChafaTermInfo * @dest: String destination * @pen: Pen number, 0-7 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FG_8. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.12 **/ CHAFA_TERM_SEQ_DEF(set_color_fg_8, SET_COLOR_FG_8, 1, 8fg, guint8, (CHAFA_TERM_SEQ_PFX, guint8 pen)) /** * chafa_term_info_emit_set_color_bg_8: * @term_info: A #ChafaTermInfo * @dest: String destination * @pen: Pen number, 0-7 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_BG_8. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.12 **/ CHAFA_TERM_SEQ_DEF(set_color_bg_8, SET_COLOR_BG_8, 1, 8bg, guint8, (CHAFA_TERM_SEQ_PFX, guint8 pen)) /** * chafa_term_info_emit_set_color_fgbg_8: * @term_info: A #ChafaTermInfo * @dest: String destination * @fg_pen: Foreground pen number, 0-7 * @bg_pen: Background pen number, 0-7 * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_COLOR_FGBG_8. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.12 **/ CHAFA_TERM_SEQ_DEF(set_color_fgbg_8, SET_COLOR_FGBG_8, 2, 8fgbg, guint8, (CHAFA_TERM_SEQ_PFX, guint8 fg_pen, guint8 bg_pen)) /* --- Available in 1.14+ --- */ #undef CHAFA_TERM_SEQ_AVAILABILITY #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_14 /** * chafa_term_info_emit_reset_default_fg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_DEFAULT_FG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(reset_default_fg, RESET_DEFAULT_FG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_set_default_fg: * @term_info: A #ChafaTermInfo * @dest: String destination * @r: Red component (0-65535) * @g: Green component (0-65535) * @b: Blue component (0-65535) * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_DEFAULT_FG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(set_default_fg, SET_DEFAULT_FG, 3, u16hex, guint16, (CHAFA_TERM_SEQ_PFX, guint16 r, guint16 g, guint16 b)) /** * chafa_term_info_emit_query_default_fg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_QUERY_DEFAULT_FG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(query_default_fg, QUERY_DEFAULT_FG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_default_bg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_DEFAULT_BG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(reset_default_bg, RESET_DEFAULT_BG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_set_default_bg: * @term_info: A #ChafaTermInfo * @dest: String destination * @r: Red component (0-65535) * @g: Green component (0-65535) * @b: Blue component (0-65535) * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_DEFAULT_BG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(set_default_bg, SET_DEFAULT_BG, 3, u16hex, guint16, (CHAFA_TERM_SEQ_PFX, guint16 r, guint16 g, guint16 b)) /** * chafa_term_info_emit_query_default_bg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_QUERY_DEFAULT_BG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(query_default_bg, QUERY_DEFAULT_BG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_return_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RETURN_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(return_key, RETURN_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_backspace_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_BACKSPACE_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(backspace_key, BACKSPACE_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_tab_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_TAB_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(tab_key, TAB_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_tab_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_TAB_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(tab_shift_key, TAB_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_up_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_UP_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(up_key, UP_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_up_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_UP_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(up_ctrl_key, UP_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_up_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_UP_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(up_shift_key, UP_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_down_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DOWN_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(down_key, DOWN_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_down_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DOWN_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(down_ctrl_key, DOWN_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_down_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DOWN_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(down_shift_key, DOWN_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_left_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_LEFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(left_key, LEFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_left_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_LEFT_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(left_ctrl_key, LEFT_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_left_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_LEFT_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(left_shift_key, LEFT_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_right_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RIGHT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(right_key, RIGHT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_right_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RIGHT_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(right_ctrl_key, RIGHT_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_right_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RIGHT_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(right_shift_key, RIGHT_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_page_up_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_PAGE_UP_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(page_up_key, PAGE_UP_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_page_up_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_PAGE_UP_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(page_up_ctrl_key, PAGE_UP_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_page_up_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_PAGE_UP_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(page_up_shift_key, PAGE_UP_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_page_down_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_PAGE_DOWN_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(page_down_key, PAGE_DOWN_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_page_down_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_PAGE_DOWN_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(page_down_ctrl_key, PAGE_DOWN_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_page_down_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_PAGE_DOWN_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(page_down_shift_key, PAGE_DOWN_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_home_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_HOME_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(home_key, HOME_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_home_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_HOME_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(home_ctrl_key, HOME_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_home_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_HOME_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(home_shift_key, HOME_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(end_key, END_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(end_ctrl_key, END_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(end_shift_key, END_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_insert_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_INSERT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(insert_key, INSERT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_insert_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_INSERT_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(insert_ctrl_key, INSERT_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_insert_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_INSERT_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(insert_shift_key, INSERT_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_delete_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DELETE_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(delete_key, DELETE_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_delete_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DELETE_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(delete_ctrl_key, DELETE_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_delete_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DELETE_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(delete_shift_key, DELETE_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f1_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F1_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f1_key, F1_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f1_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F1_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f1_ctrl_key, F1_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f1_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F1_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f1_shift_key, F1_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f2_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F2_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f2_key, F2_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f2_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F2_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f2_ctrl_key, F2_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f2_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F2_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f2_shift_key, F2_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f3_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F3_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f3_key, F3_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f3_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F3_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f3_ctrl_key, F3_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f3_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F3_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f3_shift_key, F3_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f4_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F4_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f4_key, F4_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f4_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F4_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f4_ctrl_key, F4_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f4_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F4_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f4_shift_key, F4_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f5_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F5_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f5_key, F5_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f5_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F5_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f5_ctrl_key, F5_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f5_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F5_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f5_shift_key, F5_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f6_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F6_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f6_key, F6_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f6_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F6_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f6_ctrl_key, F6_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f6_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F6_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f6_shift_key, F6_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f7_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F7_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f7_key, F7_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f7_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F7_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f7_ctrl_key, F7_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f7_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F7_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f7_shift_key, F7_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f8_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F8_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f8_key, F8_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f8_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F8_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f8_ctrl_key, F8_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f8_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F8_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f8_shift_key, F8_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f9_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F9_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f9_key, F9_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f9_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F9_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f9_ctrl_key, F9_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f9_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F9_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f9_shift_key, F9_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f10_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F10_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f10_key, F10_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f10_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F10_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f10_ctrl_key, F10_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f10_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F10_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f10_shift_key, F10_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f11_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F11_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f11_key, F11_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f11_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F11_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f11_ctrl_key, F11_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f11_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F11_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f11_shift_key, F11_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f12_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F12_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f12_key, F12_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f12_ctrl_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F12_CTRL_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f12_ctrl_key, F12_CTRL_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_f12_shift_key: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_F12_SHIFT_KEY. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(f12_shift_key, F12_SHIFT_KEY, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_color_fg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_COLOR_FG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(reset_color_fg, RESET_COLOR_FG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_color_bg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_COLOR_BG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(reset_color_bg, RESET_COLOR_BG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_color_fgbg: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_COLOR_FGBG. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(reset_color_fgbg, RESET_COLOR_FGBG, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_reset_scrolling_rows: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESET_SCROLLING_ROWS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(reset_scrolling_rows, RESET_SCROLLING_ROWS, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_save_cursor_pos: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_SAVE_CURSOR_POS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(save_cursor_pos, SAVE_CURSOR_POS, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_restore_cursor_pos: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_RESTORE_CURSOR_POS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(restore_cursor_pos, RESTORE_CURSOR_POS, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_set_sixel_advance_down: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(set_sixel_advance_down, SET_SIXEL_ADVANCE_DOWN, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_set_sixel_advance_right: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_RIGHT. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(set_sixel_advance_right, SET_SIXEL_ADVANCE_RIGHT, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_enable_alt_screen: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_ENABLE_ALT_SCREEN. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(enable_alt_screen, ENABLE_ALT_SCREEN, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_disable_alt_screen: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_DISABLE_ALT_SCREEN. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(disable_alt_screen, DISABLE_ALT_SCREEN, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_begin_screen_passthrough: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_SCREEN_PASSTHROUGH. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Any control sequences between the beginning and end passthrough seqs * must be escaped by turning \033 into \033\033. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(begin_screen_passthrough, BEGIN_SCREEN_PASSTHROUGH, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_screen_passthrough: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_SCREEN_PASSTHROUGH. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Any control sequences between the beginning and end passthrough seqs * must be escaped by turning \033 into \033\033. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(end_screen_passthrough, END_SCREEN_PASSTHROUGH, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_begin_tmux_passthrough: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_TMUX_PASSTHROUGH. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Any control sequences between the beginning and end passthrough seqs * must be escaped by turning \033 into \033\033. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(begin_tmux_passthrough, BEGIN_TMUX_PASSTHROUGH, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_tmux_passthrough: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_TMUX_PASSTHROUGH. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Any control sequences between the beginning and end passthrough seqs * must be escaped by turning \033 into \033\033. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(end_tmux_passthrough, END_TMUX_PASSTHROUGH, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_begin_kitty_immediate_virt_image_v1: * @term_info: A #ChafaTermInfo * @dest: String destination * @bpp: Bits per pixel * @width_pixels: Image width in pixels * @height_pixels: Image height in pixels * @width_cells: Target width in cells * @height_cells: Target height in cells * @id: Image ID * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * @bpp must be set to either 24 for RGB data, 32 for RGBA, or 100 to embed a * PNG file. * * This sequence must be followed by zero or more paired sequences of * type #CHAFA_TERM_SEQ_BEGIN_KITTY_IMAGE_CHUNK and #CHAFA_TERM_SEQ_END_KITTY_IMAGE_CHUNK * with base-64 encoded image data between them. * * When the image data has been transferred, #CHAFA_TERM_SEQ_END_KITTY_IMAGE must * be emitted. * * Returns: Pointer to first byte after emitted string * * Since: 1.14 **/ CHAFA_TERM_SEQ_DEF(begin_kitty_immediate_virt_image_v1, BEGIN_KITTY_IMMEDIATE_VIRT_IMAGE_V1, 6, none, guint, (CHAFA_TERM_SEQ_PFX, guint bpp, guint width_pixels, guint height_pixels, guint width_cells, guint height_cells, guint id)) /* --- Available in 1.16+ --- */ #undef CHAFA_TERM_SEQ_AVAILABILITY #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_16 /** * chafa_term_info_emit_query_primary_device_attributes: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(query_primary_device_attributes, QUERY_PRIMARY_DEVICE_ATTRIBUTES, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_primary_device_attributes: * @term_info: A #ChafaTermInfo * @dest: String destination * @args: Pointer to array of attributes * @n_args: Number of attributes in array * * Prints the control sequence for #CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF_VARARGS(primary_device_attributes, PRIMARY_DEVICE_ATTRIBUTES, guint) /** * chafa_term_info_emit_query_text_area_size_cells: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_CELLS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(query_text_area_size_cells, QUERY_TEXT_AREA_SIZE_CELLS, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_text_area_size_cells: * @term_info: A #ChafaTermInfo * @dest: String destination * @height_cells: Text area height in cells * @width_cells: Text area width in cells * * Prints the control sequence for #CHAFA_TERM_SEQ_TEXT_AREA_SIZE_CELLS. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(text_area_size_cells, TEXT_AREA_SIZE_CELLS, 2, none, guint, (CHAFA_TERM_SEQ_PFX, guint height_cells, guint width_cells)) /** * chafa_term_info_emit_query_text_area_size_px: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_PX. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(query_text_area_size_px, QUERY_TEXT_AREA_SIZE_PX, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_text_area_size_px: * @term_info: A #ChafaTermInfo * @dest: String destination * @height_px: Text area height in pixels * @width_px: Text area width in pixels * * Prints the control sequence for #CHAFA_TERM_SEQ_TEXT_AREA_SIZE_PX. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(text_area_size_px, TEXT_AREA_SIZE_PX, 2, none, guint, (CHAFA_TERM_SEQ_PFX, guint height_px, guint width_px)) /** * chafa_term_info_emit_query_cell_size_px: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_QUERY_CELL_SIZE_PX. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(query_cell_size_px, QUERY_CELL_SIZE_PX, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_cell_size_px: * @term_info: A #ChafaTermInfo * @dest: String destination * @height_px: Cell height in pixels * @width_px: Cell width in pixels * * Prints the control sequence for #CHAFA_TERM_SEQ_CELL_SIZE_PX. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.16 **/ CHAFA_TERM_SEQ_DEF(cell_size_px, CELL_SIZE_PX, 2, none, guint, (CHAFA_TERM_SEQ_PFX, guint height_px, guint width_px)) /* --- Available in 1.18+ --- */ #undef CHAFA_TERM_SEQ_AVAILABILITY #define CHAFA_TERM_SEQ_AVAILABILITY CHAFA_AVAILABLE_IN_1_18 /** * chafa_term_info_emit_begin_hyperlink: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_HYPERLINK. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.18 **/ CHAFA_TERM_SEQ_DEF(begin_hyperlink, BEGIN_HYPERLINK, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_begin_hyperlink_anchor: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_BEGIN_HYPERLINK_ANCHOR. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.18 **/ CHAFA_TERM_SEQ_DEF(begin_hyperlink_anchor, BEGIN_HYPERLINK_ANCHOR, 0, none, char, (CHAFA_TERM_SEQ_PFX)) /** * chafa_term_info_emit_end_hyperlink: * @term_info: A #ChafaTermInfo * @dest: String destination * * Prints the control sequence for #CHAFA_TERM_SEQ_END_HYPERLINK. * * @dest must have enough space to hold * #CHAFA_TERM_SEQ_LENGTH_MAX bytes, even if the emitted sequence is * shorter. The output will not be zero-terminated. * * Returns: Pointer to first byte after emitted string * * Since: 1.18 **/ CHAFA_TERM_SEQ_DEF(end_hyperlink, END_HYPERLINK, 0, none, char, (CHAFA_TERM_SEQ_PFX)) #undef CHAFA_TERM_SEQ_AVAILABILITY #undef CHAFA_TERM_SEQ_PFX chafa-1.18.2/chafa/chafa-term-seq-doc-in.h000066400000000000000000000030371517447374300200460ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #define CHAFA_TERM_SEQ_DEF(name, NAME, n_args, arg_proc, arg_type, args) \ gchar *chafa_term_info_emit_##name args; #define CHAFA_TERM_SEQ_DEF_VARARGS(name, NAME, arg_type) \ gchar * chafa_term_info_emit_##name(const ChafaTermInfo *term_info, gchar *dest, arg_type *args, gint n_args); #include "chafa-term-seq-def.h" #undef CHAFA_TERM_SEQ_DEF #undef CHAFA_TERM_SEQ_DEF_VARARGS typedef enum { #define CHAFA_TERM_SEQ_DEF(name, NAME, n_args, arg_proc, arg_type, args) CHAFA_TERM_SEQ_##NAME, #define CHAFA_TERM_SEQ_DEF_VARARGS(name, NAME, arg_type) CHAFA_TERM_SEQ_##NAME, #include "chafa-term-seq-def.h" #undef CHAFA_TERM_SEQ_DEF #undef CHAFA_TERM_SEQ_DEF_VARARGS CHAFA_TERM_SEQ_MAX } ChafaTermSeq; chafa-1.18.2/chafa/chafa-util.c000066400000000000000000000160431517447374300161130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chafa.h" #include "internal/chafa-private.h" /** * SECTION:chafa-util * @title: Miscellaneous * @short_description: Potentially useful functions * * Miscellaneous functions that may be useful to Chafa users. **/ /** * chafa_calc_canvas_geometry: * @src_width: Width of source * @src_height: Height of source * @dest_width_inout: Inout location for width of destination * @dest_height_inout: Inout location for height of destination * @font_ratio: Target font's width to height ratio * @zoom: %TRUE to upscale image to fit maximum dimensions, %FALSE otherwise * @stretch: %TRUE to ignore aspect of source, %FALSE otherwise * * Calculates an optimal geometry for a #ChafaCanvas given the width and * height of an input image, maximum width and height of the canvas, font * ratio, zoom and stretch preferences. * * @src_width and @src_height must both be zero or greater. * * @dest_width_inout and @dest_height_inout must point to integers * containing the maximum dimensions of the canvas in character cells. * These will be replaced by the calculated values, which may be zero if * one of the input dimensions is zero. If one or both of the input * parameters is negative, they will be treated as unspecified and * calculated based on the remaining parameters and aspect ratio. * * @font_ratio is the font's width divided by its height. 0.5 is a typical * value. **/ void chafa_calc_canvas_geometry (gint src_width, gint src_height, gint *dest_width_inout, gint *dest_height_inout, gfloat font_ratio, gboolean zoom, gboolean stretch) { gint dest_width = -1, dest_height = -1; gdouble font_ratio_dbl = (gdouble) font_ratio; g_return_if_fail (src_width >= 0); g_return_if_fail (src_height >= 0); g_return_if_fail (font_ratio > 0.0f); if (dest_width_inout) dest_width = *dest_width_inout; if (dest_height_inout) dest_height = *dest_height_inout; /* If any dimension is explicitly set to zero, width and height will * both be zero. */ if (src_width == 0 || src_height == 0 || dest_width == 0 || dest_height == 0) { if (dest_width_inout) *dest_width_inout = 0; if (dest_height_inout) *dest_height_inout = 0; return; } /* If both output dimensions are unspecified, make them 1/8 of their * corresponding input dimensions, rounding up and accounting * for font ratio. Both dimensions will be >= 1. */ if (dest_width < 0 && dest_height < 0) { if (dest_width_inout) { *dest_width_inout = (src_width + 7) / 8; *dest_width_inout = MAX (*dest_width_inout, 1); } if (dest_height_inout) { *dest_height_inout = ((src_height + 7) / 8) * font_ratio_dbl + 0.5; *dest_height_inout = MAX (*dest_height_inout, 1); } return; } if (!zoom) { dest_width = MIN (dest_width, src_width); dest_height = MIN (dest_height, src_height); } if (!stretch || dest_width < 0 || dest_height < 0) { gdouble src_aspect; gdouble dest_aspect; src_aspect = src_width / (gdouble) src_height; dest_aspect = (dest_width / (gdouble) dest_height) * font_ratio_dbl; if (dest_width < 1) { dest_width = ceil (dest_height * (src_aspect / font_ratio_dbl)); } else if (dest_height < 1) { dest_height = ceil ((dest_width / src_aspect) * font_ratio_dbl); } else if (src_aspect > dest_aspect) { dest_height = ceil (dest_width * (font_ratio_dbl / src_aspect)); } else { dest_width = ceil (dest_height * (src_aspect / font_ratio_dbl)); } } /* Clamp dest dimensions */ dest_width = MAX (dest_width, 1); dest_height = MAX (dest_height, 1); if (dest_width_inout && *dest_width_inout > 0) dest_width = MIN (dest_width, *dest_width_inout); if (dest_height_inout && *dest_height_inout > 0) dest_height = MIN (dest_height, *dest_height_inout); if (dest_width_inout) *dest_width_inout = dest_width; if (dest_height_inout) *dest_height_inout = dest_height; } /** * chafa_free_gstring_array: * @gsa: Pointer to a %NULL-terminated array of pointers to #GString * * Frees an array of #GString. If @gsa is %NULL, simply returns without * doing anything. **/ void chafa_free_gstring_array (GString **gsa) { gint i; if (!gsa) return; for (i = 0; gsa [i]; i++) g_string_free (gsa [i], TRUE); g_free (gsa); } /* --- Internal; not part of public API --- */ static void fill_matrix_r (gint *matrix, gint matrix_size, gint sub_size, gint x, gint y, gint value, gint step) { gint half; if (sub_size == 1) { matrix [x + y * matrix_size] = value; return; } half = sub_size / 2; fill_matrix_r (matrix, matrix_size, half, x, y, value, step * 4); fill_matrix_r (matrix, matrix_size, half, x + half, y + half, value + step, step * 4); fill_matrix_r (matrix, matrix_size, half, x + half, y, value + step * 2, step * 4); fill_matrix_r (matrix, matrix_size, half, x, y + half, value + step * 3, step * 4); } static void fill_matrix (gint *matrix, gint matrix_size, gfloat magnitude) { gint maxval = matrix_size * matrix_size; gfloat maxval_f = maxval; gint i; fill_matrix_r (matrix, matrix_size, matrix_size, 0, 0, 0, 1); /* Recenter around 0 and scale so magnitude == 1.0 => -128..127 */ for (i = 0; i < matrix_size * matrix_size; i++) { matrix [i] = ((gfloat) matrix [i] - maxval_f / 2.0f) * (256.0f / maxval_f) * magnitude + 0.5f; } } gint * chafa_gen_bayer_matrix (gint matrix_size, gfloat magnitude) { gint *matrix; g_assert (matrix_size == 2 || matrix_size == 4 || matrix_size == 8 || matrix_size == 16); matrix = g_malloc (matrix_size * matrix_size * sizeof (gint)); fill_matrix (matrix, matrix_size, magnitude); return matrix; } chafa-1.18.2/chafa/chafa-util.h000066400000000000000000000030561517447374300161200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_UTIL_H__ #define __CHAFA_UTIL_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif G_BEGIN_DECLS /* Miscellaneous functions */ CHAFA_AVAILABLE_IN_ALL void chafa_calc_canvas_geometry (gint src_width, gint src_height, gint *dest_width_inout, gint *dest_height_inout, gfloat font_ratio, gboolean zoom, gboolean stretch); CHAFA_AVAILABLE_IN_1_14 void chafa_free_gstring_array (GString **gsa); G_END_DECLS #endif /* __CHAFA_UTIL_H__ */ chafa-1.18.2/chafa/chafa-version-macros.h000066400000000000000000000227531517447374300201170ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_VERSION_MACROS_H__ #define __CHAFA_VERSION_MACROS_H__ #if !defined (__CHAFA_H_INSIDE__) && !defined (CHAFA_COMPILATION) # error "Only can be included directly." #endif /* Our current version is defined here */ #include G_BEGIN_DECLS /* Exported symbol versioning/visibility. Similar to the versioning macros * used by GLib. */ #define CHAFA_VERSION_1_0 (G_ENCODE_VERSION (1, 0)) #define CHAFA_VERSION_1_2 (G_ENCODE_VERSION (1, 2)) #define CHAFA_VERSION_1_4 (G_ENCODE_VERSION (1, 4)) #define CHAFA_VERSION_1_6 (G_ENCODE_VERSION (1, 6)) #define CHAFA_VERSION_1_8 (G_ENCODE_VERSION (1, 8)) #define CHAFA_VERSION_1_10 (G_ENCODE_VERSION (1, 10)) #define CHAFA_VERSION_1_12 (G_ENCODE_VERSION (1, 12)) #define CHAFA_VERSION_1_14 (G_ENCODE_VERSION (1, 14)) #define CHAFA_VERSION_1_16 (G_ENCODE_VERSION (1, 16)) #define CHAFA_VERSION_1_18 (G_ENCODE_VERSION (1, 18)) /* Evaluates to the current stable version; for development cycles, * this means the next stable target. */ #if (CHAFA_MINOR_VERSION % 2) #define CHAFA_VERSION_CUR_STABLE (G_ENCODE_VERSION (CHAFA_MAJOR_VERSION, CHAFA_MINOR_VERSION + 1)) #else #define CHAFA_VERSION_CUR_STABLE (G_ENCODE_VERSION (CHAFA_MAJOR_VERSION, CHAFA_MINOR_VERSION)) #endif /* Evaluates to the previous stable version */ #if (CHAFA_MINOR_VERSION % 2) #define CHAFA_VERSION_PREV_STABLE (G_ENCODE_VERSION (CHAFA_MAJOR_VERSION, CHAFA_MINOR_VERSION - 1)) #else #define CHAFA_VERSION_PREV_STABLE (G_ENCODE_VERSION (CHAFA_MAJOR_VERSION, CHAFA_MINOR_VERSION - 2)) #endif /** * CHAFA_VERSION_MIN_REQUIRED: * * A macro that can be defined by the user prior to including * the chafa.h header. * The definition should be one of the predefined Chafa version * macros: %CHAFA_VERSION_1_0, %CHAFA_VERSION_1_2,... * * This macro defines the earliest version of Chafa that the package is * required to be able to compile against. * * If the compiler is configured to warn about the use of deprecated * functions, then using functions that were deprecated in version * %CHAFA_VERSION_MIN_REQUIRED or earlier will cause warnings (but * using functions deprecated in later releases will not). * * Since: 1.2 */ /* Make sure all exportable symbols are made visible, even * deprecated ones. */ #ifdef CHAFA_COMPILATION # define CHAFA_VERSION_MIN_REQUIRED (CHAFA_VERSION_1_0) #endif /* If the package sets CHAFA_VERSION_MIN_REQUIRED to some future * CHAFA_VERSION_X_Y value that we don't know about, it will compare as * 0 in preprocessor tests. */ #ifndef CHAFA_VERSION_MIN_REQUIRED # define CHAFA_VERSION_MIN_REQUIRED (CHAFA_VERSION_CUR_STABLE) #elif CHAFA_VERSION_MIN_REQUIRED == 0 # undef CHAFA_VERSION_MIN_REQUIRED # define CHAFA_VERSION_MIN_REQUIRED (CHAFA_VERSION_CUR_STABLE + 2) #endif /** * CHAFA_VERSION_MAX_ALLOWED: * * A macro that can be defined by the user prior to including * the chafa.h header. * The definition should be one of the predefined Chafa version * macros: %CHAFA_VERSION_1_0, %CHAFA_VERSION_1_2,... * * This macro defines the latest version of the Chafa API that the * package is allowed to make use of. * * If the compiler is configured to warn about the use of deprecated * functions, then using functions added after version * %CHAFA_VERSION_MAX_ALLOWED will cause warnings. * * This should normally be set to the same value as * %CHAFA_VERSION_MIN_REQUIRED. * * Since: 1.2 */ #if !defined (CHAFA_VERSION_MAX_ALLOWED) || (CHAFA_VERSION_MAX_ALLOWED == 0) # undef CHAFA_VERSION_MAX_ALLOWED # define CHAFA_VERSION_MAX_ALLOWED (CHAFA_VERSION_CUR_STABLE) #endif /* Sanity checks */ #if CHAFA_VERSION_MIN_REQUIRED > CHAFA_VERSION_CUR_STABLE #error "CHAFA_VERSION_MIN_REQUIRED must be <= CHAFA_VERSION_CUR_STABLE" #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_MIN_REQUIRED #error "CHAFA_VERSION_MAX_ALLOWED must be >= CHAFA_VERSION_MIN_REQUIRED" #endif #if CHAFA_VERSION_MIN_REQUIRED < CHAFA_VERSION_1_0 #error "CHAFA_VERSION_MIN_REQUIRED must be >= CHAFA_VERSION_1_0" #endif #ifndef _CHAFA_EXTERN # define _CHAFA_EXTERN extern #endif #define CHAFA_AVAILABLE_IN_ALL _CHAFA_EXTERN #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_2 # define CHAFA_DEPRECATED_IN_1_2 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_2_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_2 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_2_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_2 # define CHAFA_AVAILABLE_IN_1_2 G_UNAVAILABLE(1, 2) #else # define CHAFA_AVAILABLE_IN_1_2 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_4 # define CHAFA_DEPRECATED_IN_1_4 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_4_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_4 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_4_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_4 # define CHAFA_AVAILABLE_IN_1_4 G_UNAVAILABLE(1, 4) #else # define CHAFA_AVAILABLE_IN_1_4 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_6 # define CHAFA_DEPRECATED_IN_1_6 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_6_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_6 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_6_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_6 # define CHAFA_AVAILABLE_IN_1_6 G_UNAVAILABLE(1, 6) #else # define CHAFA_AVAILABLE_IN_1_6 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_8 # define CHAFA_DEPRECATED_IN_1_8 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_8_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_8 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_8_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_8 # define CHAFA_AVAILABLE_IN_1_8 G_UNAVAILABLE(1, 8) #else # define CHAFA_AVAILABLE_IN_1_8 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_10 # define CHAFA_DEPRECATED_IN_1_10 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_10_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_10 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_10_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_10 # define CHAFA_AVAILABLE_IN_1_10 G_UNAVAILABLE(1, 10) #else # define CHAFA_AVAILABLE_IN_1_10 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_12 # define CHAFA_DEPRECATED_IN_1_12 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_12_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_12 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_12_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_12 # define CHAFA_AVAILABLE_IN_1_12 G_UNAVAILABLE(1, 12) #else # define CHAFA_AVAILABLE_IN_1_12 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_14 # define CHAFA_DEPRECATED_IN_1_14 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_14_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_14 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_14_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_14 # define CHAFA_AVAILABLE_IN_1_14 G_UNAVAILABLE(1, 14) #else # define CHAFA_AVAILABLE_IN_1_14 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_16 # define CHAFA_DEPRECATED_IN_1_16 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_16_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_16 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_16_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_16 # define CHAFA_AVAILABLE_IN_1_16 G_UNAVAILABLE(1, 16) #else # define CHAFA_AVAILABLE_IN_1_16 _CHAFA_EXTERN #endif #if CHAFA_VERSION_MIN_REQUIRED >= CHAFA_VERSION_1_18 # define CHAFA_DEPRECATED_IN_1_18 G_DEPRECATED # define CHAFA_DEPRECATED_IN_1_18_FOR(f) G_DEPRECATED_FOR(f) #else # define CHAFA_DEPRECATED_IN_1_18 _CHAFA_EXTERN # define CHAFA_DEPRECATED_IN_1_18_FOR(f) _CHAFA_EXTERN #endif #if CHAFA_VERSION_MAX_ALLOWED < CHAFA_VERSION_1_18 # define CHAFA_AVAILABLE_IN_1_18 G_UNAVAILABLE(1, 18) #else # define CHAFA_AVAILABLE_IN_1_18 _CHAFA_EXTERN #endif G_END_DECLS #endif /* __CHAFA_VERSION_MACROS_H__ */ chafa-1.18.2/chafa/chafa.h000066400000000000000000000025761517447374300151530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_H__ #define __CHAFA_H__ #define __CHAFA_H_INSIDE__ #include G_BEGIN_DECLS /* Version macros go before everything else */ #include #include #include #include #include #include #include #include #include #include #include #include G_END_DECLS #undef __CHAFA_H_INSIDE__ #endif /* __CHAFA_H__ */ chafa-1.18.2/chafa/chafaconfig.h.in000066400000000000000000000005371517447374300167410ustar00rootroot00000000000000/* chafaconfig.h * * This is a generated file. Please modify 'chafaconfig.h.in'. */ #ifndef __CHAFACONFIG_H__ #define __CHAFACONFIG_H__ G_BEGIN_DECLS #define CHAFA_MAJOR_VERSION @CHAFA_MAJOR_VERSION@ #define CHAFA_MINOR_VERSION @CHAFA_MINOR_VERSION@ #define CHAFA_MICRO_VERSION @CHAFA_MICRO_VERSION@ G_END_DECLS #endif /* __CHAFACONFIG_H__ */ chafa-1.18.2/chafa/internal/000077500000000000000000000000001517447374300155425ustar00rootroot00000000000000chafa-1.18.2/chafa/internal/Makefile.am000066400000000000000000000052171517447374300176030ustar00rootroot00000000000000SUBDIRS = smolscale ## --- Library --- noinst_LTLIBRARIES = libchafa-internal.la libchafa_internal_la_CFLAGS = $(LIBCHAFA_CFLAGS) $(GLIB_CFLAGS) -DCHAFA_COMPILATION libchafa_internal_la_LDFLAGS = $(LIBCHAFA_LDFLAGS) libchafa_internal_la_LIBADD = $(GLIB_LIBS) smolscale/libsmolscale.la -lm libchafa_internal_la_SOURCES = \ chafa-base64.c \ chafa-base64.h \ chafa-batch.c \ chafa-batch.h \ chafa-bitfield.h \ chafa-canvas-internal.h \ chafa-canvas-printer.c \ chafa-canvas-printer.h \ chafa-color.c \ chafa-color.h \ chafa-color-hash.c \ chafa-color-hash.h \ chafa-color-table.c \ chafa-color-table.h \ chafa-dither.c \ chafa-dither.h \ chafa-indexed-image.c \ chafa-indexed-image.h \ chafa-iterm2-canvas.c \ chafa-iterm2-canvas.h \ chafa-kitty-canvas.c \ chafa-kitty-canvas.h \ chafa-math-util.c \ chafa-math-util.h \ chafa-noise.c \ chafa-noise.h \ chafa-palette.c \ chafa-palette.h \ chafa-passthrough-encoder.c \ chafa-passthrough-encoder.h \ chafa-pca.c \ chafa-pca.h \ chafa-pixops.c \ chafa-pixops.h \ chafa-private.h \ chafa-sixel-canvas.c \ chafa-sixel-canvas.h \ chafa-string-util.c \ chafa-string-util.h \ chafa-symbols.c \ chafa-symbols-ascii.h \ chafa-symbols-block.h \ chafa-symbols-kana.h \ chafa-symbols-latin.h \ chafa-symbols-misc-narrow.h \ chafa-vector.h \ chafa-work-cell.c \ chafa-work-cell.h if HAVE_MMX_INTRINSICS noinst_LTLIBRARIES += libchafa-mmx.la libchafa_internal_la_LIBADD += libchafa-mmx.la libchafa_mmx_la_SOURCES = chafa-mmx.c libchafa_mmx_la_CFLAGS = $(LIBCHAFA_CFLAGS) $(GLIB_CFLAGS) -mmmx -DCHAFA_COMPILATION libchafa_mmx_la_LDFLAGS = $(LIBCHAFA_LDFLAGS) endif if HAVE_SSE41_INTRINSICS noinst_LTLIBRARIES += libchafa-sse41.la libchafa_internal_la_LIBADD += libchafa-sse41.la libchafa_sse41_la_SOURCES = chafa-sse41.c libchafa_sse41_la_CFLAGS = $(LIBCHAFA_CFLAGS) $(GLIB_CFLAGS) -msse4.1 -DCHAFA_COMPILATION libchafa_sse41_la_LDFLAGS = $(LIBCHAFA_LDFLAGS) endif if HAVE_POPCNT_INTRINSICS noinst_LTLIBRARIES += libchafa-popcnt.la libchafa_internal_la_LIBADD += libchafa-popcnt.la libchafa_popcnt_la_SOURCES = chafa-popcnt.c libchafa_popcnt_la_CFLAGS = $(LIBCHAFA_CFLAGS) $(GLIB_CFLAGS) -mpopcnt -DCHAFA_COMPILATION libchafa_popcnt_la_LDFLAGS = $(LIBCHAFA_LDFLAGS) endif if HAVE_AVX2_INTRINSICS noinst_LTLIBRARIES += libchafa-avx2.la libchafa_internal_la_LIBADD += libchafa-avx2.la libchafa_avx2_la_SOURCES = chafa-avx2.c libchafa_avx2_la_CFLAGS = $(LIBCHAFA_CFLAGS) $(GLIB_CFLAGS) -mavx2 -DCHAFA_COMPILATION libchafa_avx2_la_LDFLAGS = $(LIBCHAFA_LDFLAGS) endif ## --- General --- ## Include $(top_builddir)/chafa to get generated chafaconfig.h. AM_CPPFLAGS = \ -I$(top_srcdir)/chafa \ -I$(top_builddir)/chafa chafa-1.18.2/chafa/internal/chafa-avx2.c000066400000000000000000000150501517447374300176270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include "chafa.h" #include "internal/chafa-private.h" /* _mm_extract_epi64() (pextrq) is not available in 32-bit mode. Work around * it. This needs to be a macro, as the compiler expects an integer constant * for n. */ #if defined __x86_64__ && !defined __ILP32__ # define extract_128_epi64(i, n) _mm_extract_epi64 ((i), (n)) #else # define extract_128_epi64(i, n) \ ((((guint64) _mm_extract_epi32 ((i), (n) * 2 + 1)) << 32) \ | _mm_extract_epi32 ((i), (n) * 2)) #endif gint chafa_calc_cell_error_avx2 (const ChafaPixel *pixels, const ChafaColorPair *color_pair, const guint32 *sym_mask_u32) { __m256i err_8x_u32 = { 0 }; __m128i err_4x_u32; __m128i fg_4x_u32, bg_4x_u32; __m256i fg_4x_u64, bg_4x_u64; const __m128i *pixels_4x_p = (const __m128i *) pixels; const __m128i *sym_mask_4x_p = (const __m128i *) sym_mask_u32; gint i; fg_4x_u32 = _mm_set1_epi32 (chafa_color8_to_u32 (color_pair->colors [CHAFA_COLOR_PAIR_FG])); fg_4x_u64 = _mm256_cvtepu8_epi16 (fg_4x_u32); bg_4x_u32 = _mm_set1_epi32 (chafa_color8_to_u32 (color_pair->colors [CHAFA_COLOR_PAIR_BG])); bg_4x_u64 = _mm256_cvtepu8_epi16 (bg_4x_u32); for (i = 0; i < CHAFA_SYMBOL_N_PIXELS / 4; i++) { __m128i pixels_4x, sym_mask_4x; __m256i p0, m0, fg0, bg0, d0; pixels_4x = _mm_loadu_si128 (pixels_4x_p++); sym_mask_4x = _mm_loadu_si128 (sym_mask_4x_p++); p0 = _mm256_cvtepu8_epi16 (pixels_4x); m0 = _mm256_cvtepi8_epi16 (sym_mask_4x); fg0 = _mm256_and_si256 (m0, _mm256_sub_epi16 (fg_4x_u64, p0)); bg0 = _mm256_andnot_si256 (m0, _mm256_sub_epi16 (bg_4x_u64, p0)); d0 = _mm256_or_si256 (fg0, bg0); d0 = _mm256_madd_epi16 (d0, d0); err_8x_u32 = _mm256_add_epi32 (err_8x_u32, d0); } err_4x_u32 = _mm_add_epi32 (_mm256_extracti128_si256 (err_8x_u32, 0), _mm256_extracti128_si256 (err_8x_u32, 1)); err_4x_u32 = _mm_hadd_epi32 (err_4x_u32, err_4x_u32); err_4x_u32 = _mm_hadd_epi32 (err_4x_u32, err_4x_u32); return _mm_extract_epi32 (err_4x_u32, 0); } void chafa_extract_cell_mean_colors_avx2 (const ChafaPixel *pixels, ChafaColorAccum *accums_out, const guint32 *sym_mask_u32) { const __m128i *pixels_4x_p = (const __m128i *) pixels; const __m128i *sym_mask_4x_p = (const __m128i *) sym_mask_u32; __m256i accum_fg = { 0 }; __m256i accum_bg = { 0 }; __m128i accum_fg_128; __m128i accum_bg_128; guint64 accums_u64 [2]; gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS / 4; i++) { __m128i pixels_4x, sym_mask_4x; pixels_4x = _mm_loadu_si128 (pixels_4x_p++); sym_mask_4x = _mm_loadu_si128 (sym_mask_4x_p++); accum_fg = _mm256_add_epi16 (accum_fg, _mm256_cvtepu8_epi16 (_mm_and_si128 (sym_mask_4x, pixels_4x))); accum_bg = _mm256_add_epi16 (accum_bg, _mm256_cvtepu8_epi16 (_mm_andnot_si128 (sym_mask_4x, pixels_4x))); } accum_bg_128 = _mm_add_epi16 (_mm256_extracti128_si256 (accum_bg, 0), _mm256_extracti128_si256 (accum_bg, 1)); accums_u64 [0] = extract_128_epi64 (accum_bg_128, 0) + extract_128_epi64 (accum_bg_128, 1); accum_fg_128 = _mm_add_epi16 (_mm256_extracti128_si256 (accum_fg, 0), _mm256_extracti128_si256 (accum_fg, 1)); accums_u64 [1] = extract_128_epi64 (accum_fg_128, 0) + extract_128_epi64 (accum_fg_128, 1); memcpy (accums_out, accums_u64, 2 * sizeof (guint64)); } /* 32768 divided by index. Divide by zero is defined as zero. */ static const guint16 invdiv16 [257] = { 0, 32768, 16384, 10922, 8192, 6553, 5461, 4681, 4096, 3640, 3276, 2978, 2730, 2520, 2340, 2184, 2048, 1927, 1820, 1724, 1638, 1560, 1489, 1424, 1365, 1310, 1260, 1213, 1170, 1129, 1092, 1057, 1024, 992, 963, 936, 910, 885, 862, 840, 819, 799, 780, 762, 744, 728, 712, 697, 682, 668, 655, 642, 630, 618, 606, 595, 585, 574, 564, 555, 546, 537, 528, 520, 512, 504, 496, 489, 481, 474, 468, 461, 455, 448, 442, 436, 431, 425, 420, 414, 409, 404, 399, 394, 390, 385, 381, 376, 372, 368, 364, 360, 356, 352, 348, 344, 341, 337, 334, 330, 327, 324, 321, 318, 315, 312, 309, 306, 303, 300, 297, 295, 292, 289, 287, 284, 282, 280, 277, 275, 273, 270, 268, 266, 264, 262, 260, 258, 256, 254, 252, 250, 248, 246, 244, 242, 240, 239, 237, 235, 234, 232, 230, 229, 227, 225, 224, 222, 221, 219, 218, 217, 215, 214, 212, 211, 210, 208, 207, 206, 204, 203, 202, 201, 199, 198, 197, 196, 195, 193, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 168, 167, 166, 165, 164, 163, 163, 162, 161, 160, 159, 159, 158, 157, 156, 156, 155, 154, 153, 153, 152, 151, 151, 150, 149, 148, 148, 147, 146, 146, 145, 144, 144, 143, 143, 142, 141, 141, 140, 140, 139, 138, 138, 137, 137, 136, 135, 135, 134, 134, 133, 133, 132, 132, 131, 131, 130, 130, 129, 129, 128, 128 }; /* Divisor must be in the range [0..256] inclusive. */ void chafa_color_accum_div_scalar_avx2 (ChafaColorAccum *accum, guint16 divisor) { __m128i accum_128, divisor_128; guint64 accum_u64; /* Not using _mm_loadu_si64() here because it's not available on * older versions of GCC. The opcode is the same. */ accum_128 = _mm_loadl_epi64 ((const __m128i *) accum); divisor_128 = _mm_set1_epi16 (invdiv16 [divisor]); accum_128 = _mm_mulhrs_epi16 (accum_128, divisor_128); accum_u64 = extract_128_epi64 (accum_128, 0); memcpy (accum, &accum_u64, sizeof (guint64)); } chafa-1.18.2/chafa/internal/chafa-base64.c000066400000000000000000000063611517447374300200400ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include "chafa.h" #include "internal/chafa-base64.h" static const gchar base64_dict [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; void chafa_base64_init (ChafaBase64 *base64) { memset (base64, 0, sizeof (*base64)); } void chafa_base64_deinit (ChafaBase64 *base64) { memset (base64, 0, sizeof (*base64)); base64->buf_len = -1; } static void encode_3_bytes (GString *gs_out, guint32 bytes) { g_string_append_c (gs_out, base64_dict [(bytes >> (3 * 6)) & 0x3f]); g_string_append_c (gs_out, base64_dict [(bytes >> (2 * 6)) & 0x3f]); g_string_append_c (gs_out, base64_dict [(bytes >> (1 * 6)) & 0x3f]); g_string_append_c (gs_out, base64_dict [bytes & 0x3f]); } void chafa_base64_encode (ChafaBase64 *base64, GString *gs_out, gconstpointer in, gsize in_len) { const guint8 *in_u8 = in; const guint8 *end_u8 = in_u8 + in_len; guint32 r; if (base64->buf_len + in_len < 3) { memcpy (base64->buf + base64->buf_len, in_u8, in_len); base64->buf_len += in_len; return; } if (base64->buf_len == 1) { r = (base64->buf [0] << 16) | (in_u8 [0] << 8) | in_u8 [1]; in_u8 += 2; encode_3_bytes (gs_out, r); } else if (base64->buf_len == 2) { r = (base64->buf [0] << 16) | (base64->buf [1] << 8) | in_u8 [0]; in_u8++; encode_3_bytes (gs_out, r); } base64->buf_len = 0; while (end_u8 - in_u8 >= 3) { r = (in_u8 [0] << 16) | (in_u8 [1] << 8) | in_u8 [2]; encode_3_bytes (gs_out, r); in_u8 += 3; } while (end_u8 - in_u8 > 0) { base64->buf [base64->buf_len++] = *(in_u8++); } } void chafa_base64_encode_end (ChafaBase64 *base64, GString *gs_out) { if (base64->buf_len == 1) { g_string_append_c (gs_out, base64_dict [base64->buf [0] >> 2]); g_string_append_c (gs_out, base64_dict [(base64->buf [0] << 4) & 0x30]); g_string_append (gs_out, "=="); } else if (base64->buf_len == 2) { g_string_append_c (gs_out, base64_dict [base64->buf [0] >> 2]); g_string_append_c (gs_out, base64_dict [((base64->buf [0] << 4) | (base64->buf [1] >> 4)) & 0x3f]); g_string_append_c (gs_out, base64_dict [(base64->buf [1] << 2) & 0x3c]); g_string_append_c (gs_out, '='); } base64->buf_len = 0; } chafa-1.18.2/chafa/internal/chafa-base64.h000066400000000000000000000026731517447374300200470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_BASE64_H__ #define __CHAFA_BASE64_H__ #include #include "chafa.h" G_BEGIN_DECLS typedef struct { /* We turn 3-byte groups into 4-character base64 groups, so we * may need to buffer up to 2 bytes between batches */ guint8 buf [2]; gint buf_len; } ChafaBase64; void chafa_base64_init (ChafaBase64 *base64); void chafa_base64_deinit (ChafaBase64 *base64); void chafa_base64_encode (ChafaBase64 *base64, GString *gs_out, gconstpointer in, gsize in_len); void chafa_base64_encode_end (ChafaBase64 *base64, GString *gs_out); G_END_DECLS #endif /* __CHAFA_BASE64_H__ */ chafa-1.18.2/chafa/internal/chafa-batch.c000066400000000000000000000122561517447374300200350ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include "chafa.h" #include "internal/chafa-batch.h" static gint chafa_batch_n_threads_global; static gint allocate_threads (gint max_threads, gint n_batches) { gint prev_n_threads; gint n_threads; /* GThreadPool supports sharing threads between pools, but there is no * mechanism to manage the global thread count. If the batch API is being * called from multiple threads, we risk creating N * M workers, which * can result in hundreds of threads. * * Therefore, we maintain a global count of active threads and allocate * each caller's allotment from that. The minimum allocation is 1 thread, * in which case the operation is performed in the calling thread. Single- * threaded tasks are allowed to overshoot the maximum, so maximum * concurrency will be N + M - 1, where N is the number of calling threads * and M is the requisition from chafa_get_n_actual_threads(). For typical * workloads, average concurrency will likely be close to M. */ prev_n_threads = 0; n_threads = MIN (max_threads, n_batches); /* Geometric backoff: The first iteration adds to the global, subsequent * iterations subtract until we're happy. */ for (;;) { gint next_n_global = n_threads + g_atomic_int_add (&chafa_batch_n_threads_global, n_threads - prev_n_threads); if (next_n_global <= max_threads || n_threads == 1) break; prev_n_threads = n_threads; n_threads /= 2; } return n_threads; } static void deallocate_threads (gint n_threads) { g_atomic_int_add (&chafa_batch_n_threads_global, -n_threads); } void chafa_process_batches (gpointer ctx, GFunc batch_func, GFunc post_func, gint n_rows, gint n_batches, gint batch_unit) { GThreadPool *thread_pool = NULL; ChafaBatchInfo *batches; gint max_threads; gint n_threads; gint n_units; gfloat units_per_batch; gfloat next_unit_ofs_f = .0f; gint unit_ofs [2] = { 0, 0 }; gint i; g_assert (n_batches >= 1); g_assert (batch_unit >= 1); if (n_rows < 1) return; max_threads = chafa_get_n_actual_threads (); n_threads = allocate_threads (max_threads, n_batches); n_units = (n_rows + batch_unit - 1) / batch_unit; units_per_batch = (gfloat) n_units / (gfloat) n_batches; units_per_batch = MAX (units_per_batch, 1.0f); batches = g_new0 (ChafaBatchInfo, n_batches); if (n_threads >= 2) { thread_pool = g_thread_pool_new (batch_func, (gpointer) ctx, n_threads, FALSE, NULL); } /* Divide work up into batches that are multiples of batch_unit, except * for the last one (if n_rows is not itself a multiple) */ for (i = 0; i < n_batches; ) { ChafaBatchInfo *batch; gint row_ofs [2]; do { next_unit_ofs_f += units_per_batch; unit_ofs [1] = next_unit_ofs_f; } while (unit_ofs [0] == unit_ofs [1]); row_ofs [0] = unit_ofs [0] * batch_unit; row_ofs [1] = unit_ofs [1] * batch_unit; if (i == n_batches - 1 || row_ofs [1] > n_rows) row_ofs [1] = n_rows; if (row_ofs [0] >= row_ofs [1]) { /* Save the number of batches actually produced to use in * post_func loop later. */ n_batches = i; break; } batch = &batches [i++]; batch->first_row = row_ofs [0]; batch->n_rows = row_ofs [1] - row_ofs [0]; #if 0 g_printerr ("Batch %d: %04d rows\n", i, batch->n_rows); #endif if (n_threads >= 2) { g_thread_pool_push (thread_pool, batch, NULL); } else { batch_func (batch, ctx); } unit_ofs [0] = unit_ofs [1]; } if (n_threads >= 2) { /* Wait for threads to finish */ g_thread_pool_free (thread_pool, FALSE, TRUE); } if (post_func) { for (i = 0; i < n_batches; i++) { ((void (*)(ChafaBatchInfo *, gpointer)) post_func) (&batches [i], ctx); } } g_free (batches); deallocate_threads (n_threads); } chafa-1.18.2/chafa/internal/chafa-batch.h000066400000000000000000000023411517447374300200340ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_BATCH_H__ #define __CHAFA_BATCH_H__ #include G_BEGIN_DECLS typedef struct { gint first_row; gint n_rows; gpointer ret_p; gint ret_n; } ChafaBatchInfo; void chafa_process_batches (gpointer ctx, GFunc batch_func, GFunc post_func, gint n_rows, gint n_batches, gint batch_unit); G_END_DECLS #endif /* __CHAFA_BATCH_H__ */ chafa-1.18.2/chafa/internal/chafa-bitfield.h000066400000000000000000000042201517447374300205330ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_BITFIELD_H__ #define __CHAFA_BITFIELD_H__ #include #include G_BEGIN_DECLS typedef struct { guint32 *bits; guint n_bits; } ChafaBitfield; static inline void chafa_bitfield_init (ChafaBitfield *bitfield, guint n_bits) { bitfield->n_bits = n_bits; bitfield->bits = g_malloc0 ((n_bits + 31) / 8); } static inline void chafa_bitfield_deinit (ChafaBitfield *bitfield) { g_free (bitfield->bits); bitfield->n_bits = 0; bitfield->bits = NULL; } static inline void chafa_bitfield_clear (ChafaBitfield *bitfield) { memset (bitfield->bits, 0, (bitfield->n_bits + 31) / 8); } static inline gboolean chafa_bitfield_get_bit (const ChafaBitfield *bitfield, guint nth) { gint index; gint shift; g_return_val_if_fail (nth < bitfield->n_bits, FALSE); index = (nth / 32); shift = (nth % 32); return (bitfield->bits [index] >> shift) & 1U; } static inline void chafa_bitfield_set_bit (ChafaBitfield *bitfield, guint nth, gboolean value) { gint index; gint shift; guint32 v32; g_return_if_fail (nth < bitfield->n_bits); index = (nth / 32); shift = (nth % 32); v32 = (guint32) !!value; bitfield->bits [index] = (bitfield->bits [index] & ~(1UL << shift)) | (v32 << shift); } G_END_DECLS #endif /* __CHAFA_BITFIELD_H__ */ chafa-1.18.2/chafa/internal/chafa-canvas-internal.h000066400000000000000000000054741517447374300220520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_CANVAS_INTERNAL_H__ #define __CHAFA_CANVAS_INTERNAL_H__ #include #include "chafa.h" #include "internal/chafa-private.h" #include "internal/chafa-pixops.h" G_BEGIN_DECLS struct ChafaCanvasCell { gunichar c; /* Colors can be either packed RGBA or index */ guint32 fg_color; guint32 bg_color; }; struct ChafaCanvas { gint refs; gint width_pixels, height_pixels; ChafaPixel *pixels; ChafaCanvasCell *cells; guint have_alpha : 1; guint needs_clear : 1; /* Whether to consider inverted symbols; FALSE if using FG only */ guint consider_inverted : 1; /* Whether to extract symbol colors; FALSE if using default colors */ guint extract_colors : 1; /* Whether to quantize colors before calculating error (slower, but * yields better results in palettized modes, especially 16/8) */ guint use_quantized_error : 1; ChafaColorPair default_colors; guint work_factor_int; /* Character to use in cells where fg color == bg color. Typically * space, but could be something else depending on the symbol map. */ gunichar blank_char; /* Character to use in cells where fg color == bg color and the color * is only legal in FG. Typically 0x2588 (solid block), but could be * something else depending on the symbol map. Can be zero if there is * no good candidate! */ gunichar solid_char; ChafaCanvasConfig config; /* Used when setting pixel data */ ChafaDither dither; /* This is NULL in CHAFA_PIXEL_MODE_SYMBOLS, otherwise one of: * (ChafaSixelCanvas *), (ChafaKittyCanvas *), (ChafaIterm2Canvas *) */ gpointer pixel_canvas; /* It's possible to have a single placement that covers the entire * canvas. In this case, it is stored here. */ ChafaPlacement *placement; /* Our palettes. Kind of a big structure, so they go last. */ ChafaPalette fg_palette; ChafaPalette bg_palette; }; G_END_DECLS #endif /* __CHAFA_CANVAS_INTERNAL_H__ */ chafa-1.18.2/chafa/internal/chafa-canvas-printer.c000066400000000000000000000576361517447374300217230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-canvas-printer.h" typedef struct { ChafaCanvas *canvas; ChafaTermInfo *term_info; gunichar cur_char; gint n_reps; guint cur_inverted : 1; guint cur_bold : 1; guint32 cur_fg; guint32 cur_bg; /* For direct-color mode */ ChafaColor cur_fg_direct; ChafaColor cur_bg_direct; } PrintCtx; static gint cmp_colors (ChafaColor a, ChafaColor b) { return memcmp (&a, &b, sizeof (ChafaColor)); } static ChafaColor threshold_alpha (ChafaColor col, gint alpha_threshold) { col.ch [3] = col.ch [3] < alpha_threshold ? 0 : 255; return col; } G_GNUC_WARN_UNUSED_RESULT static gchar * flush_chars (PrintCtx *ctx, gchar *out) { gchar buf [8]; gint len; if (!ctx->cur_char) return out; len = g_unichar_to_utf8 (ctx->cur_char, buf); if ((ctx->canvas->config.optimizations & CHAFA_OPTIMIZATION_REPEAT_CELLS) && chafa_term_info_have_seq (ctx->term_info, CHAFA_TERM_SEQ_REPEAT_CHAR) && ctx->n_reps > 1 && ctx->n_reps * len > len + 4 /* ESC [#b */) { memcpy (out, buf, len); out += len; out = chafa_term_info_emit_repeat_char (ctx->term_info, out, ctx->n_reps - 1); ctx->n_reps = 0; } else { do { memcpy (out, buf, len); out += len; ctx->n_reps--; } while (ctx->n_reps != 0); } ctx->cur_char = 0; return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * queue_char (PrintCtx *ctx, gchar *out, gunichar c) { if (ctx->cur_char == c) { ctx->n_reps++; } else { if (ctx->cur_char) out = flush_chars (ctx, out); ctx->cur_char = c; ctx->n_reps = 1; } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * reset_fg (PrintCtx *ctx, gchar *out) { out = chafa_term_info_emit_reset_color_fg (ctx->term_info, out); ctx->cur_fg = CHAFA_PALETTE_INDEX_TRANSPARENT; ctx->cur_fg_direct.ch [3] = 0; return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * reset_attributes (PrintCtx *ctx, gchar *out) { out = chafa_term_info_emit_reset_attributes (ctx->term_info, out); ctx->cur_inverted = FALSE; ctx->cur_bold = FALSE; ctx->cur_fg = CHAFA_PALETTE_INDEX_TRANSPARENT; ctx->cur_bg = CHAFA_PALETTE_INDEX_TRANSPARENT; ctx->cur_fg_direct.ch [3] = 0; ctx->cur_bg_direct.ch [3] = 0; return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_attributes_truecolor (PrintCtx *ctx, gchar *out, ChafaColor fg, ChafaColor bg, gboolean inverted) { if (ctx->canvas->config.optimizations & CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES) { if (!ctx->canvas->config.fg_only_enabled && ((ctx->cur_inverted && !inverted) || (ctx->cur_fg_direct.ch [3] != 0 && fg.ch [3] == 0) || (ctx->cur_bg_direct.ch [3] != 0 && bg.ch [3] == 0))) { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); } if (!ctx->cur_inverted && inverted) { out = flush_chars (ctx, out); out = chafa_term_info_emit_invert_colors (ctx->term_info, out); } if (cmp_colors (fg, ctx->cur_fg_direct)) { if (cmp_colors (bg, ctx->cur_bg_direct) && bg.ch [3] != 0) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fgbg_direct (ctx->term_info, out, fg.ch [0], fg.ch [1], fg.ch [2], bg.ch [0], bg.ch [1], bg.ch [2]); } else if (fg.ch [3] != 0) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fg_direct (ctx->term_info, out, fg.ch [0], fg.ch [1], fg.ch [2]); } } else if (cmp_colors (bg, ctx->cur_bg_direct) && bg.ch [3] != 0) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_bg_direct (ctx->term_info, out, bg.ch [0], bg.ch [1], bg.ch [2]); } } else { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); if (inverted) out = chafa_term_info_emit_invert_colors (ctx->term_info, out); if (fg.ch [3] != 0) { if (bg.ch [3] != 0) { out = chafa_term_info_emit_set_color_fgbg_direct (ctx->term_info, out, fg.ch [0], fg.ch [1], fg.ch [2], bg.ch [0], bg.ch [1], bg.ch [2]); } else { out = chafa_term_info_emit_set_color_fg_direct (ctx->term_info, out, fg.ch [0], fg.ch [1], fg.ch [2]); } } else if (bg.ch [3] != 0) { out = chafa_term_info_emit_set_color_bg_direct (ctx->term_info, out, bg.ch [0], bg.ch [1], bg.ch [2]); } } ctx->cur_fg_direct = fg; ctx->cur_bg_direct = bg; ctx->cur_inverted = inverted; return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_ansi_truecolor (PrintCtx *ctx, gchar *out, gsize i, gsize i_max) { for ( ; i < i_max; i++) { ChafaCanvasCell *cell = &ctx->canvas->cells [i]; ChafaColor fg, bg; /* Wide symbols have a zero code point in the rightmost cell */ if (cell->c == 0) continue; chafa_unpack_color (cell->fg_color, &fg); fg = threshold_alpha (fg, ctx->canvas->config.alpha_threshold); chafa_unpack_color (cell->bg_color, &bg); bg = threshold_alpha (bg, ctx->canvas->config.alpha_threshold); if (fg.ch [3] == 0 && bg.ch [3] != 0) out = emit_attributes_truecolor (ctx, out, bg, fg, TRUE); else out = emit_attributes_truecolor (ctx, out, fg, bg, FALSE); if (fg.ch [3] == 0 && bg.ch [3] == 0) { out = queue_char (ctx, out, ' '); if (i < i_max - 1 && ctx->canvas->cells [i + 1].c == 0) out = queue_char (ctx, out, ' '); } else { out = queue_char (ctx, out, cell->c); } } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * handle_attrs_with_reuse (PrintCtx *ctx, gchar *out, guint32 fg, guint32 bg, gboolean inverted, gboolean bold) { /* In FG-only mode, we can't use inverse color or bold because the * attribute reset would mess with the background color. */ if (ctx->canvas->config.fg_only_enabled) return out; if ((ctx->cur_inverted && !inverted) || (ctx->cur_bold && !bold) || (ctx->cur_fg != CHAFA_PALETTE_INDEX_TRANSPARENT && fg == CHAFA_PALETTE_INDEX_TRANSPARENT) || (ctx->cur_bg != CHAFA_PALETTE_INDEX_TRANSPARENT && bg == CHAFA_PALETTE_INDEX_TRANSPARENT)) { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); } if (!ctx->cur_inverted && inverted) { out = flush_chars (ctx, out); out = chafa_term_info_emit_invert_colors (ctx->term_info, out); } if (!ctx->cur_bold && bold) { out = flush_chars (ctx, out); out = chafa_term_info_emit_enable_bold (ctx->term_info, out); } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_attributes_256 (PrintCtx *ctx, gchar *out, guint32 fg, guint32 bg, gboolean inverted) { if (ctx->canvas->config.optimizations & CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES) { out = handle_attrs_with_reuse (ctx, out, fg, bg, inverted, FALSE); if (fg != ctx->cur_fg) { if (bg != ctx->cur_bg && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fgbg_256 (ctx->term_info, out, fg, bg); } else if (fg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fg_256 (ctx->term_info, out, fg); } } else if (bg != ctx->cur_bg && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_bg_256 (ctx->term_info, out, bg); } } else { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); if (inverted) out = chafa_term_info_emit_invert_colors (ctx->term_info, out); if (fg != CHAFA_PALETTE_INDEX_TRANSPARENT) { if (bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = chafa_term_info_emit_set_color_fgbg_256 (ctx->term_info, out, fg, bg); } else { out = chafa_term_info_emit_set_color_fg_256 (ctx->term_info, out, fg); } } else if (bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = chafa_term_info_emit_set_color_bg_256 (ctx->term_info, out, bg); } } ctx->cur_fg = fg; ctx->cur_bg = bg; ctx->cur_inverted = inverted; return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_ansi_256 (PrintCtx *ctx, gchar *out, gsize i, gsize i_max) { for ( ; i < i_max; i++) { ChafaCanvasCell *cell = &ctx->canvas->cells [i]; guint32 fg, bg; /* Wide symbols have a zero code point in the rightmost cell */ if (cell->c == 0) continue; fg = cell->fg_color; bg = cell->bg_color; if (fg == CHAFA_PALETTE_INDEX_TRANSPARENT && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) out = emit_attributes_256 (ctx, out, bg, fg, TRUE); else out = emit_attributes_256 (ctx, out, fg, bg, FALSE); if (fg == CHAFA_PALETTE_INDEX_TRANSPARENT && bg == CHAFA_PALETTE_INDEX_TRANSPARENT) { out = queue_char (ctx, out, ' '); if (i < i_max - 1 && ctx->canvas->cells [i + 1].c == 0) out = queue_char (ctx, out, ' '); } else { out = queue_char (ctx, out, cell->c); } } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_attributes_16 (PrintCtx *ctx, gchar *out, guint32 fg, guint32 bg, gboolean inverted) { if (ctx->canvas->config.optimizations & CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES) { out = handle_attrs_with_reuse (ctx, out, fg, bg, inverted, FALSE); if (fg != ctx->cur_fg) { if (bg != ctx->cur_bg && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fgbg_16 (ctx->term_info, out, fg, bg); } else if (fg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fg_16 (ctx->term_info, out, fg); } } else if (bg != ctx->cur_bg && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_bg_16 (ctx->term_info, out, bg); } } else { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); if (inverted) out = chafa_term_info_emit_invert_colors (ctx->term_info, out); if (fg != CHAFA_PALETTE_INDEX_TRANSPARENT) { if (bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = chafa_term_info_emit_set_color_fgbg_16 (ctx->term_info, out, fg, bg); } else { out = chafa_term_info_emit_set_color_fg_16 (ctx->term_info, out, fg); } } else if (bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = chafa_term_info_emit_set_color_bg_16 (ctx->term_info, out, bg); } } ctx->cur_fg = fg; ctx->cur_bg = bg; ctx->cur_inverted = inverted; return out; } /* Uses aixterm control codes for bright colors */ G_GNUC_WARN_UNUSED_RESULT static gchar * emit_ansi_16 (PrintCtx *ctx, gchar *out, gsize i, gsize i_max) { for ( ; i < i_max; i++) { ChafaCanvasCell *cell = &ctx->canvas->cells [i]; guint32 fg, bg; /* Wide symbols have a zero code point in the rightmost cell */ if (cell->c == 0) continue; fg = cell->fg_color; bg = cell->bg_color; if (fg == CHAFA_PALETTE_INDEX_TRANSPARENT && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) out = emit_attributes_16 (ctx, out, bg, fg, TRUE); else out = emit_attributes_16 (ctx, out, fg, bg, FALSE); if (fg == CHAFA_PALETTE_INDEX_TRANSPARENT && bg == CHAFA_PALETTE_INDEX_TRANSPARENT) { out = queue_char (ctx, out, ' '); if (i < i_max - 1 && ctx->canvas->cells [i + 1].c == 0) out = queue_char (ctx, out, ' '); } else { out = queue_char (ctx, out, cell->c); } } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_attributes_16_8 (PrintCtx *ctx, gchar *out, guint32 fg, guint32 bg, gboolean inverted) { if (ctx->canvas->config.optimizations & CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES) { out = handle_attrs_with_reuse (ctx, out, fg, bg, inverted, fg > 7 && fg < 256 ? TRUE : FALSE); if (fg != ctx->cur_fg) { if (bg != ctx->cur_bg && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fgbg_8 (ctx->term_info, out, fg & 7, bg); } else if (fg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_fg_8 (ctx->term_info, out, fg & 7); } } else if (bg != ctx->cur_bg && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = flush_chars (ctx, out); out = chafa_term_info_emit_set_color_bg_8 (ctx->term_info, out, bg); } } else { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); if (inverted) out = chafa_term_info_emit_invert_colors (ctx->term_info, out); if (fg > 7) out = chafa_term_info_emit_enable_bold (ctx->term_info, out); if (fg != CHAFA_PALETTE_INDEX_TRANSPARENT) { if (bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = chafa_term_info_emit_set_color_fgbg_8 (ctx->term_info, out, fg & 7, bg); } else { out = chafa_term_info_emit_set_color_fg_8 (ctx->term_info, out, fg & 7); } } else if (bg != CHAFA_PALETTE_INDEX_TRANSPARENT) { out = chafa_term_info_emit_set_color_bg_8 (ctx->term_info, out, bg); } } ctx->cur_fg = fg; ctx->cur_bg = bg; ctx->cur_inverted = inverted; ctx->cur_bold = fg > 7 && fg < 256 ? TRUE : FALSE; return out; } /* Uses bold for bright FG colors. */ G_GNUC_WARN_UNUSED_RESULT static gchar * emit_ansi_16_8 (PrintCtx *ctx, gchar *out, gsize i, gsize i_max) { for ( ; i < i_max; i++) { ChafaCanvasCell *cell = &ctx->canvas->cells [i]; guint32 fg, bg; /* Wide symbols have a zero code point in the rightmost cell */ if (cell->c == 0) continue; fg = cell->fg_color; bg = cell->bg_color; if (fg == CHAFA_PALETTE_INDEX_TRANSPARENT && bg != CHAFA_PALETTE_INDEX_TRANSPARENT) out = emit_attributes_16_8 (ctx, out, bg, fg, TRUE); else out = emit_attributes_16_8 (ctx, out, fg, bg, FALSE); if (fg == CHAFA_PALETTE_INDEX_TRANSPARENT && bg == CHAFA_PALETTE_INDEX_TRANSPARENT) { out = queue_char (ctx, out, ' '); if (i < i_max - 1 && ctx->canvas->cells [i + 1].c == 0) out = queue_char (ctx, out, ' '); } else { out = queue_char (ctx, out, cell->c); } } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_ansi_fgbg_bgfg (PrintCtx *ctx, gchar *out, gsize i, gsize i_max) { gunichar blank_symbol = 0; if (chafa_symbol_map_has_symbol (&ctx->canvas->config.symbol_map, ' ')) { blank_symbol = ' '; } else if (chafa_symbol_map_has_symbol (&ctx->canvas->config.symbol_map, 0x2588 /* Solid block */ )) { blank_symbol = 0x2588; } for ( ; i < i_max; i++) { ChafaCanvasCell *cell = &ctx->canvas->cells [i]; gboolean invert = FALSE; gunichar c = cell->c; /* Wide symbols have a zero code point in the rightmost cell */ if (c == 0) continue; /* Replace with blank symbol only if this is a single-width cell */ if (cell->fg_color == cell->bg_color && blank_symbol != 0 && (i == i_max - 1 || (ctx->canvas->cells [i + 1].c != 0))) { c = blank_symbol; if (blank_symbol == 0x2588) invert = TRUE; } if (cell->bg_color == CHAFA_PALETTE_INDEX_FG) { invert ^= TRUE; } if (ctx->canvas->config.optimizations & CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES) { if (!ctx->cur_inverted && invert) { out = flush_chars (ctx, out); out = chafa_term_info_emit_invert_colors (ctx->term_info, out); } else if (ctx->cur_inverted && !invert) { out = flush_chars (ctx, out); out = reset_attributes (ctx, out); } ctx->cur_inverted = invert; } else { out = flush_chars (ctx, out); if (invert) out = chafa_term_info_emit_invert_colors (ctx->term_info, out); else out = reset_attributes (ctx, out); } out = queue_char (ctx, out, c); } return out; } G_GNUC_WARN_UNUSED_RESULT static gchar * emit_ansi_fgbg (PrintCtx *ctx, gchar *out, gsize i, gsize i_max) { for ( ; i < i_max; i++) { ChafaCanvasCell *cell = &ctx->canvas->cells [i]; /* Wide symbols have a zero code point in the rightmost cell */ if (cell->c == 0) continue; out = queue_char (ctx, out, cell->c); } return out; } static void prealloc_string (GString *gs, gint n_cells) { gsize needed_len; /* Each cell produces at most three control sequences and six bytes * for the UTF-8 character. Each row may add one seq and one newline. */ needed_len = ((gsize) n_cells + 1) * (CHAFA_TERM_SEQ_LENGTH_MAX * 3 + 6) + 1; if (gs->allocated_len - gs->len < needed_len) { gsize current_len = gs->len; g_string_set_size (gs, gs->len + needed_len * 2); gs->len = current_len; } } G_GNUC_WARN_UNUSED_RESULT static gchar * build_ansi_row (PrintCtx *ctx, gint row, gchar *out) { ChafaCanvas *canvas; gsize i, i_max; canvas = ctx->canvas; i = (gsize) row * (gsize) canvas->config.width; i_max = (gsize) (row + 1) * (gsize) canvas->config.width; if (row == 0 && canvas->config.canvas_mode != CHAFA_CANVAS_MODE_FGBG) { if (canvas->config.fg_only_enabled) out = reset_fg (ctx, out); else out = reset_attributes (ctx, out); } switch (canvas->config.canvas_mode) { case CHAFA_CANVAS_MODE_TRUECOLOR: out = emit_ansi_truecolor (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_INDEXED_256: case CHAFA_CANVAS_MODE_INDEXED_240: out = emit_ansi_256 (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_INDEXED_16: out = emit_ansi_16 (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_INDEXED_16_8: out = emit_ansi_16_8 (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_INDEXED_8: out = emit_ansi_16 (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_FGBG_BGFG: out = emit_ansi_fgbg_bgfg (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_FGBG: out = emit_ansi_fgbg (ctx, out, i, i_max); break; case CHAFA_CANVAS_MODE_MAX: g_assert_not_reached (); break; } out = flush_chars (ctx, out); /* Avoid control codes in FGBG mode. Don't reset attributes when BG * is held, to preserve any BG color set previously. */ if (canvas->config.canvas_mode != CHAFA_CANVAS_MODE_FGBG) { if (canvas->config.fg_only_enabled) out = reset_fg (ctx, out); else out = reset_attributes (ctx, out); } return out; } static GString * build_ansi_gstring (ChafaCanvas *canvas, ChafaTermInfo *ti) { GString *gs = g_string_new (""); PrintCtx ctx = { 0 }; gint i; ctx.canvas = canvas; ctx.term_info = ti; for (i = 0; i < canvas->config.height; i++) { gchar *out; prealloc_string (gs, canvas->config.width); out = gs->str + gs->len; out = build_ansi_row (&ctx, i, out); /* Rows end in a newline, except for the last one. This allows for * filling the display area while avoiding a blank bottom row. */ if (i < canvas->config.height - 1) *(out++) = '\n'; *out = '\0'; gs->len = out - gs->str; } return gs; } static void build_ansi_gstring_array (ChafaCanvas *canvas, ChafaTermInfo *ti, GString ***array_out, gint *array_len_out) { PrintCtx ctx = { 0 }; GString **array; gint i; ctx.canvas = canvas; ctx.term_info = ti; array = g_new (GString *, canvas->config.height + 1); for (i = 0; i < canvas->config.height; i++) { GString *gs = g_string_new (""); gchar *out; prealloc_string (gs, canvas->config.width); out = gs->str + gs->len; out = build_ansi_row (&ctx, i, out); *out = '\0'; gs->len = out - gs->str; array [i] = gs; } array [canvas->config.height] = NULL; *array_out = array; if (array_len_out) *array_len_out = canvas->config.height; } GString * chafa_canvas_print_symbols (ChafaCanvas *canvas, ChafaTermInfo *ti) { g_assert (canvas != NULL); g_assert (ti != NULL); return build_ansi_gstring (canvas, ti); } void chafa_canvas_print_symbol_rows (ChafaCanvas *canvas, ChafaTermInfo *ti, GString ***array_out, gint *array_len_out) { g_assert (canvas != NULL); g_assert (ti != NULL); g_assert (array_out != NULL); build_ansi_gstring_array (canvas, ti, array_out, array_len_out); } chafa-1.18.2/chafa/internal/chafa-canvas-printer.h000066400000000000000000000025501517447374300217110ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_CANVAS_PRINTER_H__ #define __CHAFA_CANVAS_PRINTER_H__ #include #include "chafa.h" #include "internal/chafa-canvas-internal.h" #include "internal/chafa-private.h" #include "internal/chafa-pixops.h" G_BEGIN_DECLS GString *chafa_canvas_print_symbols (ChafaCanvas *canvas, ChafaTermInfo *ti); void chafa_canvas_print_symbol_rows (ChafaCanvas *canvas, ChafaTermInfo *ti, GString ***array_out, gint *array_len_out); G_END_DECLS #endif /* __CHAFA_CANVAS_PRINTER_H__ */ chafa-1.18.2/chafa/internal/chafa-color-hash.c000066400000000000000000000025361517447374300210130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-color-hash.h" void chafa_color_hash_init (ChafaColorHash *color_hash) { guint i; guint32 j; /* Initialize with invalid entries */ for (i = 0, j = 0; i < CHAFA_COLOR_HASH_N_ENTRIES; i++) { while (_chafa_color_hash_calc_hash (j) == i) { j++; j %= 0x01000000; } color_hash->map [i] = j << 8; } } void chafa_color_hash_deinit (G_GNUC_UNUSED ChafaColorHash *color_hash) { } chafa-1.18.2/chafa/internal/chafa-color-hash.h000066400000000000000000000036161517447374300210200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_COLOR_HASH_H__ #define __CHAFA_COLOR_HASH_H__ G_BEGIN_DECLS #define CHAFA_COLOR_HASH_N_ENTRIES 16384 typedef struct { guint32 map [CHAFA_COLOR_HASH_N_ENTRIES]; } ChafaColorHash; void chafa_color_hash_init (ChafaColorHash *color_hash); void chafa_color_hash_deinit (ChafaColorHash *color_hash); static inline guint _chafa_color_hash_calc_hash (guint32 color) { color &= 0x00ffffff; return (color ^ (color >> 7) ^ (color >> 14)) % CHAFA_COLOR_HASH_N_ENTRIES; } static inline void chafa_color_hash_replace (ChafaColorHash *color_hash, guint32 color, guint8 pen) { guint index = _chafa_color_hash_calc_hash (color); guint32 entry = (color << 8) | pen; color_hash->map [index] = entry; } static inline gint chafa_color_hash_lookup (const ChafaColorHash *color_hash, guint32 color) { guint index = _chafa_color_hash_calc_hash (color); guint32 entry = color_hash->map [index]; if ((entry & 0xffffff00) == (color << 8)) return entry & 0xff; return -1; } G_END_DECLS #endif /* __CHAFA_COLOR_HASH_H__ */ chafa-1.18.2/chafa/internal/chafa-color-table.c000066400000000000000000000251321517447374300211540ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include "chafa.h" #include "internal/chafa-color-table.h" #include "internal/chafa-pca.h" #define CHAFA_COLOR_TABLE_ENABLE_PROFILING 0 #define DEBUG_PEN_CHOICE(x) #define POW2(x) ((x) * (x)) #define FIXED_MUL_BIG_SHIFT 14 #define FIXED_MUL_BIG (1 << (FIXED_MUL_BIG_SHIFT)) #define FIXED_MUL 32 #define FIXED_MUL_F ((gfloat) (FIXED_MUL)) #if CHAFA_COLOR_TABLE_ENABLE_PROFILING # define profile_counter_inc(x) g_atomic_int_inc ((gint *) &(x)) static gint n_lookups; static gint n_misses; static gint n_a; static gint n_b; static gint n_c; static gint n_d; static void dump_entry (const ChafaColorTable *color_table, gint entry, gint want_color) { const ChafaColorTableEntry *e = &color_table->entries [entry]; guint32 c = color_table->pens [e->pen]; gint err; err = POW2 (((gint) (c & 0xff) - (want_color & 0xff))) + POW2 (((gint) (c >> 8) & 0xff) - ((want_color >> 8) & 0xff)) + POW2 (((gint) (c >> 16) & 0xff) - ((want_color >> 16) & 0xff)); g_printerr ("{ %3d, %3d, %3d } { %7d, %7d } n = %3d err = %6d\n", c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff, e->v [0], e->v [1], entry, err); } #else # define profile_counter_inc(x) #endif static gint compare_entries (gconstpointer a, gconstpointer b) { const ChafaColorTableEntry *ab = a; const ChafaColorTableEntry *bb = b; return ab->v [0] - bb->v [0]; } static gint scalar_project_vec3i32 (const ChafaVec3i32 *a, const ChafaVec3i32 *b, gint32 b_mul) { gint64 d = chafa_vec3i32_dot_64 (a, b); /* I replaced the following (a division, three multiplications and * two additions) with a multiplication and a right shift: * * d / (POW2 (b->v [0]) + POW2 (b->v [1]) + POW2 (b->v [2])) * * The result is multiplied by FIXED_MUL for increased precision. */ return (d * b_mul) / (FIXED_MUL_BIG / FIXED_MUL); } static gint color_diff (guint32 a, guint32 b) { gint diff; gint n; n = ((gint) (b & 0xff) - (gint) (a & 0xff)) * FIXED_MUL; diff = n * n; n = ((gint) ((b >> 8) & 0xff) - (gint) ((a >> 8) & 0xff)) * FIXED_MUL; diff += n * n; n = ((gint) ((b >> 16) & 0xff) - (gint) ((a >> 16) & 0xff)) * FIXED_MUL; diff += n * n; return diff; } static void project_color (const ChafaColorTable *color_table, guint32 color, gint *v_out) { ChafaVec3i32 v; v.v [0] = (color & 0xff) * FIXED_MUL; v.v [1] = ((color >> 8) & 0xff) * FIXED_MUL; v.v [2] = ((color >> 16) & 0xff) * FIXED_MUL; chafa_vec3i32_sub (&v, &v, &color_table->average); v_out [0] = scalar_project_vec3i32 (&v, &color_table->eigenvectors [0], color_table->eigen_mul [0]); v_out [1] = scalar_project_vec3i32 (&v, &color_table->eigenvectors [1], color_table->eigen_mul [1]); } static void vec3i32_fixed_point_from_vec3f32 (ChafaVec3i32 *out, const ChafaVec3f32 *in) { ChafaVec3f32 t; chafa_vec3f32_mul_scalar (&t, in, FIXED_MUL_F); chafa_vec3i32_from_vec3f32 (out, &t); } static void do_pca (ChafaColorTable *color_table) { ChafaVec3f32 v [256]; ChafaVec3f32 eigenvectors [2]; ChafaVec3f32 average; gint i, j; for (i = 0, j = 0; i < 256; i++) { guint32 col = color_table->pens [i]; if ((col & 0xff000000) == 0xff000000) continue; v [j].v [0] = (col & 0xff) * FIXED_MUL_F; v [j].v [1] = ((col >> 8) & 0xff) * FIXED_MUL_F; v [j].v [2] = ((col >> 16) & 0xff) * FIXED_MUL_F; j++; } chafa_vec3f32_array_compute_pca (v, j, 2, eigenvectors, NULL, &average); vec3i32_fixed_point_from_vec3f32 (&color_table->eigenvectors [0], &eigenvectors [0]); vec3i32_fixed_point_from_vec3f32 (&color_table->eigenvectors [1], &eigenvectors [1]); vec3i32_fixed_point_from_vec3f32 (&color_table->average, &average); color_table->eigen_mul [0] = POW2 (color_table->eigenvectors [0].v [0]) + POW2 (color_table->eigenvectors [0].v [1]) + POW2 (color_table->eigenvectors [0].v [2]); color_table->eigen_mul [0] = MAX (color_table->eigen_mul [0], 1); color_table->eigen_mul [0] = FIXED_MUL_BIG / color_table->eigen_mul [0]; color_table->eigen_mul [1] = POW2 (color_table->eigenvectors [1].v [0]) + POW2 (color_table->eigenvectors [1].v [1]) + POW2 (color_table->eigenvectors [1].v [2]); color_table->eigen_mul [1] = MAX (color_table->eigen_mul [1], 1); color_table->eigen_mul [1] = FIXED_MUL_BIG / color_table->eigen_mul [1]; for (i = 0; i < color_table->n_entries; i++) { ChafaColorTableEntry *entry = &color_table->entries [i]; project_color (color_table, color_table->pens [entry->pen], entry->v); } } static inline gboolean refine_pen_choice (const ChafaColorTable *color_table, guint want_color, const gint *v, gint j, gint *best_pen, gint64 *best_diff) { const ChafaColorTableEntry *pj = &color_table->entries [j]; gint64 a, b, d; a = POW2 ((gint64) pj->v [0] - v [0]); profile_counter_inc (n_a); DEBUG_PEN_CHOICE (g_printerr ("a=%d\n", a)); if (a <= *best_diff) { /* TODO: When using gint32, the POW2 multiplication can result in overflow. * Our workaround is to use gint64 for best_diff, a, b and d. This probably * slows us down, though (we should measure). Is there a better fix? */ b = POW2 ((gint64) pj->v [1] - v [1]); profile_counter_inc (n_b); DEBUG_PEN_CHOICE (g_printerr ("b=%d\n", b)); if (b <= *best_diff) { d = color_diff (color_table->pens [pj->pen], want_color); profile_counter_inc (n_c); DEBUG_PEN_CHOICE (g_printerr ("d=%d\n", d)); if (d <= *best_diff) { *best_pen = j; *best_diff = d; profile_counter_inc (n_d); DEBUG_PEN_CHOICE (g_printerr ("a=%d, b=%d, d=%d\n", a, b, d)); } } } else { DEBUG_PEN_CHOICE (g_printerr ("\n")); return FALSE; } return TRUE; } void chafa_color_table_init (ChafaColorTable *color_table) { color_table->n_entries = 0; color_table->is_sorted = TRUE; memset (color_table->pens, 0xff, sizeof (color_table->pens)); } void chafa_color_table_deinit (G_GNUC_UNUSED ChafaColorTable *color_table) { #if CHAFA_COLOR_TABLE_ENABLE_PROFILING g_printerr ("l=%7d m=%7d a=%7d b=%7d c=%7d d=%7d\n" "per probe: a=%6.1lf b=%6.1lf c=%6.1lf d=%6.1lf\n", n_lookups, n_misses, n_a, n_b, n_c, n_d, n_a / (gdouble) n_lookups, n_b / (gdouble) n_lookups, n_c / (gdouble) n_lookups, n_d / (gdouble) n_lookups); #endif } guint32 chafa_color_table_get_pen_color (const ChafaColorTable *color_table, gint pen) { g_assert (pen >= 0); g_assert (pen < CHAFA_COLOR_TABLE_MAX_ENTRIES); return color_table->pens [pen]; } void chafa_color_table_set_pen_color (ChafaColorTable *color_table, gint pen, guint32 color) { g_assert (pen >= 0); g_assert (pen < CHAFA_COLOR_TABLE_MAX_ENTRIES); color_table->pens [pen] = color & 0x00ffffff; color_table->is_sorted = FALSE; } void chafa_color_table_sort (ChafaColorTable *color_table) { gint i, j; if (color_table->is_sorted) return; for (i = 0, j = 0; i < CHAFA_COLOR_TABLE_MAX_ENTRIES; i++) { ChafaColorTableEntry *entry; if (color_table->pens [i] == 0xffffffff) continue; entry = &color_table->entries [j++]; entry->pen = i; } color_table->n_entries = j; do_pca (color_table); qsort (color_table->entries, color_table->n_entries, sizeof (ChafaColorTableEntry), compare_entries); color_table->is_sorted = TRUE; } gint chafa_color_table_find_nearest_pen (const ChafaColorTable *color_table, guint32 want_color) { gint64 best_diff = G_MAXINT64; gint best_pen = 0; gint v [2]; gint i, j, m; g_assert (color_table->n_entries > 0); g_assert (color_table->is_sorted); profile_counter_inc (n_lookups); project_color (color_table, want_color, v); /* Binary search for first vector component */ i = 0; j = color_table->n_entries; while (i != j) { gint n = i + (j - i) / 2; if (v [0] > color_table->entries [n].v [0]) i = n + 1; else j = n; } m = j; /* Left scan for closer match */ for (j = m; j >= 0; j--) { if (!refine_pen_choice (color_table, want_color, v, j, &best_pen, &best_diff)) break; } /* Right scan for closer match */ for (j = m + 1; j < color_table->n_entries; j++) { if (!refine_pen_choice (color_table, want_color, v, j, &best_pen, &best_diff)) break; } #if CHAFA_COLOR_TABLE_ENABLE_PROFILING gint best_pen_2 = -1; gint64 best_diff_2 = G_MAXINT64; for (i = 0; i < color_table->n_entries; i++) { const ChafaColorTableEntry *pi = &color_table->entries [i]; gint64 d = color_diff (color_table->pens [pi->pen], want_color); if (d < best_diff_2) { best_pen_2 = i; best_diff_2 = d; } } if (best_diff_2 < best_diff) { profile_counter_inc (n_misses); g_printerr ("Bad lookup: "); dump_entry (color_table, best_pen, want_color); g_printerr ("\nShould be: "); dump_entry (color_table, best_pen_2, want_color); g_printerr ("\n"); } #endif return color_table->entries [best_pen].pen; } chafa-1.18.2/chafa/internal/chafa-color-table.h000066400000000000000000000037351517447374300211660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_COLOR_TABLE_H__ #define __CHAFA_COLOR_TABLE_H__ #include "internal/chafa-pca.h" G_BEGIN_DECLS #define CHAFA_COLOR_TABLE_MAX_ENTRIES 256 typedef struct { gint v [2]; gint pen; } ChafaColorTableEntry; typedef struct { ChafaColorTableEntry entries [CHAFA_COLOR_TABLE_MAX_ENTRIES]; /* Each pen is 24 bits (B8G8R8) of color information */ guint32 pens [CHAFA_COLOR_TABLE_MAX_ENTRIES]; gint n_entries; guint is_sorted : 1; ChafaVec3i32 eigenvectors [2]; ChafaVec3i32 average; gint eigen_mul [2]; } ChafaColorTable; void chafa_color_table_init (ChafaColorTable *color_table); void chafa_color_table_deinit (ChafaColorTable *color_table); guint32 chafa_color_table_get_pen_color (const ChafaColorTable *color_table, gint pen); void chafa_color_table_set_pen_color (ChafaColorTable *color_table, gint pen, guint32 color); void chafa_color_table_sort (ChafaColorTable *color_table); gint chafa_color_table_find_nearest_pen (const ChafaColorTable *color_table, guint32 color); G_END_DECLS #endif /* __CHAFA_COLOR_TABLE_H__ */ chafa-1.18.2/chafa/internal/chafa-color.c000066400000000000000000000106501517447374300200660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* abs */ #include /* pow, cbrt, log, sqrt, atan2, cos, sin */ #include "chafa.h" #include "internal/chafa-private.h" #include "internal/chafa-color.h" guint32 chafa_pack_color (const ChafaColor *color) { /* Assumes each channel 0 <= value <= 255 */ return ((guint32) color->ch [0] << 16) | ((guint32) color->ch [1] << 8) | ((guint32) color->ch [2]) | ((guint32) color->ch [3] << 24); /* Alpha */ } void chafa_unpack_color (guint32 packed, ChafaColor *color_out) { color_out->ch [0] = (packed >> 16) & 0xff; color_out->ch [1] = (packed >> 8) & 0xff; color_out->ch [2] = packed & 0xff; color_out->ch [3] = (packed >> 24) & 0xff; /* Alpha */ } void chafa_color_accum_div_scalar (ChafaColorAccum *accum, gint scalar) { #ifdef HAVE_AVX2_INTRINSICS if (chafa_have_avx2 ()) { chafa_color_accum_div_scalar_avx2 (accum, scalar); } else #endif { accum->ch [0] /= scalar; accum->ch [1] /= scalar; accum->ch [2] /= scalar; accum->ch [3] /= scalar; } } typedef struct { gdouble c [3]; } ChafaColorRGBf; typedef struct { gdouble c [3]; } ChafaColorXYZ; typedef struct { gdouble c [3]; } ChafaColorLab; static gdouble invert_rgb_channel_compand (gdouble v) { return v <= 0.04045 ? (v / 12.92) : pow ((v + 0.055) / 1.044, 2.4); } static void convert_rgb_to_xyz (const ChafaColor *rgbi, ChafaColorXYZ *xyz) { ChafaColorRGBf rgbf; gint i; for (i = 0; i < 3; i++) { rgbf.c [i] = (gdouble) rgbi->ch [i] / 255.0; rgbf.c [i] = invert_rgb_channel_compand (rgbf.c [i]); } xyz->c [0] = 0.4124564 * rgbf.c [0] + 0.3575761 * rgbf.c [1] + 0.1804375 * rgbf.c [2]; xyz->c [1] = 0.2126729 * rgbf.c [0] + 0.7151522 * rgbf.c [1] + 0.0721750 * rgbf.c [2]; xyz->c [2] = 0.0193339 * rgbf.c [0] + 0.1191920 * rgbf.c [1] + 0.9503041 * rgbf.c [2]; } #define XYZ_EPSILON (216.0 / 24389.0) #define XYZ_KAPPA (24389.0 / 27.0) static gdouble lab_f (gdouble v) { return v > XYZ_EPSILON ? cbrt (v) : (XYZ_KAPPA * v + 16.0) / 116.0; } static void convert_xyz_to_lab (const ChafaColorXYZ *xyz, ChafaColorLab *lab) { ChafaColorXYZ wp = { { 0.95047, 1.0, 1.08883 } }; /* D65 white point */ ChafaColorXYZ xyz2; gint i; for (i = 0; i < 3; i++) xyz2.c [i] = lab_f (xyz->c [i] / wp.c [i]); lab->c [0] = 116.0 * xyz2.c [1] - 16.0; lab->c [1] = 500.0 * (xyz2.c [0] - xyz2.c [1]); lab->c [2] = 200.0 * (xyz2.c [1] - xyz2.c [2]); } void chafa_color_rgb_to_din99d (const ChafaColor *rgb, ChafaColor *din99) { ChafaColorXYZ xyz; ChafaColorLab lab; gdouble adj_L, ee, f, G, C, h; convert_rgb_to_xyz (rgb, &xyz); /* Apply tristimulus-space correction term */ xyz.c [0] = 1.12 * xyz.c [0] - 0.12 * xyz.c [2]; /* Convert to L*a*b* */ convert_xyz_to_lab (&xyz, &lab); adj_L = 325.22 * log (1.0 + 0.0036 * lab.c [0]); /* Intermediate parameters */ ee = 0.6427876096865393 * lab.c [1] + 0.766044443118978 * lab.c [2]; f = 1.14 * (0.6427876096865393 * lab.c [2] - 0.766044443118978 * lab.c [1]); G = sqrt (ee * ee + f * f); /* Hue/chroma */ C = 22.5 * log (1.0 + 0.06 * G); h = atan2 (f, ee) + 0.8726646 /* 50 degrees */; while (h < 0.0) h += 6.283185; /* 360 degrees */ while (h > 6.283185) h -= 6.283185; /* 360 degrees */ /* The final values should be in the range [0..255] */ din99->ch [0] = adj_L * 2.5; din99->ch [1] = C * cos (h) * 2.5 + 128.0; din99->ch [2] = C * sin (h) * 2.5 + 128.0; din99->ch [3] = rgb->ch [3]; } chafa-1.18.2/chafa/internal/chafa-color.h000066400000000000000000000071021517447374300200710ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_COLOR_H__ #define __CHAFA_COLOR_H__ #include #include "chafa.h" G_BEGIN_DECLS #define CHAFA_PALETTE_INDEX_TRANSPARENT 256 #define CHAFA_PALETTE_INDEX_FG 257 #define CHAFA_PALETTE_INDEX_BG 258 #define CHAFA_PALETTE_INDEX_MAX 259 /* Color space agnostic */ typedef struct { guint8 ch [4]; } ChafaColor; /* BG/FG indexes must be 0 and 1 respectively, corresponding to * coverage bitmap values */ #define CHAFA_COLOR_PAIR_BG 0 #define CHAFA_COLOR_PAIR_FG 1 typedef struct { ChafaColor colors [2]; } ChafaColorPair; typedef struct { union { guint32 u32; ChafaColor col; } u; } ChafaColorConv; static inline ChafaColor chafa_color8_fetch_from_rgba8 (gconstpointer p) { const guint32 *p32 = (const guint32 *) p; ChafaColorConv cc; cc.u.u32 = *p32; return cc.u.col; } static inline void chafa_color8_store_to_rgba8 (ChafaColor col, gpointer p) { guint32 *p32 = (guint32 *) p; ChafaColorConv cc; cc.u.col = col; *p32 = cc.u.u32; } static inline ChafaColor chafa_color8_from_u32 (guint32 u32) { ChafaColorConv cc; cc.u.u32 = u32; return cc.u.col; } static inline guint32 chafa_color8_to_u32 (ChafaColor col) { ChafaColorConv cc; cc.u.col = col; return cc.u.u32; } static inline ChafaColor chafa_color_average_2 (ChafaColor color_a, ChafaColor color_b) { ChafaColor avg = { 0 }; avg = chafa_color8_from_u32 ( ((chafa_color8_to_u32 (color_a) >> 1) & 0x7f7f7f7f) + ((chafa_color8_to_u32 (color_b) >> 1) & 0x7f7f7f7f)); return avg; } typedef struct { ChafaColor col [CHAFA_COLOR_SPACE_MAX]; } ChafaPaletteColor; typedef struct { gint16 ch [4]; } ChafaColorAccum; typedef struct { ChafaColor col; } ChafaPixel; /* Color selection candidate pair */ typedef struct { gint16 index [2]; gint error [2]; } ChafaColorCandidates; /* Internal API */ guint32 chafa_pack_color (const ChafaColor *color) G_GNUC_PURE; void chafa_unpack_color (guint32 packed, ChafaColor *color_out); #define chafa_color_accum_add(d, s) \ G_STMT_START { \ (d)->ch [0] += (s)->ch [0]; (d)->ch [1] += (s)->ch [1]; (d)->ch [2] += (s)->ch [2]; (d)->ch [3] += (s)->ch [3]; \ } G_STMT_END #define chafa_color_diff_fast(col_a, col_b) \ (((gint) (col_b)->ch [0] - (gint) (col_a)->ch [0]) * ((gint) (col_b)->ch [0] - (gint) (col_a)->ch [0]) \ + ((gint) (col_b)->ch [1] - (gint) (col_a)->ch [1]) * ((gint) (col_b)->ch [1] - (gint) (col_a)->ch [1]) \ + ((gint) (col_b)->ch [2] - (gint) (col_a)->ch [2]) * ((gint) (col_b)->ch [2] - (gint) (col_a)->ch [2])) void chafa_color_accum_div_scalar (ChafaColorAccum *color, gint scalar); void chafa_color_rgb_to_din99d (const ChafaColor *rgb, ChafaColor *din99); G_END_DECLS #endif /* __CHAFA_COLOR_H__ */ chafa-1.18.2/chafa/internal/chafa-dither.c000066400000000000000000000100151517447374300202220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include "chafa.h" #include "internal/chafa-dither.h" #include "internal/chafa-private.h" #define TEXTURE_DIM_SHIFT 4 #define TEXTURE_DIM (1 << (TEXTURE_DIM_SHIFT)) #define TEXTURE_SIZE ((TEXTURE_DIM) * (TEXTURE_DIM)) #define TEXTURE_NOISE_N_CHANNELS 3 static gint calc_grain_shift (gint size) { switch (size) { case 1: return 0; case 2: return 1; case 4: return 2; case 8: return 3; default: g_assert_not_reached (); } return 0; } void chafa_dither_init (ChafaDither *dither, ChafaDitherMode mode, gfloat intensity, gint grain_width, gint grain_height) { memset (dither, 0, sizeof (*dither)); dither->mode = mode; dither->intensity = intensity; dither->grain_width_shift = calc_grain_shift (grain_width); dither->grain_height_shift = calc_grain_shift (grain_height); if (mode == CHAFA_DITHER_MODE_ORDERED) { dither->texture_size_shift = TEXTURE_DIM_SHIFT; dither->texture_size_mask = TEXTURE_DIM - 1; dither->texture_data = chafa_gen_bayer_matrix (TEXTURE_DIM, intensity); } else if (mode == CHAFA_DITHER_MODE_NOISE) { dither->texture_size_shift = 6; dither->texture_size_mask = (1 << 6) - 1; dither->texture_data = chafa_gen_noise_matrix (dither->intensity * 0.1f); } else if (mode == CHAFA_DITHER_MODE_DIFFUSION) { dither->intensity = MIN (dither->intensity, 1.0f); } } void chafa_dither_deinit (ChafaDither *dither) { g_free (dither->texture_data); dither->texture_data = NULL; } void chafa_dither_copy (const ChafaDither *src, ChafaDither *dest) { memcpy (dest, src, sizeof (*dest)); if (dest->texture_data) { if (dest->mode == CHAFA_DITHER_MODE_NOISE) dest->texture_data = g_memdup (src->texture_data, 64 * 64 * TEXTURE_NOISE_N_CHANNELS * sizeof (gint)); else dest->texture_data = g_memdup (src->texture_data, TEXTURE_SIZE * sizeof (gint)); } } ChafaColor chafa_dither_color (const ChafaDither *dither, ChafaColor color, gint x, gint y) { gint texture_index = (((y >> dither->grain_height_shift) & dither->texture_size_mask) << dither->texture_size_shift) + ((x >> dither->grain_width_shift) & dither->texture_size_mask); gint i; if (dither->mode == CHAFA_DITHER_MODE_ORDERED) { gint16 texture_mod = dither->texture_data [texture_index]; for (i = 0; i < 3; i++) { gint16 c; c = (gint16) color.ch [i] + texture_mod; c = CLAMP (c, 0, 255); color.ch [i] = c; } } else if (dither->mode == CHAFA_DITHER_MODE_NOISE) { for (i = 0; i < 3; i++) { gint16 texture_mod = dither->texture_data [texture_index * TEXTURE_NOISE_N_CHANNELS + i]; gint16 c; c = (gint16) color.ch [i] + texture_mod; c = CLAMP (c, 0, 255); color.ch [i] = c; } } else { g_assert_not_reached (); } return color; } chafa-1.18.2/chafa/internal/chafa-dither.h000066400000000000000000000031121517447374300202270ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_DITHER_H__ #define __CHAFA_DITHER_H__ #include "internal/chafa-palette.h" G_BEGIN_DECLS typedef struct { ChafaDitherMode mode; gfloat intensity; gint grain_width_shift; gint grain_height_shift; gint texture_size_shift; guint texture_size_mask; gint *texture_data; } ChafaDither; void chafa_dither_init (ChafaDither *dither, ChafaDitherMode mode, gfloat intensity, gint grain_width, gint grain_height); void chafa_dither_deinit (ChafaDither *dither); void chafa_dither_copy (const ChafaDither *src, ChafaDither *dest); ChafaColor chafa_dither_color (const ChafaDither *dither, ChafaColor color, gint x, gint y); G_END_DECLS #endif /* __CHAFA_DITHER_H__ */ chafa-1.18.2/chafa/internal/chafa-indexed-image.c000066400000000000000000000451271517447374300214570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "smolscale/smolscale.h" #include "chafa.h" #include "internal/chafa-batch.h" #include "internal/chafa-math-util.h" #include "internal/chafa-private.h" typedef struct { ChafaIndexedImage *indexed_image; ChafaColorSpace color_space; ChafaPixelType src_pixel_type; gconstpointer src_pixels; gint src_width, src_height, src_rowstride; gint dest_width, dest_height; gfloat quality; SmolScaleCtx *scale_ctx; guint32 *scaled_data; /* BG color with alpha multiplier 255-0 */ guint32 bg_color_lut [256]; } DrawPixelsCtx; static void gen_color_lut_rgba8 (guint32 *color_lut, ChafaColor col) { gint i; for (i = 0; i < 256; i++) { ChafaColor ncol; ncol.ch [0] = (col.ch [0] * (255 - i)) / 255; ncol.ch [1] = (col.ch [1] * (255 - i)) / 255; ncol.ch [2] = (col.ch [2] * (255 - i)) / 255; ncol.ch [3] = 0; chafa_color8_store_to_rgba8 (ncol, &color_lut [i]); } } static void post_scale_row (gpointer row_inout, int width, void *user_data) { const DrawPixelsCtx *ctx = user_data; guint32 *row_inout_u32 = row_inout; guint32 *row_inout_end = row_inout_u32 + width; /* Composite on solid background color */ for ( ; row_inout_u32 < row_inout_end; row_inout_u32++) { ChafaColor c = chafa_color8_fetch_from_rgba8 (row_inout_u32); *row_inout_u32 += ctx->bg_color_lut [c.ch [3]]; } } static void draw_pixels_pass_1_worker (ChafaBatchInfo *batch, const DrawPixelsCtx *ctx) { smol_scale_batch_full (ctx->scale_ctx, ctx->scaled_data + ((gsize) ctx->dest_width * batch->first_row), batch->first_row, batch->n_rows); } static gint quantize_pixel (const ChafaPalette *palette, ChafaColorSpace color_space, ChafaColorHash *color_hash, ChafaColor color) { ChafaColor cached_color; gint index; if ((gint) (color.ch [3]) < chafa_palette_get_alpha_threshold (palette)) return chafa_palette_get_transparent_index (palette); /* Sixel color resolution is only slightly less than 7 bits per channel, * so eliminate the low-order bits to get better hash performance. Also * mask out the alpha channel. */ cached_color = chafa_color8_from_u32 (chafa_color8_to_u32 (color) & GUINT32_FROM_BE (0xfefefe00)); index = chafa_color_hash_lookup (color_hash, chafa_color8_to_u32 (cached_color)); if (index < 0) { if (color_space == CHAFA_COLOR_SPACE_DIN99D) chafa_color_rgb_to_din99d (&color, &color); index = chafa_palette_lookup_nearest (palette, color_space, &color, NULL) - chafa_palette_get_first_color (palette); /* Don't insert transparent pixels, since color hash does not store transparency */ if (index != chafa_palette_get_transparent_index (palette)) chafa_color_hash_replace (color_hash, chafa_color8_to_u32 (cached_color), index); } return index; } static gint quantize_pixel_with_error (const ChafaPalette *palette, ChafaColorSpace color_space, ChafaColor color, ChafaColorAccum *error_inout) { gint index; if ((gint) (color.ch [3]) < chafa_palette_get_alpha_threshold (palette)) { gint i; /* Don't propagate error across transparency */ for (i = 0; i < 4; i++) error_inout->ch [i] = 0; return chafa_palette_get_transparent_index (palette); } if (color_space == CHAFA_COLOR_SPACE_DIN99D) chafa_color_rgb_to_din99d (&color, &color); index = chafa_palette_lookup_with_error (palette, color_space, color, error_inout) - chafa_palette_get_first_color (palette); return index; } static void draw_pixels_pass_2_nodither (ChafaBatchInfo *batch, const DrawPixelsCtx *ctx, ChafaColorHash *chash) { const guint32 *src_p; guint8 *dest_p, *dest_end_p; src_p = ctx->scaled_data + ((gsize) ctx->dest_width * batch->first_row); dest_p = ctx->indexed_image->pixels + ((gsize) ctx->dest_width * batch->first_row); dest_end_p = dest_p + ((gsize) ctx->dest_width * batch->n_rows); for ( ; dest_p < dest_end_p; src_p++, dest_p++) { ChafaColor col; gint index; col = chafa_color8_fetch_from_rgba8 (src_p); index = quantize_pixel (&ctx->indexed_image->palette, ctx->color_space, chash, col); *dest_p = index; } } static void draw_pixels_pass_2_dither (ChafaBatchInfo *batch, const DrawPixelsCtx *ctx, ChafaColorHash *chash) { const guint32 *src_p; guint8 *dest_p, *dest_end_p; gint x, y; src_p = ctx->scaled_data + ((gsize) ctx->dest_width * batch->first_row); dest_p = ctx->indexed_image->pixels + ((gsize) ctx->dest_width * batch->first_row); dest_end_p = dest_p + ((gsize) ctx->dest_width * batch->n_rows); x = 0; y = batch->first_row; for ( ; dest_p < dest_end_p; src_p++, dest_p++) { ChafaColor col; gint index; col = chafa_color8_fetch_from_rgba8 (src_p); col = chafa_dither_color (&ctx->indexed_image->dither, col, x, y); index = quantize_pixel (&ctx->indexed_image->palette, ctx->color_space, chash, col); *dest_p = index; if (++x >= ctx->dest_width) { x = 0; y++; } } } static void distribute_error (ChafaColorAccum error_in, ChafaColorAccum *error_out_0, ChafaColorAccum *error_out_1, ChafaColorAccum *error_out_2, ChafaColorAccum *error_out_3, gfloat intensity) { gint i; for (i = 0; i < 3; i++) { gint16 ch = error_in.ch [i]; error_out_0->ch [i] += (ch * 7) * intensity; error_out_1->ch [i] += (ch * 1) * intensity; error_out_2->ch [i] += (ch * 5) * intensity; error_out_3->ch [i] += (ch * 3) * intensity; } } static guint8 fs_dither_pixel (const DrawPixelsCtx *ctx, G_GNUC_UNUSED ChafaColorHash *chash, const guint32 *inpixel_p, ChafaColorAccum error_in, ChafaColorAccum *error_out_0, ChafaColorAccum *error_out_1, ChafaColorAccum *error_out_2, ChafaColorAccum *error_out_3) { ChafaColor col = chafa_color8_fetch_from_rgba8 (inpixel_p); guint8 index; index = quantize_pixel_with_error (&ctx->indexed_image->palette, ctx->color_space, col, &error_in); distribute_error (error_in, error_out_0, error_out_1, error_out_2, error_out_3, ctx->indexed_image->dither.intensity); return index; } static void fs_dither_row (const DrawPixelsCtx *ctx, ChafaColorHash *chash, const guint32 *inrow_p, guint8 *outrow_p, ChafaColorAccum *error_row, ChafaColorAccum *next_error_row, gint width, gint y) { gint x; if (y & 1) { /* Forwards pass */ outrow_p [0] = fs_dither_pixel (ctx, chash, &inrow_p [0], error_row [0], &error_row [1], &next_error_row [1], &next_error_row [0], &next_error_row [1]); for (x = 1; x < width - 1; x++) { outrow_p [x] = fs_dither_pixel (ctx, chash, &inrow_p [x], error_row [x], &error_row [x + 1], &next_error_row [x + 1], &next_error_row [x], &next_error_row [x - 1]); } outrow_p [x] = fs_dither_pixel (ctx, chash, &inrow_p [x], error_row [x], &next_error_row [x], &next_error_row [x], &next_error_row [x - 1], &next_error_row [x - 1]); } else { /* Backwards pass */ x = width - 1; outrow_p [x] = fs_dither_pixel (ctx, chash, &inrow_p [x], error_row [x], &error_row [x - 1], &next_error_row [x - 1], &next_error_row [x], &next_error_row [x - 1]); for (x--; x >= 1; x--) { outrow_p [x] = fs_dither_pixel (ctx, chash, &inrow_p [x], error_row [x], &error_row [x - 1], &next_error_row [x - 1], &next_error_row [x], &next_error_row [x + 1]); } outrow_p [0] = fs_dither_pixel (ctx, chash, &inrow_p [0], error_row [0], &next_error_row [0], &next_error_row [0], &next_error_row [1], &next_error_row [1]); } } static void draw_pixels_pass_2_fs (ChafaBatchInfo *batch, const DrawPixelsCtx *ctx, ChafaColorHash *chash) { ChafaColorAccum *error_row [2]; const guint32 *src_p; guint8 *dest_end_p, *dest_p; gint y; error_row [0] = g_malloc ((gsize) ctx->dest_width * sizeof (ChafaColorAccum)); error_row [1] = g_malloc ((gsize) ctx->dest_width * sizeof (ChafaColorAccum)); src_p = ctx->scaled_data + ((gsize) ctx->dest_width * batch->first_row); dest_p = ctx->indexed_image->pixels + ((gsize) ctx->dest_width * batch->first_row); dest_end_p = dest_p + ((gsize) ctx->dest_width * batch->n_rows); y = batch->first_row; memset (error_row [0], 0, (gsize) ctx->dest_width * sizeof (ChafaColorAccum)); for ( ; dest_p < dest_end_p; src_p += ctx->dest_width, dest_p += ctx->dest_width, y++) { ChafaColorAccum *error_row_temp; memset (error_row [1], 0, (gsize) ctx->dest_width * sizeof (ChafaColorAccum)); fs_dither_row (ctx, chash, src_p, dest_p, error_row [0], error_row [1], ctx->dest_width, y); error_row_temp = error_row [0]; error_row [0] = error_row [1]; error_row [1] = error_row_temp; } g_free (error_row [1]); g_free (error_row [0]); } static void draw_pixels_pass_2_worker (ChafaBatchInfo *batch, const DrawPixelsCtx *ctx) { ChafaColorHash chash; chafa_color_hash_init (&chash); switch (ctx->indexed_image->dither.mode) { case CHAFA_DITHER_MODE_NONE: draw_pixels_pass_2_nodither (batch, ctx, &chash); break; case CHAFA_DITHER_MODE_ORDERED: case CHAFA_DITHER_MODE_NOISE: draw_pixels_pass_2_dither (batch, ctx, &chash); break; case CHAFA_DITHER_MODE_DIFFUSION: draw_pixels_pass_2_fs (batch, ctx, &chash); break; case CHAFA_DITHER_MODE_MAX: g_assert_not_reached (); break; } chafa_color_hash_deinit (&chash); } static void draw_pixels (DrawPixelsCtx *ctx) { chafa_process_batches (ctx, (GFunc) draw_pixels_pass_1_worker, NULL, ctx->dest_height, chafa_get_n_actual_threads (), 1); chafa_palette_generate (&ctx->indexed_image->palette, ctx->scaled_data, (gsize) ctx->dest_width * ctx->dest_height, ctx->color_space, ctx->quality); /* Single thread only for diffusion; it's a fully serial operation */ chafa_process_batches (ctx, (GFunc) draw_pixels_pass_2_worker, NULL, ctx->dest_height, ctx->indexed_image->dither.mode == CHAFA_DITHER_MODE_DIFFUSION ? 1 : chafa_get_n_actual_threads (), 1); } ChafaIndexedImage * chafa_indexed_image_new (gint width, gint height, const ChafaPalette *palette, const ChafaDither *dither) { ChafaIndexedImage *indexed_image; indexed_image = g_new0 (ChafaIndexedImage, 1); indexed_image->width = width; indexed_image->height = height; indexed_image->pixels = g_try_malloc ((gsize) width * height); if (!indexed_image->pixels) { #if 0 g_warning ("ChafaIndexedImage: Out of memory allocating %ux%u pixels.", width, height); #endif g_free (indexed_image); return NULL; } chafa_palette_copy (palette, &indexed_image->palette); chafa_palette_set_transparent_index (&indexed_image->palette, 255); chafa_dither_copy (dither, &indexed_image->dither); return indexed_image; } void chafa_indexed_image_destroy (ChafaIndexedImage *indexed_image) { chafa_dither_deinit (&indexed_image->dither); g_free (indexed_image->pixels); g_free (indexed_image); } void chafa_indexed_image_draw_pixels (ChafaIndexedImage *indexed_image, ChafaColorSpace color_space, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, gint dest_width, gint dest_height, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck, gfloat quality) { DrawPixelsCtx ctx; ChafaColor bg; gint placement_x, placement_y; gint placement_width, placement_height; g_return_if_fail (dest_width == indexed_image->width); g_return_if_fail (dest_height <= indexed_image->height); dest_width = MIN (dest_width, indexed_image->width); dest_height = MIN (dest_height, indexed_image->height); ctx.indexed_image = indexed_image; ctx.color_space = color_space; ctx.src_pixel_type = src_pixel_type; ctx.src_pixels = src_pixels; ctx.src_width = src_width; ctx.src_height = src_height; ctx.src_rowstride = src_rowstride; ctx.dest_width = dest_width; ctx.dest_height = dest_height; ctx.quality = quality; #if 0 /* FIXME: Need a new smolscale compositing mode that preserves src * alpha before this can be implemented */ bg = *chafa_palette_get_color (&indexed_image->palette, CHAFA_COLOR_SPACE_RGB, CHAFA_PALETTE_INDEX_BG); bg.ch [3] = 0xff; #else gen_color_lut_rgba8 (ctx.bg_color_lut, *chafa_palette_get_color (&indexed_image->palette, CHAFA_COLOR_SPACE_RGB, CHAFA_PALETTE_INDEX_BG)); #endif chafa_tuck_and_align (src_width, src_height, dest_width, dest_height, halign, valign, tuck, &placement_x, &placement_y, &placement_width, &placement_height); /* FIXME: Save temp memory by sampling the image in strips. ChafaPalette * will need a batch API for this. */ ctx.scaled_data = g_try_new (guint32, (gsize) dest_width * dest_height); if (!ctx.scaled_data) { #if 0 g_warning ("ChafaIndexedImage: Out of memory allocating %ux%u temp pixels.", dest_width, dest_height); #endif return; } ctx.scale_ctx = smol_scale_new_full (/* Source */ (const guint32 *) src_pixels, (SmolPixelType) src_pixel_type, src_width, src_height, src_rowstride, /* Fill */ #if 0 bg.ch, #else NULL, #endif SMOL_PIXEL_RGBA8_UNASSOCIATED, /* Destination */ NULL, SMOL_PIXEL_RGBA8_PREMULTIPLIED, dest_width, dest_height, dest_width * sizeof (guint32), /* Placement */ placement_x * SMOL_SUBPIXEL_MUL, placement_y * SMOL_SUBPIXEL_MUL, placement_width * SMOL_SUBPIXEL_MUL, placement_height * SMOL_SUBPIXEL_MUL, /* Extra args */ SMOL_COMPOSITE_SRC_CLEAR_DEST, #if 0 SMOL_NO_FLAGS, NULL, #else SMOL_DISABLE_SRGB_LINEARIZATION, post_scale_row, #endif &ctx); draw_pixels (&ctx); memset (indexed_image->pixels + (gsize) indexed_image->width * dest_height, chafa_palette_get_transparent_index (&indexed_image->palette), (gsize) indexed_image->width * (indexed_image->height - dest_height)); smol_scale_destroy (ctx.scale_ctx); g_free (ctx.scaled_data); } chafa-1.18.2/chafa/internal/chafa-indexed-image.h000066400000000000000000000040661517447374300214610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_INDEXED_IMAGE_H__ #define __CHAFA_INDEXED_IMAGE_H__ #include "internal/chafa-palette.h" #include "internal/chafa-dither.h" G_BEGIN_DECLS typedef struct { gint width, height; ChafaPalette palette; ChafaDither dither; guint8 *pixels; } ChafaIndexedImage; ChafaIndexedImage *chafa_indexed_image_new (gint width, gint height, const ChafaPalette *palette, const ChafaDither *dither); void chafa_indexed_image_destroy (ChafaIndexedImage *indexed_image); void chafa_indexed_image_draw_pixels (ChafaIndexedImage *indexed_image, ChafaColorSpace color_space, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, gint dest_width, gint dest_height, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck, gfloat quality); G_END_DECLS #endif /* __CHAFA_INDEXED_IMAGE_H__ */ chafa-1.18.2/chafa/internal/chafa-iterm2-canvas.c000066400000000000000000000260301517447374300214220ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "smolscale/smolscale.h" #include "internal/chafa-base64.h" #include "internal/chafa-batch.h" #include "internal/chafa-bitfield.h" #include "internal/chafa-indexed-image.h" #include "internal/chafa-iterm2-canvas.h" #include "internal/chafa-math-util.h" #include "internal/chafa-string-util.h" /* We support iTerm2 images by embedding them as uncompressed TIFF files. * * See: https://www.adobe.io/open/standards/TIFF.html */ typedef enum { TIFF_TYPE_NONE = 0, TIFF_TYPE_BYTE, TIFF_TYPE_ASCII, TIFF_TYPE_SHORT, TIFF_TYPE_LONG, TIFF_TYPE_RATIONAL, TIFF_TYPE_SBYTE, TIFF_TYPE_UNDEF, TIFF_TYPE_SSHORT, TIFF_TYPE_SLONG, TIFF_TYPE_SRATIONAL, TIFF_TYPE_FLOAT, TIFF_TYPE_DOUBLE } TiffType; typedef enum { TIFF_TAG_NONE = 0, TIFF_TAG_NEW_SUB_FILE_TYPE = 254, TIFF_TAG_SUB_FILE_TYPE, TIFF_TAG_IMAGE_WIDTH, TIFF_TAG_IMAGE_LENGTH, TIFF_TAG_BITS_PER_SAMPLE, TIFF_TAG_COMPRESSION, TIFF_TAG_PHOTOMETRIC_INTERPRETATION = 262, TIFF_TAG_MAKE = 271, TIFF_TAG_MODEL, TIFF_TAG_STRIP_OFFSETS, TIFF_TAG_ORIENTATION, TIFF_TAG_SAMPLES_PER_PIXEL = 277, TIFF_TAG_ROWS_PER_STRIP, TIFF_TAG_STRIP_BYTE_COUNTS, TIFF_TAG_MIN_SAMPLE_VALUE, TIFF_TAG_MAX_SAMPLE_VALUE, TIFF_TAG_X_RESOLUTION, TIFF_TAG_Y_RESOLUTION, TIFF_TAG_PLANAR_CONFIGURATION, TIFF_TAG_EXTRA_SAMPLES = 338 } TiffTagId; typedef enum { TIFF_EXTRA_SAMPLE_UNSPECIFIED = 0, TIFF_EXTRA_SAMPLE_ASSOC_ALPHA = 1, TIFF_EXTRA_SAMPLE_UNASSOC_ALPHA = 2 } TiffExtraSampleType; #define TIFF_PHOTOMETRIC_INTERPRETATION_RGB 2 #define TIFF_ORIENTATION_TOPLEFT 1 #define TIFF_PLANAR_CONFIGURATION_CONTIGUOUS 1 typedef struct { guint16 tag_id; guint16 type; guint32 count; guint32 data; } TiffTag; typedef struct { ChafaIterm2Canvas *iterm2_canvas; GString *out_str; } BuildCtx; typedef struct { ChafaIterm2Canvas *iterm2_canvas; SmolScaleCtx *scale_ctx; } DrawCtx; ChafaIterm2Canvas * chafa_iterm2_canvas_new (gint width, gint height) { ChafaIterm2Canvas *iterm2_canvas; gsize image_size; if (width < 0 || height < 0) return NULL; image_size = (gsize) width * (gsize) height * sizeof (guint32); /* We wrap pixel data in a TIFF container with u32 offsets. Reject * dimensions whose payload plus header overhead can't be represented * in the wire format. */ if (image_size > (gsize) G_MAXUINT32 - 4096) return NULL; iterm2_canvas = g_new (ChafaIterm2Canvas, 1); iterm2_canvas->width = width; iterm2_canvas->height = height; iterm2_canvas->rgba_image = g_try_malloc (image_size); if (!iterm2_canvas->rgba_image) { g_free (iterm2_canvas); return NULL; } return iterm2_canvas; } void chafa_iterm2_canvas_destroy (ChafaIterm2Canvas *iterm2_canvas) { g_free (iterm2_canvas->rgba_image); g_free (iterm2_canvas); } static void draw_pixels_worker (ChafaBatchInfo *batch, const DrawCtx *ctx) { smol_scale_batch_full (ctx->scale_ctx, ((guint32 *) ctx->iterm2_canvas->rgba_image) + ((gsize) ctx->iterm2_canvas->width * batch->first_row), batch->first_row, batch->n_rows); } void chafa_iterm2_canvas_draw_all_pixels (ChafaIterm2Canvas *iterm2_canvas, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaColor bg_color, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck) { uint8_t bg_color_rgba [4]; DrawCtx ctx; gboolean flatten_alpha; gint placement_x, placement_y; gint placement_width, placement_height; g_return_if_fail (iterm2_canvas != NULL); g_return_if_fail (src_pixel_type < CHAFA_PIXEL_MAX); g_return_if_fail (src_pixels != NULL); g_return_if_fail (src_width >= 0); g_return_if_fail (src_height >= 0); if (src_width == 0 || src_height == 0) return; flatten_alpha = bg_color.ch [3] == 0; bg_color.ch [3] = 0xff; chafa_color8_store_to_rgba8 (bg_color, bg_color_rgba); chafa_tuck_and_align (src_width, src_height, iterm2_canvas->width, iterm2_canvas->height, halign, valign, tuck, &placement_x, &placement_y, &placement_width, &placement_height); ctx.iterm2_canvas = iterm2_canvas; ctx.scale_ctx = smol_scale_new_full (/* Source */ (const guint32 *) src_pixels, (SmolPixelType) src_pixel_type, src_width, src_height, src_rowstride, /* Fill */ flatten_alpha ? bg_color_rgba : NULL, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* Destination */ NULL, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* FIXME: Premul? */ iterm2_canvas->width, iterm2_canvas->height, iterm2_canvas->width * sizeof (guint32), /* Placement */ placement_x * SMOL_SUBPIXEL_MUL, placement_y * SMOL_SUBPIXEL_MUL, placement_width * SMOL_SUBPIXEL_MUL, placement_height * SMOL_SUBPIXEL_MUL, /* Extra args */ SMOL_COMPOSITE_SRC_CLEAR_DEST, SMOL_NO_FLAGS, NULL, &ctx); chafa_process_batches (&ctx, (GFunc) draw_pixels_worker, NULL, iterm2_canvas->height, chafa_get_n_actual_threads (), 1); smol_scale_destroy (ctx.scale_ctx); } static void encode_tag (ChafaBase64 *base64, GString *gs, const TiffTag *tag) { chafa_base64_encode (base64, gs, tag, sizeof (*tag)); } static void generate_tag (ChafaBase64 *base64, GString *gs, guint16 tag_id, guint16 type, guint32 count, guint32 data) { TiffTag tag; tag.tag_id = GUINT16_TO_LE (tag_id); tag.type = GUINT16_TO_LE (type); tag.count = GUINT32_TO_LE (count); tag.data = GUINT32_TO_LE (data); encode_tag (base64, gs, &tag); } void chafa_iterm2_canvas_build_ansi (ChafaIterm2Canvas *iterm2_canvas, ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells) { gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; ChafaBase64 base64; guint32 u32; guint16 u16; gsize image_size = (gsize) iterm2_canvas->width * (gsize) iterm2_canvas->height * sizeof (guint32); *chafa_term_info_emit_begin_iterm2_image (term_info, seq, width_cells, height_cells) = '\0'; g_string_append (out_str, seq); chafa_base64_init (&base64); /* Header and directory offset */ u32 = GUINT32_TO_LE (0x002a4949); chafa_base64_encode (&base64, out_str, &u32, sizeof (u32)); u32 = GUINT32_TO_LE ((guint32) (image_size + sizeof (guint32) * 2)); chafa_base64_encode (&base64, out_str, &u32, sizeof (u32)); /* Image data */ chafa_base64_encode (&base64, out_str, iterm2_canvas->rgba_image, image_size); /* IFD */ u16 = GUINT16_TO_LE (11); /* Tag count */ chafa_base64_encode (&base64, out_str, &u16, sizeof (u16)); /* Tags */ generate_tag (&base64, out_str, TIFF_TAG_IMAGE_WIDTH, TIFF_TYPE_LONG, 1, iterm2_canvas->width); generate_tag (&base64, out_str, TIFF_TAG_IMAGE_LENGTH, TIFF_TYPE_LONG, 1, iterm2_canvas->height); /* For BitsPerSample, the data field points to external data towards the end of file */ generate_tag (&base64, out_str, TIFF_TAG_BITS_PER_SAMPLE, TIFF_TYPE_SHORT, 4, (guint32) (image_size + sizeof (guint32) * 2 + sizeof (guint16) + sizeof (TiffTag) * 11 /* Tag count */ + sizeof (guint32))); generate_tag (&base64, out_str, TIFF_TAG_PHOTOMETRIC_INTERPRETATION, TIFF_TYPE_SHORT, 1, TIFF_PHOTOMETRIC_INTERPRETATION_RGB); generate_tag (&base64, out_str, TIFF_TAG_STRIP_OFFSETS, TIFF_TYPE_LONG, 1, sizeof (guint32) * 2); generate_tag (&base64, out_str, TIFF_TAG_ORIENTATION, TIFF_TYPE_SHORT, 1, TIFF_ORIENTATION_TOPLEFT); generate_tag (&base64, out_str, TIFF_TAG_SAMPLES_PER_PIXEL, TIFF_TYPE_SHORT, 1, 4); generate_tag (&base64, out_str, TIFF_TAG_ROWS_PER_STRIP, TIFF_TYPE_LONG, 1, iterm2_canvas->height); generate_tag (&base64, out_str, TIFF_TAG_STRIP_BYTE_COUNTS, TIFF_TYPE_LONG, 1, (guint32) image_size); generate_tag (&base64, out_str, TIFF_TAG_PLANAR_CONFIGURATION, TIFF_TYPE_SHORT, 1, TIFF_PLANAR_CONFIGURATION_CONTIGUOUS); generate_tag (&base64, out_str, TIFF_TAG_EXTRA_SAMPLES, TIFF_TYPE_SHORT, 1, TIFF_EXTRA_SAMPLE_UNASSOC_ALPHA); /* Next IFD offset (terminator) */ u32 = GUINT32_TO_LE (0); chafa_base64_encode (&base64, out_str, &u32, sizeof (u32)); /* Bits per sample external data */ u16 = GUINT16_TO_LE (8); chafa_base64_encode (&base64, out_str, &u16, sizeof (u16)); chafa_base64_encode (&base64, out_str, &u16, sizeof (u16)); chafa_base64_encode (&base64, out_str, &u16, sizeof (u16)); chafa_base64_encode (&base64, out_str, &u16, sizeof (u16)); chafa_base64_encode_end (&base64, out_str); chafa_base64_deinit (&base64); *chafa_term_info_emit_end_iterm2_image (term_info, seq) = '\0'; g_string_append (out_str, seq); } chafa-1.18.2/chafa/internal/chafa-iterm2-canvas.h000066400000000000000000000035561517447374300214370ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_ITERM2_CANVAS_H__ #define __CHAFA_ITERM2_CANVAS_H__ #include "chafa.h" G_BEGIN_DECLS typedef struct { gint width, height; gpointer rgba_image; } ChafaIterm2Canvas; ChafaIterm2Canvas *chafa_iterm2_canvas_new (gint width, gint height); void chafa_iterm2_canvas_destroy (ChafaIterm2Canvas *iterm2_canvas); void chafa_iterm2_canvas_draw_all_pixels (ChafaIterm2Canvas *iterm2_canvas, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaColor bg_color, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck); void chafa_iterm2_canvas_build_ansi (ChafaIterm2Canvas *iterm2_canvas, ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells); G_END_DECLS #endif /* __CHAFA_ITERM2_CANVAS_H__ */ chafa-1.18.2/chafa/internal/chafa-kitty-canvas.c000066400000000000000000000434351517447374300213740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "smolscale/smolscale.h" #include "internal/chafa-base64.h" #include "internal/chafa-batch.h" #include "internal/chafa-bitfield.h" #include "internal/chafa-indexed-image.h" #include "internal/chafa-math-util.h" #include "internal/chafa-kitty-canvas.h" #include "internal/chafa-passthrough-encoder.h" #include "internal/chafa-pixops.h" #include "internal/chafa-string-util.h" typedef struct { ChafaKittyCanvas *kitty_canvas; GString *out_str; } BuildCtx; typedef struct { ChafaKittyCanvas *kitty_canvas; SmolScaleCtx *scale_ctx; } DrawCtx; /* Kitty's cell-based placeholders use Unicode diacritics to encode each * cell's row/col offsets. The below table maps integers to code points * using this scheme. */ #define ROWCOLUMN_UNICHAR 0x10eeeeU #define ENCODING_DIACRITIC_MAX 297 static const guint32 encoding_diacritics [ENCODING_DIACRITIC_MAX] = { 0x0305, 0x030d, 0x030e, 0x0310, 0x0312, 0x033d, 0x033e, 0x033f, 0x0346, 0x034a, 0x034b, 0x034c, 0x0350, 0x0351, 0x0352, 0x0357, 0x035b, 0x0363, 0x0364, 0x0365, 0x0366, 0x0367, 0x0368, 0x0369, 0x036a, 0x036b, 0x036c, 0x036d, 0x036e, 0x036f, 0x0483, 0x0484, 0x0485, 0x0486, 0x0487, 0x0592, 0x0593, 0x0594, 0x0595, 0x0597, 0x0598, 0x0599, 0x059c, 0x059d, 0x059e, 0x059f, 0x05a0, 0x05a1, 0x05a8, 0x05a9, 0x05ab, 0x05ac, 0x05af, 0x05c4, 0x0610, 0x0611, 0x0612, 0x0613, 0x0614, 0x0615, 0x0616, 0x0617, 0x0657, 0x0658, 0x0659, 0x065a, 0x065b, 0x065d, 0x065e, 0x06d6, 0x06d7, 0x06d8, 0x06d9, 0x06da, 0x06db, 0x06dc, 0x06df, 0x06e0, 0x06e1, 0x06e2, 0x06e4, 0x06e7, 0x06e8, 0x06eb, 0x06ec, 0x0730, 0x0732, 0x0733, 0x0735, 0x0736, 0x073a, 0x073d, 0x073f, 0x0740, 0x0741, 0x0743, 0x0745, 0x0747, 0x0749, 0x074a, 0x07eb, 0x07ec, 0x07ed, 0x07ee, 0x07ef, 0x07f0, 0x07f1, 0x07f3, 0x0816, 0x0817, 0x0818, 0x0819, 0x081b, 0x081c, 0x081d, 0x081e, 0x081f, 0x0820, 0x0821, 0x0822, 0x0823, 0x0825, 0x0826, 0x0827, 0x0829, 0x082a, 0x082b, 0x082c, /* 128 */ 0x082d, 0x0951, 0x0953, 0x0954, 0x0f82, 0x0f83, 0x0f86, 0x0f87, 0x135d, 0x135e, 0x135f, 0x17dd, 0x193a, 0x1a17, 0x1a75, 0x1a76, 0x1a77, 0x1a78, 0x1a79, 0x1a7a, 0x1a7b, 0x1a7c, 0x1b6b, 0x1b6d, 0x1b6e, 0x1b6f, 0x1b70, 0x1b71, 0x1b72, 0x1b73, 0x1cd0, 0x1cd1, 0x1cd2, 0x1cda, 0x1cdb, 0x1ce0, 0x1dc0, 0x1dc1, 0x1dc3, 0x1dc4, 0x1dc5, 0x1dc6, 0x1dc7, 0x1dc8, 0x1dc9, 0x1dcb, 0x1dcc, 0x1dd1, 0x1dd2, 0x1dd3, 0x1dd4, 0x1dd5, 0x1dd6, 0x1dd7, 0x1dd8, 0x1dd9, 0x1dda, 0x1ddb, 0x1ddc, 0x1ddd, 0x1dde, 0x1ddf, 0x1de0, 0x1de1, 0x1de2, 0x1de3, 0x1de4, 0x1de5, 0x1de6, 0x1dfe, 0x20d0, 0x20d1, 0x20d4, 0x20d5, 0x20d6, 0x20d7, 0x20db, 0x20dc, 0x20e1, 0x20e7, 0x20e9, 0x20f0, 0x2cef, 0x2cf0, 0x2cf1, 0x2de0, 0x2de1, 0x2de2, 0x2de3, 0x2de4, 0x2de5, 0x2de6, 0x2de7, 0x2de8, 0x2de9, 0x2dea, 0x2deb, 0x2dec, 0x2ded, 0x2dee, 0x2def, 0x2df0, 0x2df1, 0x2df2, 0x2df3, 0x2df4, 0x2df5, 0x2df6, 0x2df7, 0x2df8, 0x2df9, 0x2dfa, 0x2dfb, 0x2dfc, 0x2dfd, 0x2dfe, 0x2dff, 0xa66f, 0xa67c, 0xa67d, 0xa6f0, 0xa6f1, 0xa8e0, 0xa8e1, 0xa8e2, 0xa8e3, 0xa8e4, 0xa8e5, /* 256 */ 0xa8e6, 0xa8e7, 0xa8e8, 0xa8e9, 0xa8ea, 0xa8eb, 0xa8ec, 0xa8ed, 0xa8ee, 0xa8ef, 0xa8f0, 0xa8f1, 0xaab0, 0xaab2, 0xaab3, 0xaab7, 0xaab8, 0xaabe, 0xaabf, 0xaac1, 0xfe20, 0xfe21, 0xfe22, 0xfe23, 0xfe24, 0xfe25, 0xfe26, 0x10a0f, 0x10a38, 0x1d185, 0x1d186, 0x1d187, 0x1d188, 0x1d189, 0x1d1aa, 0x1d1ab, 0x1d1ac, 0x1d1ad, 0x1d242, 0x1d243, 0x1d244 /* 297 */ }; ChafaKittyCanvas * chafa_kitty_canvas_new (gint width, gint height) { ChafaKittyCanvas *kitty_canvas; kitty_canvas = g_new0 (ChafaKittyCanvas, 1); kitty_canvas->width = width; kitty_canvas->height = height; kitty_canvas->rgba_image = g_try_malloc ((gsize) width * height * sizeof (guint32)); if (!kitty_canvas->rgba_image) { #if 0 g_warning ("ChafaKittyCanvas: Out of memory allocating %ux%u pixels.", width, height); #endif g_free (kitty_canvas); kitty_canvas = NULL; } return kitty_canvas; } void chafa_kitty_canvas_destroy (ChafaKittyCanvas *kitty_canvas) { g_free (kitty_canvas->rgba_image); g_free (kitty_canvas); } static void draw_pixels_worker (ChafaBatchInfo *batch, const DrawCtx *ctx) { smol_scale_batch_full (ctx->scale_ctx, ((guint32 *) ctx->kitty_canvas->rgba_image) + ((gsize) ctx->kitty_canvas->width * batch->first_row), batch->first_row, batch->n_rows); } void chafa_kitty_canvas_draw_all_pixels (ChafaKittyCanvas *kitty_canvas, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaColor bg_color, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck) { uint8_t bg_color_rgba [4]; DrawCtx ctx; gboolean flatten_alpha; gint placement_x, placement_y; gint placement_width, placement_height; g_return_if_fail (kitty_canvas != NULL); g_return_if_fail (src_pixel_type < CHAFA_PIXEL_MAX); g_return_if_fail (src_pixels != NULL); g_return_if_fail (src_width >= 0); g_return_if_fail (src_height >= 0); if (src_width == 0 || src_height == 0) return; flatten_alpha = bg_color.ch [3] == 0; bg_color.ch [3] = 0xff; chafa_color8_store_to_rgba8 (bg_color, bg_color_rgba); chafa_tuck_and_align (src_width, src_height, kitty_canvas->width, kitty_canvas->height, halign, valign, tuck, &placement_x, &placement_y, &placement_width, &placement_height); ctx.kitty_canvas = kitty_canvas; ctx.scale_ctx = smol_scale_new_full (/* Source */ (const guint32 *) src_pixels, (SmolPixelType) src_pixel_type, src_width, src_height, src_rowstride, /* Fill */ flatten_alpha ? bg_color_rgba : NULL, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* Destination */ NULL, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* FIXME: Opaque? */ kitty_canvas->width, kitty_canvas->height, kitty_canvas->width * sizeof (guint32), /* Placement */ placement_x * SMOL_SUBPIXEL_MUL, placement_y * SMOL_SUBPIXEL_MUL, placement_width * SMOL_SUBPIXEL_MUL, placement_height * SMOL_SUBPIXEL_MUL, /* Extra args */ SMOL_COMPOSITE_SRC_CLEAR_DEST, SMOL_NO_FLAGS, NULL, &ctx); chafa_process_batches (&ctx, (GFunc) draw_pixels_worker, NULL, kitty_canvas->height, chafa_get_n_actual_threads (), 1); smol_scale_destroy (ctx.scale_ctx); } static void encode_chunk (GString *gs, const guint8 *start, const guint8 *end) { ChafaBase64 base64; chafa_base64_init (&base64); chafa_base64_encode (&base64, gs, start, end - start); chafa_base64_encode_end (&base64, gs); chafa_base64_deinit (&base64); } static void end_passthrough (ChafaPassthroughEncoder *ptenc) { gchar buf [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; if (ptenc->mode == CHAFA_PASSTHROUGH_SCREEN) { gint i; *chafa_term_info_emit_end_screen_passthrough (ptenc->term_info, buf) = '\0'; for (i = 0; buf [i]; i++) { chafa_passthrough_encoder_flush (ptenc); chafa_passthrough_encoder_append_len (ptenc, buf + i, 1); } } else if (ptenc->mode == CHAFA_PASSTHROUGH_TMUX) { *chafa_term_info_emit_end_tmux_passthrough (ptenc->term_info, buf) = '\0'; chafa_passthrough_encoder_flush (ptenc); g_string_append (ptenc->out, buf); } chafa_passthrough_encoder_flush (ptenc); } static void build_image_chunks (ChafaKittyCanvas *kitty_canvas, ChafaPassthroughEncoder *ptenc) { const guint8 *p, *last; gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; last = ((guint8 *) kitty_canvas->rgba_image) + (gsize) kitty_canvas->width * (gsize) kitty_canvas->height * sizeof (guint32); for (p = kitty_canvas->rgba_image; p < last; ) { const guint8 *end; end = p + (ptenc->mode == CHAFA_PASSTHROUGH_SCREEN ? 63 : 510); if (end > last) end = last; *chafa_term_info_emit_begin_kitty_image_chunk (ptenc->term_info, seq) = '\0'; chafa_passthrough_encoder_append (ptenc, seq); encode_chunk (ptenc->out, p, end); *chafa_term_info_emit_end_kitty_image_chunk (ptenc->term_info, seq) = '\0'; chafa_passthrough_encoder_append (ptenc, seq); chafa_passthrough_encoder_reset (ptenc); end_passthrough (ptenc); p = end; } *chafa_term_info_emit_end_kitty_image (ptenc->term_info, seq) = '\0'; chafa_passthrough_encoder_append (ptenc, seq); chafa_passthrough_encoder_reset (ptenc); end_passthrough (ptenc); } static void build_immediate (ChafaKittyCanvas *kitty_canvas, ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells) { ChafaPassthroughEncoder ptenc; gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; chafa_passthrough_encoder_begin (&ptenc, CHAFA_PASSTHROUGH_NONE, term_info, out_str); *chafa_term_info_emit_begin_kitty_immediate_image_v1 (term_info, seq, 32, kitty_canvas->width, kitty_canvas->height, width_cells, height_cells) = '\0'; chafa_passthrough_encoder_append (&ptenc, seq); chafa_passthrough_encoder_flush (&ptenc); build_image_chunks (kitty_canvas, &ptenc); chafa_passthrough_encoder_end (&ptenc); } static gboolean screen_is_wide_diacritic (gint diacritic_index) { if (diacritic_index == 35 || diacritic_index == 61 || diacritic_index == 62) return TRUE; return FALSE; } static void build_begin_row (ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint row, ChafaPassthrough passthrough) { gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX * 2 + 1]; gchar *p0; if (row > 0) { /* Screen advances the cursor by one position too much for some of the * diacritics. We compensate for the first few, since they will come up * fairly frequently. We don't compensate for every single instance, * since Screen only exhibits this behavior when printing and scrolling * up in the current dpy, and not when scrolling down or redrawing after * switching dpys, making the corrected graphics illegible in those * cases. * * I.e. there's no perfect workaround here, so we try to make the common * case look good and the uncommon case not terrible. * * Another option would've been to save/restore the cursor position * between rows, but we don't want to clobber the register, as the CLI * tool uses it to home the cursor between animation frames. It's * also good policy in general to reserve it for client use. */ p0 = chafa_term_info_emit_cursor_left (term_info, seq, width_cells + ((passthrough == CHAFA_PASSTHROUGH_SCREEN && screen_is_wide_diacritic (row)) ? 1 : 0)); p0 = chafa_term_info_emit_cursor_down_scroll (term_info, p0); g_string_append_len (out_str, seq, p0 - seq); } } static void build_unicode_placement (ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells, gint placement_id, ChafaPassthrough passthrough) { gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX * 2 + 1]; gchar *p0; gchar *row; gint row_ofs; gint i, j; g_assert (placement_id >= 1); g_assert (placement_id <= 255); width_cells = MIN (width_cells, ENCODING_DIACRITIC_MAX - 1); height_cells = MIN (height_cells, ENCODING_DIACRITIC_MAX - 1); row = g_malloc ((gsize) width_cells * (6 * 3) + 1); for (i = 0; i < height_cells; i++) { /* Reposition after previous row */ build_begin_row (term_info, out_str, width_cells, i, passthrough); /* Encode the image ID in the foreground color */ p0 = chafa_term_info_emit_set_color_fg_256 (term_info, seq, placement_id); g_string_append_len (out_str, seq, p0 - seq); /* Print the row */ row_ofs = 0; for (j = 0; j < width_cells; j++) { row_ofs += g_unichar_to_utf8 (ROWCOLUMN_UNICHAR, row + row_ofs); /* Screen has issues with some diacritics. We can compensate for this once * per row, but doing it for every col is pushing it. So we omit all offsets * except the row offsets in the first col. This harms overlapping images * and horizontal scrolling, but oh well. */ if (passthrough != CHAFA_PASSTHROUGH_SCREEN || j == 0) row_ofs += g_unichar_to_utf8 (encoding_diacritics [i], row + row_ofs); if (passthrough != CHAFA_PASSTHROUGH_SCREEN) row_ofs += g_unichar_to_utf8 (encoding_diacritics [j], row + row_ofs); } g_string_append_len (out_str, row, row_ofs); } /* Reset foreground color */ p0 = chafa_term_info_emit_reset_color_fg (term_info, seq); g_string_append_len (out_str, seq, p0 - seq); g_free (row); } static void build_unicode_virtual (ChafaKittyCanvas *kitty_canvas, ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells, gint placement_id, ChafaPassthrough passthrough) { ChafaPassthroughEncoder ptenc; gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; chafa_passthrough_encoder_begin (&ptenc, passthrough, term_info, out_str); *chafa_term_info_emit_begin_kitty_immediate_virt_image_v1 (term_info, seq, 32, kitty_canvas->width, kitty_canvas->height, width_cells, height_cells, placement_id) = '\0'; chafa_passthrough_encoder_append (&ptenc, seq); chafa_passthrough_encoder_reset (&ptenc); end_passthrough (&ptenc); build_image_chunks (kitty_canvas, &ptenc); end_passthrough (&ptenc); chafa_passthrough_encoder_end (&ptenc); build_unicode_placement (term_info, out_str, width_cells, height_cells, placement_id, passthrough); } void chafa_kitty_canvas_build_ansi (ChafaKittyCanvas *kitty_canvas, ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells, gint placement_id, ChafaPassthrough passthrough) { if (passthrough == CHAFA_PASSTHROUGH_NONE) { build_immediate (kitty_canvas, term_info, out_str, width_cells, height_cells); } else { /* Make IDs in the first <256 range predictable, but as the range * cycles we add one to skip over every ID==0 */ if (placement_id < 1) placement_id = 1; else if (placement_id > 255) placement_id = 1 + (placement_id % 255); build_unicode_virtual (kitty_canvas, term_info, out_str, width_cells, height_cells, placement_id, passthrough); } } chafa-1.18.2/chafa/internal/chafa-kitty-canvas.h000066400000000000000000000037731517447374300214020ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_KITTY_CANVAS_H__ #define __CHAFA_KITTY_CANVAS_H__ #include "chafa.h" G_BEGIN_DECLS typedef struct { gint width, height; gpointer rgba_image; } ChafaKittyCanvas; ChafaKittyCanvas *chafa_kitty_canvas_new (gint width, gint height); void chafa_kitty_canvas_destroy (ChafaKittyCanvas *kitty_canvas); void chafa_kitty_canvas_draw_all_pixels (ChafaKittyCanvas *kitty_canvas, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaColor bg_color, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck); void chafa_kitty_canvas_build_ansi (ChafaKittyCanvas *kitty_canvas, ChafaTermInfo *term_info, GString *out_str, gint width_cells, gint height_cells, gint placement_id, ChafaPassthrough passthrough); G_END_DECLS #endif /* __CHAFA_KITTY_CANVAS_H__ */ chafa-1.18.2/chafa/internal/chafa-math-util.c000066400000000000000000000065301517447374300206560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "internal/chafa-private.h" #include "internal/chafa-math-util.h" static gint align_dim (ChafaAlign align, gint src_size, gint dest_size) { gint ofs; g_return_val_if_fail (src_size <= dest_size, 0); switch (align) { case CHAFA_ALIGN_START: ofs = 0; break; case CHAFA_ALIGN_CENTER: ofs = (dest_size - src_size) / 2; break; case CHAFA_ALIGN_END: ofs = dest_size - src_size; break; default: g_assert_not_reached (); } return ofs; } void chafa_tuck_and_align (gint src_width, gint src_height, gint dest_width, gint dest_height, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck, gint *ofs_x_out, gint *ofs_y_out, gint *width_out, gint *height_out) { gfloat ratio [2]; switch (tuck) { case CHAFA_TUCK_STRETCH: *ofs_x_out = 0; *ofs_y_out = 0; *width_out = dest_width; *height_out = dest_height; break; case CHAFA_TUCK_SHRINK_TO_FIT: if (src_width <= dest_width && src_height <= dest_height) { /* Image fits entirely in dest. Do alignment only, no scaling. */ *width_out = src_width; *height_out = src_height; break; } /* Fall through */ case CHAFA_TUCK_FIT: ratio [0] = (gfloat) dest_width / (gfloat) src_width; ratio [1] = (gfloat) dest_height / (gfloat) src_height; *width_out = ceilf (src_width * MIN (ratio [0], ratio [1])); *height_out = ceilf (src_height * MIN (ratio [0], ratio [1])); break; default: g_assert_not_reached (); } /* Never exceed the dest size */ *width_out = MIN (*width_out, dest_width); *height_out = MIN (*height_out, dest_height); *ofs_x_out = align_dim (halign, *width_out, dest_width); *ofs_y_out = align_dim (valign, *height_out, dest_height); #if 0 g_printerr ("src=(%dx%d) dest=(%dx%d) out=(%dx%d) @ (%d,%d)\n", src_width, src_height, dest_width, dest_height, *width_out, *height_out, *ofs_x_out, *ofs_y_out); #endif } gint chafa_round_up_to_multiple_of (gint value, gint m) { value = value + m - 1; return value - (value % m); } chafa-1.18.2/chafa/internal/chafa-math-util.h000066400000000000000000000026501517447374300206620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_MATH_UTIL_H__ #define __CHAFA_MATH_UTIL_H__ #include G_BEGIN_DECLS #define CHAFA_SQUARE(n) ((n) * (n)) void chafa_tuck_and_align (gint src_width, gint src_height, gint dest_width, gint dest_height, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck, gint *ofs_x_out, gint *ofs_y_out, gint *width_out, gint *height_out); gint chafa_round_up_to_multiple_of (gint value, gint m); G_END_DECLS #endif /* __CHAFA_MATH_UTIL_H__ */ chafa-1.18.2/chafa/internal/chafa-mmx.c000066400000000000000000000030461517447374300175520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chafa.h" #include "internal/chafa-private.h" void chafa_extract_cell_mean_colors_mmx (const ChafaPixel *pixels, ChafaColorAccum *accums_out, const guint8 *cov) { __m64 accum [2] = { 0 }; __m64 m64b; gint i; m64b = _mm_setzero_si64 (); for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { __m64 *m64p1; __m64 m64a; m64p1 = &accum [cov [i]]; m64a = _mm_cvtsi32_si64 (chafa_color8_to_u32 (pixels [i].col)); m64a = _mm_unpacklo_pi8 (m64a, m64b); *m64p1 = _mm_adds_pi16 (*m64p1, m64a); } ((__m64 *) accums_out) [0] = accum [0]; ((__m64 *) accums_out) [1] = accum [1]; _mm_empty (); } chafa-1.18.2/chafa/internal/chafa-noise.c000066400000000000000000002247311517447374300200740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-noise.h" /* Blue noise texture from https://momentsingraphics.de/BlueNoise.html by * Christoph Peters. Generated by void and cluster method. Released under * Creative Commons CC0 Public Domain Dedication (thanks!). * * LDR_RGB1_0.png */ static const unsigned char blue_noise_src [CHAFA_NOISE_TEXTURE_ARRAY_LEN] = { 0xda, 0x15, 0x5b, 0x6e, 0xdd, 0x6d, 0xa6, 0x9c, 0xd4, 0x1c, 0x0b, 0x4a, 0xe6, 0x75, 0x7e, 0x3a, 0xf6, 0x66, 0x9f, 0x8d, 0x10, 0x48, 0x08, 0xaa, 0x05, 0xd9, 0x78, 0xa7, 0x60, 0x00, 0x79, 0xb6, 0x3f, 0xd2, 0xe0, 0x6a, 0x8f, 0x56, 0x26, 0x51, 0x25, 0x07, 0x19, 0x65, 0x39, 0x42, 0xa7, 0xc1, 0xe2, 0x49, 0x1f, 0xf2, 0xe6, 0x32, 0x9f, 0x68, 0xfe, 0x4f, 0xac, 0x87, 0x7a, 0x8d, 0xbc, 0xb4, 0xcc, 0x28, 0xf0, 0x5b, 0xea, 0x6d, 0xa2, 0x6a, 0xbd, 0xc2, 0xfc, 0xdb, 0x93, 0xa2, 0x1f, 0xb4, 0xb5, 0x4f, 0x72, 0xe8, 0x6c, 0x2e, 0x42, 0x9a, 0x59, 0x97, 0x58, 0x4b, 0x2b, 0x2e, 0xd1, 0xf1, 0xe9, 0xa3, 0x39, 0xde, 0x80, 0x7f, 0x52, 0xc9, 0x68, 0x9e, 0x17, 0xd6, 0xcb, 0xe9, 0x44, 0x5e, 0x69, 0x31, 0x95, 0x24, 0xab, 0x41, 0x32, 0x79, 0xfb, 0x7c, 0xcd, 0x9f, 0xb0, 0x43, 0x5d, 0x20, 0x64, 0xbd, 0x88, 0xb3, 0xed, 0xee, 0x77, 0x95, 0xbc, 0x20, 0x01, 0x93, 0xa1, 0xa3, 0x5a, 0x0e, 0xf3, 0x9e, 0xae, 0x73, 0x35, 0xcd, 0x39, 0x67, 0xf2, 0x7e, 0x55, 0x58, 0xe1, 0x90, 0xd7, 0x9f, 0xb9, 0x12, 0x77, 0x78, 0xe9, 0x49, 0xcd, 0xc2, 0xea, 0x0f, 0x3c, 0xb8, 0xe1, 0xa2, 0x1f, 0x92, 0x4c, 0x74, 0xc1, 0x8a, 0xaf, 0x6a, 0xf6, 0x4f, 0x53, 0x68, 0x9c, 0xef, 0xbf, 0x5e, 0xc5, 0x33, 0x0b, 0x35, 0xdc, 0x8e, 0xb7, 0x89, 0xf2, 0x4e, 0x04, 0x7c, 0xce, 0x9b, 0x63, 0x42, 0xe3, 0xc3, 0xb1, 0x1d, 0x2a, 0x30, 0xb8, 0xb8, 0x51, 0x4d, 0xe1, 0x7e, 0x34, 0xf6, 0x94, 0xf3, 0x22, 0x14, 0x59, 0x10, 0x73, 0xb2, 0x6c, 0x0d, 0xdc, 0xfd, 0x87, 0x4f, 0xa6, 0xd9, 0x99, 0x76, 0x3c, 0xeb, 0x58, 0x93, 0xad, 0x2b, 0x76, 0x72, 0xba, 0x20, 0x96, 0x8b, 0x2f, 0x3f, 0x35, 0x0a, 0x62, 0x5e, 0x6f, 0x7e, 0xa6, 0xf5, 0xac, 0x26, 0x0f, 0x3a, 0x57, 0xe8, 0x01, 0x78, 0x1c, 0x76, 0x33, 0x3b, 0x5c, 0xc7, 0xf4, 0x34, 0x83, 0xa1, 0x0f, 0x00, 0x01, 0x68, 0xb8, 0x92, 0xca, 0x88, 0x77, 0x4b, 0x1d, 0x0e, 0xa6, 0xa6, 0x2a, 0xc0, 0x3a, 0x52, 0x27, 0xfe, 0x95, 0xf4, 0x73, 0x87, 0x99, 0x01, 0x48, 0x4f, 0xb8, 0xde, 0xec, 0x55, 0xbb, 0x90, 0xcd, 0x91, 0x57, 0x35, 0xe6, 0x2b, 0xde, 0x66, 0x8c, 0x2b, 0x09, 0x01, 0x16, 0x39, 0xc7, 0xd8, 0x51, 0x51, 0x6b, 0x2b, 0x6c, 0x84, 0xe5, 0xe2, 0xcf, 0xcd, 0x37, 0x4a, 0x0d, 0x63, 0x93, 0xfb, 0x77, 0xef, 0xa4, 0x19, 0x2e, 0x43, 0x30, 0x55, 0x04, 0x6c, 0x00, 0x64, 0x9a, 0xaa, 0x24, 0x5d, 0x33, 0xb4, 0x1e, 0x59, 0x5e, 0xef, 0xfd, 0x31, 0x72, 0x42, 0xd7, 0xda, 0xca, 0xa8, 0x25, 0x13, 0x29, 0x99, 0x81, 0x0e, 0x83, 0xc4, 0x93, 0x1b, 0x45, 0xf9, 0xf8, 0x57, 0x70, 0x3f, 0x27, 0x2a, 0xb1, 0xaf, 0xa8, 0x61, 0x08, 0x5e, 0x2b, 0xfb, 0xd5, 0x8f, 0x8f, 0x16, 0xfb, 0x14, 0xbe, 0x6d, 0x80, 0xff, 0xca, 0x5f, 0x48, 0x93, 0x98, 0xcf, 0x1a, 0x44, 0x36, 0xc6, 0xdd, 0x9a, 0x73, 0x34, 0xc8, 0xfa, 0xc2, 0xef, 0x15, 0x07, 0x00, 0x7e, 0x94, 0xc1, 0xd9, 0xc9, 0xd4, 0x03, 0x65, 0x54, 0xc7, 0xfc, 0xf0, 0xe3, 0x1f, 0x47, 0x12, 0x99, 0x96, 0x1e, 0xcb, 0xb1, 0xc4, 0x46, 0x29, 0x95, 0xf9, 0x84, 0xe1, 0x94, 0x52, 0xbe, 0xa9, 0xcf, 0x8b, 0xf4, 0x61, 0xf6, 0x42, 0x80, 0x9e, 0xee, 0xc7, 0xe2, 0xd6, 0xae, 0xb1, 0x70, 0xeb, 0x0a, 0xc5, 0x69, 0xeb, 0x64, 0xdb, 0x93, 0x92, 0xfb, 0x57, 0x12, 0xaa, 0x01, 0x47, 0x08, 0xc8, 0x85, 0xef, 0x82, 0xe4, 0x9e, 0x0e, 0x1f, 0x13, 0xb8, 0x7e, 0x3f, 0x20, 0xb3, 0x53, 0xe5, 0x05, 0x9b, 0xa4, 0x8d, 0xcd, 0xd7, 0xa9, 0x75, 0xf1, 0x3b, 0xb5, 0x2e, 0x54, 0x83, 0xb8, 0x2f, 0x6b, 0xfc, 0x1e, 0x21, 0x8f, 0xb7, 0xaf, 0x08, 0x07, 0x79, 0xa6, 0x69, 0x2a, 0xbc, 0xaf, 0xd0, 0xed, 0xcd, 0x83, 0x8d, 0x89, 0xf4, 0x45, 0xdb, 0x9d, 0xd3, 0xc2, 0x3f, 0x84, 0x7f, 0x7d, 0x2e, 0x98, 0xfb, 0xac, 0x28, 0x17, 0x11, 0x63, 0x75, 0x3a, 0xe1, 0xe9, 0xc8, 0x34, 0xb0, 0x49, 0xed, 0x60, 0xa2, 0xa3, 0x1f, 0xbb, 0xcf, 0xe2, 0x74, 0xe1, 0x87, 0x15, 0x36, 0x04, 0xef, 0x87, 0xea, 0xc3, 0x50, 0x7a, 0x58, 0xd6, 0x9a, 0x41, 0x6f, 0x6c, 0xd8, 0x3c, 0xa6, 0x24, 0xae, 0x27, 0xa0, 0xcd, 0xe6, 0xe6, 0x87, 0x64, 0x89, 0xb4, 0xba, 0x2c, 0x62, 0x4e, 0xab, 0x25, 0x2d, 0x62, 0x84, 0x5e, 0x42, 0xdb, 0x19, 0x59, 0x3c, 0xb0, 0x29, 0x0e, 0x85, 0x4c, 0x49, 0xdf, 0xa5, 0xdf, 0xbc, 0xf8, 0x06, 0x7a, 0x54, 0xe6, 0x38, 0xd3, 0x87, 0xd7, 0x46, 0x0f, 0x67, 0x29, 0xd2, 0x9d, 0x16, 0x17, 0x08, 0x4c, 0x63, 0xe4, 0xc5, 0x26, 0x26, 0x24, 0xa1, 0x46, 0x58, 0x35, 0x1d, 0x78, 0x0d, 0x34, 0x88, 0x4b, 0xb7, 0x19, 0xee, 0x42, 0x71, 0x24, 0x1f, 0x3c, 0xd0, 0x62, 0xb9, 0xac, 0x3b, 0x60, 0xf2, 0xb4, 0xe1, 0x2a, 0x5c, 0x6a, 0xa4, 0x74, 0x3b, 0x6d, 0xfd, 0xf9, 0x4a, 0x29, 0x72, 0xf5, 0xc0, 0x49, 0x61, 0xde, 0x7f, 0x74, 0x17, 0x14, 0xba, 0xfa, 0x9b, 0xfe, 0x00, 0x5a, 0xdf, 0x45, 0x1d, 0x9e, 0xc3, 0x7d, 0xe8, 0x8b, 0xdb, 0x5d, 0x4d, 0x50, 0xc5, 0xe7, 0x3f, 0x12, 0xc0, 0xcb, 0xf5, 0x14, 0x24, 0x23, 0xd9, 0xb0, 0x64, 0x55, 0xf9, 0x16, 0xc6, 0x15, 0xe5, 0xa5, 0xbb, 0x0c, 0x00, 0x91, 0xd4, 0x4a, 0x5a, 0x8e, 0x8d, 0xd4, 0xa9, 0xcc, 0x79, 0x6f, 0x82, 0xeb, 0x19, 0x45, 0x0e, 0x7a, 0xa1, 0x51, 0x94, 0x55, 0x94, 0x10, 0xc4, 0xd1, 0x6a, 0x94, 0x39, 0xc8, 0x38, 0xa3, 0x9d, 0x22, 0x07, 0x21, 0xf1, 0xb4, 0xbe, 0x3f, 0x82, 0xf0, 0x02, 0x0f, 0x2f, 0x89, 0x60, 0x51, 0xad, 0x3c, 0x09, 0x1d, 0x4b, 0xf5, 0xf7, 0x0b, 0x9e, 0x7f, 0x92, 0x48, 0xa4, 0xbc, 0xef, 0xea, 0xcc, 0xa8, 0x6d, 0xef, 0x6d, 0x37, 0x8e, 0xb1, 0x9c, 0xb8, 0x80, 0x07, 0x80, 0xbe, 0x61, 0x31, 0x72, 0xcb, 0x70, 0x2e, 0x1e, 0x88, 0x68, 0xec, 0xf3, 0x3e, 0x45, 0x64, 0xb8, 0xac, 0x81, 0x53, 0x78, 0xdb, 0xe1, 0xb8, 0x6f, 0x74, 0x8d, 0x06, 0xc2, 0xff, 0xd4, 0x5a, 0xd3, 0x44, 0x96, 0x5b, 0x32, 0xb2, 0x86, 0xcd, 0xda, 0x9f, 0xdc, 0x7f, 0xc3, 0xfd, 0x57, 0xd6, 0xa8, 0xbf, 0x7d, 0x14, 0x65, 0x2c, 0x2e, 0x3d, 0xd1, 0xa3, 0xd6, 0xc5, 0xd1, 0x0c, 0x04, 0x95, 0xe2, 0xa8, 0x0a, 0x98, 0x7f, 0xb2, 0xc7, 0x48, 0x61, 0x46, 0x5e, 0x3d, 0x08, 0x94, 0x8a, 0x8a, 0xa7, 0xd2, 0x13, 0xd5, 0x46, 0x7b, 0xf1, 0xc5, 0x3f, 0x13, 0x29, 0x28, 0x9a, 0xf6, 0x99, 0x5e, 0x5f, 0x4e, 0x36, 0x9f, 0x74, 0x6f, 0x03, 0x38, 0x93, 0x79, 0xa4, 0x2d, 0x51, 0x46, 0x1c, 0x65, 0x71, 0x69, 0xe0, 0xb0, 0xed, 0x41, 0x54, 0xba, 0xfc, 0x3e, 0x59, 0x06, 0xf4, 0x36, 0xb0, 0x23, 0x06, 0x60, 0xba, 0xd5, 0x2f, 0x3a, 0x77, 0xe6, 0xff, 0x17, 0x68, 0x4a, 0xf5, 0x25, 0xb4, 0x65, 0x84, 0xed, 0xb9, 0xda, 0x5b, 0x53, 0x76, 0x42, 0xca, 0xe9, 0x00, 0xdb, 0x31, 0xa2, 0x5d, 0xac, 0xe6, 0xc5, 0xf6, 0x17, 0x78, 0xc0, 0xc3, 0x3d, 0x7c, 0x71, 0x07, 0xd5, 0x1c, 0x90, 0xe9, 0xd3, 0x43, 0x36, 0x54, 0xb9, 0x21, 0x13, 0x7b, 0xa1, 0xf6, 0xfe, 0x11, 0x23, 0x26, 0x68, 0xd5, 0x40, 0xdb, 0x91, 0xa7, 0x07, 0x51, 0x12, 0xb1, 0xab, 0x56, 0x9b, 0xc5, 0x88, 0x0f, 0x9f, 0xc0, 0xba, 0x7b, 0xf8, 0xa3, 0x04, 0x17, 0x30, 0x8b, 0x36, 0xad, 0xb0, 0x4f, 0x92, 0x1b, 0x6b, 0xee, 0x81, 0x98, 0xba, 0xf3, 0x16, 0xa1, 0x3e, 0xf2, 0x64, 0x75, 0x03, 0x4e, 0x05, 0x70, 0x23, 0x31, 0x90, 0x78, 0x8e, 0xf7, 0x88, 0x16, 0x1b, 0xf0, 0x9b, 0x4c, 0x4c, 0xc2, 0x89, 0x1c, 0x5a, 0x64, 0x59, 0x84, 0xec, 0xc8, 0x1a, 0x1d, 0x33, 0x28, 0x34, 0xf5, 0xec, 0xb2, 0xc1, 0xd3, 0xe8, 0xe3, 0x5b, 0x2c, 0x04, 0xac, 0x55, 0x72, 0xc4, 0x39, 0xae, 0x6d, 0x73, 0x96, 0xf9, 0xdc, 0x13, 0xd5, 0x04, 0x85, 0x84, 0xaa, 0x6e, 0xbd, 0x47, 0xe5, 0xe8, 0xfe, 0x34, 0x95, 0xb1, 0xc5, 0xd0, 0xde, 0x0c, 0x2f, 0x85, 0x9b, 0xf8, 0xca, 0x7d, 0xbf, 0x98, 0xc2, 0x02, 0x23, 0x6e, 0x85, 0xe5, 0x21, 0xcc, 0x66, 0x8f, 0x5d, 0xbc, 0xcd, 0x05, 0x31, 0x01, 0xd9, 0x40, 0xa8, 0x73, 0xda, 0xfe, 0x1b, 0x11, 0x47, 0x2d, 0xad, 0x18, 0x82, 0x7f, 0x66, 0xdd, 0x0c, 0x50, 0x78, 0x90, 0x97, 0x68, 0x2f, 0xd3, 0x93, 0x4e, 0x70, 0x5b, 0xec, 0x15, 0x7e, 0xd1, 0xa8, 0xe3, 0x70, 0x53, 0x38, 0xda, 0x6a, 0x8d, 0x24, 0x07, 0xbb, 0x0c, 0x86, 0x78, 0x52, 0x74, 0x31, 0xd2, 0xf5, 0x9b, 0xc3, 0x3b, 0x5c, 0x8f, 0xce, 0x3a, 0xe6, 0x5e, 0xfa, 0xf7, 0xec, 0x12, 0x99, 0x22, 0xeb, 0x6d, 0x39, 0x24, 0x0b, 0xcf, 0xda, 0x2d, 0x56, 0xff, 0x5e, 0xff, 0x37, 0xc9, 0x40, 0x47, 0xdd, 0x1d, 0xe6, 0x07, 0x7d, 0xce, 0xc0, 0x29, 0x2c, 0x76, 0xf8, 0x13, 0xe0, 0x90, 0xbb, 0x49, 0x05, 0x9d, 0x2d, 0xb3, 0xe0, 0x56, 0x98, 0xef, 0x0c, 0x43, 0x4f, 0x9a, 0xd9, 0x76, 0xad, 0xbe, 0xfd, 0xe3, 0x75, 0x32, 0x31, 0x85, 0xb7, 0x97, 0xde, 0x40, 0xd5, 0x17, 0xad, 0x6c, 0xa7, 0x7d, 0x89, 0x6c, 0x9c, 0x0e, 0x27, 0x36, 0x78, 0xa1, 0x21, 0x9f, 0xef, 0x4b, 0x64, 0x64, 0x8f, 0xb5, 0x3a, 0x0c, 0x27, 0xe0, 0xa9, 0xee, 0xba, 0x1d, 0x89, 0x1e, 0x43, 0xbb, 0xd2, 0x09, 0x0a, 0x8b, 0xb4, 0x78, 0xa7, 0x58, 0x4f, 0xee, 0x8a, 0x34, 0x25, 0x1e, 0x0e, 0x4e, 0x9f, 0x41, 0x32, 0x69, 0x70, 0xa5, 0xde, 0xa6, 0xf3, 0x4e, 0xfd, 0x43, 0x9c, 0x93, 0x81, 0x2b, 0xc9, 0x1d, 0xc0, 0xa9, 0xc6, 0x8a, 0x85, 0x5a, 0xce, 0x4a, 0xb9, 0xa9, 0x2b, 0x9e, 0x13, 0xe5, 0xf3, 0xfa, 0x6f, 0x23, 0xaf, 0xa3, 0xbd, 0x4b, 0xf8, 0x02, 0xd0, 0xb4, 0x44, 0x23, 0x11, 0xe3, 0x40, 0x9e, 0x29, 0xad, 0x55, 0x9b, 0x9b, 0xbf, 0xff, 0x04, 0xa8, 0xb5, 0x64, 0xe3, 0xde, 0xcf, 0x96, 0x4a, 0x44, 0x15, 0xac, 0xe6, 0x67, 0x1a, 0x00, 0x4b, 0x95, 0xcb, 0x73, 0x44, 0x1d, 0x30, 0xc3, 0x84, 0xb4, 0x50, 0x5f, 0x3f, 0xe2, 0x4c, 0xd3, 0x79, 0x92, 0x90, 0x04, 0x66, 0xe9, 0x68, 0xc9, 0xa0, 0xe6, 0x9e, 0x81, 0xc9, 0x08, 0xaa, 0x60, 0x6b, 0x2a, 0x52, 0xaa, 0x3d, 0x10, 0x60, 0xb3, 0xc1, 0xfc, 0xa2, 0x39, 0x44, 0xcc, 0xe8, 0x6a, 0xe9, 0xcc, 0xb0, 0xb9, 0x5b, 0x09, 0xdb, 0x08, 0xd1, 0x6d, 0xae, 0x20, 0x40, 0x28, 0x8c, 0x14, 0x9c, 0xe7, 0x57, 0xed, 0x6f, 0xba, 0x46, 0xd9, 0xf6, 0x90, 0x0f, 0x3f, 0x54, 0x67, 0xcf, 0x10, 0xf6, 0xbf, 0x83, 0xcd, 0x1c, 0x32, 0xe3, 0xf8, 0xcf, 0xb3, 0xc8, 0x0c, 0x30, 0x7f, 0x57, 0x58, 0x52, 0xa4, 0xe0, 0xce, 0x49, 0x6b, 0x63, 0xff, 0xff, 0x25, 0x5a, 0x7c, 0xea, 0x3d, 0x14, 0x90, 0x6b, 0xea, 0x5f, 0xb5, 0x4a, 0xf8, 0xdb, 0x7a, 0xd6, 0x14, 0x33, 0xb7, 0x95, 0x12, 0x1a, 0x55, 0xb2, 0x4e, 0xe0, 0xe9, 0x0b, 0xb5, 0x63, 0x5e, 0x98, 0xa5, 0xe9, 0x71, 0x54, 0x6b, 0x30, 0x3e, 0x9e, 0x8d, 0x65, 0xfc, 0x09, 0x92, 0xc0, 0xcd, 0xc1, 0x1a, 0x7d, 0x36, 0x44, 0x38, 0x0d, 0x64, 0x8f, 0xf1, 0x20, 0x57, 0xba, 0x83, 0x85, 0xdc, 0x2d, 0xc9, 0x6a, 0x68, 0x1a, 0xf9, 0xfa, 0x3b, 0x29, 0x34, 0x5f, 0xea, 0x62, 0x26, 0xa5, 0x84, 0xc6, 0x88, 0xee, 0x58, 0xb7, 0xad, 0xe6, 0x69, 0x04, 0x2a, 0xa1, 0x82, 0x7c, 0x75, 0xcf, 0xa5, 0xe1, 0x23, 0x6c, 0xb1, 0xe2, 0x8e, 0x31, 0xa9, 0xaf, 0x0e, 0x4d, 0x26, 0xbb, 0x71, 0x99, 0x1d, 0x20, 0x85, 0x58, 0x41, 0x14, 0xf7, 0x58, 0xa6, 0x90, 0xf6, 0xe0, 0x4c, 0x8a, 0x71, 0xd3, 0x60, 0xd5, 0x87, 0x21, 0x83, 0x1c, 0x7b, 0x68, 0xc7, 0x66, 0x2e, 0x29, 0x3a, 0x19, 0x81, 0x24, 0x6e, 0x3f, 0x81, 0xfc, 0xaa, 0xf1, 0x3d, 0x63, 0xcb, 0x66, 0x03, 0x7a, 0x03, 0x4b, 0x0a, 0xba, 0xc3, 0xa3, 0x78, 0x30, 0x25, 0xd6, 0x50, 0x50, 0xfe, 0x85, 0xdf, 0xbf, 0x02, 0x8f, 0x4c, 0x75, 0x48, 0xb4, 0x61, 0x0d, 0x90, 0xef, 0x33, 0xf1, 0x80, 0xa4, 0x7a, 0x9f, 0x1a, 0x2f, 0x35, 0x3c, 0x09, 0xca, 0x9b, 0x96, 0x28, 0xd3, 0x19, 0x62, 0x17, 0xcf, 0xd7, 0xaf, 0x82, 0xa8, 0x9f, 0x5f, 0xc5, 0x7b, 0xec, 0xf2, 0x2d, 0xca, 0x91, 0x8a, 0x0d, 0x41, 0xdb, 0x66, 0x7f, 0x7d, 0x3a, 0x0d, 0x28, 0xd2, 0x20, 0x1c, 0x4d, 0xe5, 0xd3, 0xee, 0xf3, 0x01, 0xe0, 0x07, 0x37, 0x40, 0xd4, 0x58, 0x5c, 0x56, 0x89, 0xa8, 0x1f, 0xd5, 0xde, 0x8b, 0xe2, 0xfb, 0x9f, 0x95, 0x64, 0x2f, 0xc3, 0xb7, 0x85, 0xe7, 0xf1, 0x15, 0x0b, 0x75, 0x4c, 0x8b, 0x91, 0x5a, 0x1b, 0xd3, 0xc5, 0x44, 0x7f, 0x1f, 0xca, 0x99, 0x0c, 0x2b, 0x00, 0x50, 0x3b, 0xbc, 0xf4, 0xdd, 0x89, 0x2a, 0xbe, 0xfd, 0xbc, 0x54, 0x09, 0x3d, 0x0f, 0x18, 0x98, 0x63, 0xf2, 0xf3, 0x7c, 0x42, 0xd2, 0x00, 0xd8, 0x77, 0xfb, 0xbd, 0x87, 0xba, 0x4c, 0x2e, 0x13, 0x35, 0xb5, 0xe5, 0xb4, 0x73, 0xc5, 0x8e, 0x22, 0x0c, 0x45, 0xe4, 0xd7, 0x1e, 0x36, 0xf0, 0xab, 0xa5, 0x13, 0x50, 0x5c, 0xab, 0xf5, 0xd8, 0x8c, 0xa0, 0xea, 0x52, 0x8d, 0x99, 0x01, 0xc5, 0x53, 0xbe, 0xe4, 0xcd, 0xa6, 0x53, 0xf6, 0x49, 0xd0, 0x9f, 0x91, 0x20, 0x8f, 0xe5, 0x2e, 0xef, 0x65, 0xac, 0xa8, 0x82, 0x3c, 0xbb, 0x03, 0x5e, 0x97, 0x6f, 0x1c, 0x3e, 0xae, 0xe9, 0x17, 0xe8, 0x68, 0xc0, 0x94, 0x24, 0xd1, 0x6a, 0xc7, 0x04, 0xf6, 0xdb, 0x51, 0xe0, 0xb0, 0xac, 0xbe, 0x76, 0x8d, 0x6c, 0xbe, 0xbc, 0x46, 0xf5, 0x07, 0xc4, 0x02, 0x3c, 0x03, 0x39, 0x5e, 0x52, 0xae, 0x24, 0x63, 0x88, 0xd2, 0xf0, 0x78, 0x70, 0x3d, 0x2a, 0xf8, 0xb0, 0xf7, 0x94, 0xf6, 0x09, 0xb1, 0x52, 0x7e, 0x33, 0xba, 0x12, 0x78, 0x94, 0xb0, 0x9c, 0x79, 0x27, 0x47, 0xcc, 0x6d, 0x6f, 0xa9, 0xc3, 0xe7, 0x07, 0x10, 0xcc, 0x34, 0x1e, 0x60, 0x75, 0xa4, 0x75, 0x40, 0x2f, 0x08, 0xce, 0x05, 0xbe, 0x4c, 0x4f, 0xd7, 0xb2, 0xae, 0x95, 0xd7, 0x0f, 0x73, 0x75, 0x44, 0x3f, 0xb9, 0xf6, 0xdd, 0x9f, 0x70, 0x7c, 0x5d, 0x38, 0x92, 0x1e, 0x60, 0x47, 0xfb, 0xb3, 0xd9, 0xa2, 0xd3, 0x09, 0x8b, 0x33, 0x54, 0xf2, 0xc7, 0x6e, 0xc5, 0x5f, 0xa7, 0x38, 0x0b, 0x44, 0x9b, 0xf9, 0xec, 0xd5, 0x72, 0xde, 0x67, 0xce, 0x3e, 0x92, 0x02, 0x10, 0x72, 0xf6, 0xc2, 0x35, 0x2b, 0x96, 0x51, 0x9b, 0x02, 0x97, 0xed, 0x78, 0x46, 0x0b, 0x49, 0xc2, 0xba, 0x91, 0xfe, 0xdd, 0x15, 0xd0, 0x7c, 0x6e, 0x9b, 0x31, 0xb6, 0x61, 0x13, 0x2c, 0x29, 0xa4, 0x12, 0xf9, 0x82, 0x78, 0x1d, 0xf7, 0x23, 0x36, 0x69, 0x5e, 0xc8, 0x98, 0x19, 0xb6, 0xdf, 0xdf, 0xff, 0x8a, 0x2a, 0x3d, 0x74, 0xfc, 0x20, 0x9e, 0xa5, 0x5d, 0x00, 0x47, 0xd9, 0x41, 0x25, 0xb6, 0x87, 0x95, 0x01, 0x50, 0x73, 0x7b, 0x63, 0xe7, 0x56, 0xe3, 0x45, 0x30, 0x2c, 0xf5, 0x87, 0x49, 0x6e, 0xf3, 0xa1, 0x97, 0x25, 0x6f, 0xe4, 0xe2, 0x21, 0xb7, 0xcc, 0x47, 0x17, 0x16, 0xd9, 0x57, 0xc1, 0xb9, 0xc4, 0x99, 0xa6, 0xdf, 0x74, 0x42, 0x4d, 0x89, 0x62, 0x84, 0x3f, 0xa2, 0xbd, 0xf1, 0xd4, 0xdb, 0x62, 0x87, 0x27, 0x23, 0xe8, 0xb3, 0x4d, 0x49, 0x7f, 0xf3, 0x98, 0x3a, 0xbc, 0x77, 0xfd, 0x13, 0xd1, 0x50, 0x5b, 0x40, 0xa5, 0xa2, 0xdb, 0xef, 0x7c, 0x6b, 0x35, 0xf0, 0xbf, 0xb1, 0x98, 0xec, 0x81, 0x57, 0x2f, 0xfe, 0x08, 0xa6, 0x2f, 0xf5, 0xd7, 0xad, 0x7e, 0x20, 0x12, 0x93, 0xe0, 0xc9, 0x6a, 0x4a, 0x65, 0x33, 0x74, 0x8a, 0x46, 0x56, 0x1a, 0xb8, 0x97, 0xc6, 0x19, 0x7e, 0x27, 0x5c, 0xa4, 0x02, 0x2a, 0x2d, 0x60, 0x82, 0x8b, 0xa0, 0x4b, 0x59, 0xcb, 0x25, 0xe8, 0x7f, 0xb5, 0x66, 0xef, 0xa6, 0x7f, 0x56, 0x84, 0xc8, 0xb2, 0xcb, 0x5a, 0xf3, 0x07, 0x76, 0xc0, 0x31, 0x3e, 0x0c, 0x74, 0x22, 0xfb, 0x18, 0x4b, 0x38, 0xe0, 0x60, 0xdc, 0x38, 0xb6, 0x85, 0x6e, 0x92, 0xbf, 0xd9, 0x38, 0x3c, 0xaf, 0xc2, 0xe3, 0x76, 0x4b, 0xd0, 0x5a, 0x06, 0x45, 0x9a, 0x18, 0x6d, 0x2b, 0xc5, 0x7b, 0xa2, 0x2c, 0x55, 0xd0, 0xd2, 0xd6, 0x86, 0xaa, 0x89, 0x4e, 0xf9, 0x66, 0x2a, 0xb9, 0xb6, 0x43, 0x0f, 0xd9, 0x8d, 0x9d, 0x0e, 0xab, 0x1f, 0x1f, 0x11, 0x8a, 0xa1, 0xd8, 0x58, 0x30, 0x75, 0xe8, 0x7d, 0x3a, 0x93, 0x10, 0xa8, 0xc3, 0x4c, 0x93, 0xfd, 0x87, 0x6e, 0x54, 0xa2, 0x4b, 0x1b, 0x38, 0x06, 0x8b, 0x67, 0xe2, 0xf1, 0xcc, 0xc7, 0xc9, 0x17, 0x2d, 0x31, 0x5d, 0x0d, 0x75, 0x10, 0xb3, 0x18, 0xf7, 0xe4, 0xfc, 0xa6, 0x99, 0x34, 0x02, 0x7f, 0xb6, 0xbb, 0x69, 0x52, 0x18, 0xae, 0xed, 0x92, 0xfe, 0x80, 0xc8, 0x23, 0x9d, 0x45, 0x01, 0x20, 0x6d, 0x3a, 0xe2, 0x1a, 0x29, 0x89, 0x06, 0xe1, 0x17, 0xbd, 0x18, 0x66, 0xd2, 0xd2, 0xc9, 0x59, 0x4d, 0x92, 0xec, 0xb2, 0x0d, 0x22, 0xc9, 0x9f, 0xa3, 0x15, 0xec, 0xf9, 0x76, 0x25, 0xe4, 0xea, 0xb9, 0x7e, 0x94, 0xe5, 0xb3, 0xde, 0x1c, 0xd6, 0xae, 0x47, 0x93, 0xc9, 0xdd, 0x18, 0xf1, 0x9e, 0x51, 0x08, 0x21, 0xab, 0xdc, 0x3d, 0x66, 0xfc, 0xbc, 0x28, 0x1d, 0xda, 0xda, 0x6b, 0x15, 0x6b, 0xed, 0x94, 0x30, 0xa0, 0xcd, 0x7e, 0x5e, 0xa9, 0xae, 0x4c, 0x01, 0x5e, 0xb0, 0xd2, 0x1e, 0x8f, 0xf2, 0xf0, 0x0e, 0x72, 0x67, 0x53, 0x0c, 0x51, 0x87, 0xda, 0xaf, 0x08, 0xb0, 0x84, 0xee, 0x7e, 0x07, 0x13, 0xf3, 0xc9, 0x4c, 0x55, 0xb2, 0xea, 0xe4, 0x0f, 0x75, 0x47, 0x34, 0xbc, 0x7d, 0xe4, 0x14, 0x31, 0x14, 0x9d, 0xd7, 0xfa, 0xca, 0x70, 0x3c, 0xfd, 0x3b, 0x5c, 0x21, 0xfb, 0x86, 0xe9, 0xcb, 0xce, 0x9c, 0xb3, 0x53, 0x5c, 0x15, 0xda, 0xbb, 0xd6, 0xfc, 0x82, 0x2f, 0xab, 0x0d, 0x06, 0x2d, 0xec, 0x9d, 0xed, 0x35, 0x68, 0x01, 0xa4, 0xdf, 0x24, 0x19, 0x23, 0xfe, 0x5a, 0x51, 0xaa, 0xab, 0x94, 0x71, 0xdc, 0xbc, 0x31, 0x6d, 0x57, 0x8e, 0x15, 0x07, 0x41, 0x42, 0x67, 0x66, 0x2a, 0x8c, 0xd6, 0xd2, 0x28, 0x2b, 0x51, 0x0c, 0xe0, 0xdb, 0x5f, 0x5d, 0x86, 0xc7, 0x21, 0xbd, 0x35, 0xe3, 0x64, 0x56, 0xa1, 0xac, 0x79, 0x62, 0x6f, 0x48, 0x4b, 0x8e, 0xba, 0x9b, 0x3f, 0x53, 0x6c, 0x27, 0x7b, 0x3a, 0xeb, 0x40, 0x77, 0x03, 0xaf, 0xb6, 0xda, 0x85, 0x2d, 0xaa, 0x11, 0x5d, 0x26, 0x3b, 0x39, 0x4f, 0xd0, 0x4c, 0x6d, 0x6f, 0xfd, 0x3d, 0xb1, 0x6c, 0x10, 0x0e, 0x2c, 0xa2, 0xc4, 0xf4, 0x58, 0x78, 0x38, 0x40, 0xad, 0x09, 0x61, 0x09, 0x8c, 0x2b, 0x4d, 0x41, 0xb2, 0x35, 0x19, 0x7f, 0x64, 0xcf, 0xe2, 0xf7, 0x51, 0xbb, 0x83, 0x9d, 0x26, 0xe9, 0xc9, 0xf4, 0x9b, 0x45, 0x79, 0x41, 0x95, 0xe9, 0x27, 0xa6, 0xbf, 0x58, 0x0d, 0xcf, 0xea, 0xfe, 0x41, 0x61, 0x99, 0xd7, 0x31, 0x37, 0x8d, 0xa0, 0xf2, 0xc2, 0xb7, 0x8f, 0x62, 0x0d, 0x9f, 0x06, 0x63, 0xc5, 0x37, 0x96, 0x5a, 0xf2, 0x16, 0x7d, 0xe2, 0x5c, 0xa7, 0x6f, 0xed, 0x29, 0x61, 0xa5, 0xc3, 0x38, 0x7a, 0xef, 0xb5, 0x07, 0xae, 0x06, 0x67, 0x03, 0x48, 0x41, 0x66, 0xfb, 0x7d, 0x8e, 0x1d, 0x5d, 0xc1, 0x58, 0xb5, 0x72, 0xb3, 0x76, 0xd7, 0xcf, 0x37, 0x7c, 0x64, 0xac, 0x8c, 0xff, 0x84, 0x3d, 0x7e, 0x05, 0x9a, 0x46, 0xf6, 0xe8, 0x9c, 0x3f, 0xc1, 0x84, 0xdb, 0x57, 0xec, 0xaa, 0xec, 0xc8, 0xcc, 0x99, 0x8d, 0xe3, 0x4d, 0x05, 0xc0, 0x76, 0x9e, 0xa6, 0xad, 0x32, 0xf9, 0x0a, 0x70, 0x8e, 0x7f, 0xe5, 0x08, 0x8d, 0xcc, 0xaa, 0xcb, 0x4f, 0xf4, 0xf1, 0xf3, 0x9b, 0x27, 0xc2, 0x05, 0x89, 0xa5, 0xfc, 0x0b, 0x66, 0xe3, 0xe2, 0x7a, 0x2d, 0x96, 0x38, 0xc5, 0x4a, 0x5b, 0xf9, 0x06, 0x85, 0x66, 0xc0, 0xce, 0x8e, 0x9d, 0x06, 0x4e, 0x8d, 0xfe, 0xf5, 0x0f, 0x8b, 0x61, 0xc4, 0x75, 0x35, 0x79, 0xe4, 0xee, 0xb7, 0x7e, 0x53, 0xd1, 0xbf, 0x92, 0x9c, 0x9b, 0xfe, 0xe7, 0xd1, 0xa2, 0xbc, 0x49, 0xe5, 0xa3, 0x15, 0xb6, 0x87, 0x3b, 0x2a, 0xe5, 0x89, 0x6e, 0x25, 0x05, 0x54, 0x74, 0xc8, 0x16, 0x00, 0x43, 0xbf, 0xd4, 0x99, 0x88, 0x32, 0x2f, 0xa9, 0x70, 0x21, 0x1d, 0xc2, 0xa3, 0x90, 0x27, 0x6b, 0xd1, 0x62, 0x33, 0x3f, 0x4d, 0x7d, 0x6e, 0x1c, 0xde, 0x21, 0x69, 0xaa, 0xf0, 0xed, 0x91, 0xbf, 0x00, 0x57, 0xcf, 0xbe, 0x80, 0x8e, 0x4d, 0x0d, 0x25, 0x90, 0xc1, 0x49, 0x69, 0x50, 0xc1, 0x79, 0xd2, 0x33, 0x36, 0x91, 0xdc, 0xbb, 0x68, 0xa9, 0x26, 0xc7, 0xf3, 0x3f, 0x31, 0x8c, 0x1b, 0xdc, 0xcf, 0x5c, 0x79, 0xed, 0x44, 0x24, 0x13, 0xba, 0x8e, 0xc2, 0x54, 0xb8, 0xe7, 0x0f, 0x09, 0xb3, 0xd4, 0xd3, 0x6c, 0x49, 0x20, 0x1c, 0x7c, 0x54, 0x9c, 0x20, 0x35, 0x7c, 0xca, 0xb9, 0x21, 0x0e, 0x5f, 0x3b, 0x86, 0xf7, 0x71, 0xf2, 0x1b, 0x17, 0xc2, 0x47, 0x46, 0x3f, 0x91, 0xb5, 0xfa, 0x15, 0x67, 0xb7, 0x9c, 0xce, 0x52, 0x0e, 0x25, 0x37, 0x31, 0xd8, 0xdc, 0x84, 0x38, 0xa9, 0x0a, 0x8b, 0xc1, 0xfd, 0x1b, 0x19, 0xbb, 0x6e, 0xf7, 0x9c, 0x5a, 0x85, 0xe6, 0x03, 0xd8, 0x41, 0xda, 0x6f, 0x67, 0xaa, 0xee, 0xa3, 0x19, 0x21, 0xc1, 0xbd, 0x58, 0x21, 0x9a, 0xe3, 0xb6, 0x85, 0x44, 0x34, 0xd1, 0x87, 0x17, 0x17, 0x1e, 0x8f, 0x2c, 0x70, 0x02, 0x6d, 0x4d, 0x74, 0x81, 0xff, 0xea, 0x1f, 0x60, 0x56, 0x8c, 0x06, 0x95, 0x0c, 0x3c, 0xd9, 0xc5, 0xf5, 0x69, 0x37, 0xbd, 0xa7, 0xde, 0x8a, 0x1b, 0x63, 0xeb, 0x62, 0xfd, 0x5a, 0x82, 0xcc, 0x1e, 0xfc, 0x48, 0xde, 0x5d, 0x77, 0x7a, 0xba, 0x08, 0xb7, 0xf3, 0xfa, 0xe2, 0x18, 0x8b, 0xd3, 0x26, 0xab, 0x29, 0x45, 0x76, 0x76, 0xc7, 0x3a, 0x43, 0x1e, 0x4f, 0x9a, 0xb0, 0xae, 0x1d, 0x2e, 0x0c, 0xe8, 0xa3, 0xe0, 0xd3, 0x86, 0x86, 0x15, 0x74, 0x55, 0x48, 0x28, 0x96, 0x9c, 0xe0, 0x29, 0xe6, 0xa5, 0x10, 0xca, 0x8a, 0x4d, 0xf3, 0x45, 0x1f, 0x0a, 0x9d, 0x40, 0xa0, 0xef, 0x96, 0xe5, 0x3d, 0x5a, 0xc5, 0xe0, 0x46, 0x65, 0x32, 0x2a, 0x2c, 0x72, 0xd3, 0xb5, 0xc2, 0x8c, 0x07, 0xf9, 0xec, 0xde, 0x0b, 0x4a, 0x6d, 0xa4, 0x60, 0xaa, 0x78, 0xef, 0x34, 0xde, 0x98, 0x1b, 0xb0, 0x55, 0x9f, 0xc1, 0xde, 0x69, 0xed, 0x2d, 0x2f, 0x5e, 0xe8, 0x13, 0x3e, 0x41, 0x71, 0x7a, 0x71, 0x02, 0xdb, 0xc1, 0x79, 0x5a, 0x5f, 0x45, 0xd0, 0xa6, 0xce, 0x1b, 0xb4, 0x64, 0x53, 0xd1, 0x55, 0x8a, 0x9a, 0xa6, 0x0c, 0x48, 0x3f, 0xb3, 0x33, 0x16, 0xf4, 0xeb, 0xd1, 0x31, 0x7b, 0xae, 0x56, 0x28, 0x35, 0xd9, 0x04, 0xa1, 0x47, 0x44, 0x05, 0xef, 0x73, 0xd9, 0x6a, 0xb8, 0x5e, 0xd5, 0xdc, 0xb0, 0xf5, 0x41, 0x0e, 0x33, 0xca, 0x33, 0xc6, 0x58, 0x78, 0xaa, 0xd5, 0xd7, 0x0c, 0x48, 0xb3, 0xfc, 0xa8, 0x68, 0x30, 0x92, 0x17, 0x52, 0x79, 0x4f, 0xb8, 0xb3, 0xad, 0xdf, 0x30, 0x81, 0x0f, 0x0f, 0xca, 0xad, 0x9f, 0x44, 0x49, 0xbb, 0x8c, 0x00, 0xdf, 0x04, 0x93, 0x51, 0xa4, 0x54, 0xc3, 0x3e, 0xb3, 0x2e, 0x84, 0xfc, 0xda, 0xb5, 0x67, 0x04, 0xf5, 0xd7, 0x80, 0xd8, 0x3e, 0xeb, 0x35, 0xf7, 0x6b, 0xad, 0xde, 0xb5, 0x08, 0x1b, 0x1b, 0x56, 0xef, 0xf7, 0xfb, 0x41, 0xc9, 0x87, 0x0a, 0x71, 0x70, 0xf6, 0xe5, 0x50, 0x15, 0xbe, 0x96, 0x70, 0xa6, 0x81, 0xc3, 0x6e, 0xaf, 0x02, 0xda, 0x1f, 0x51, 0x7a, 0x77, 0xa4, 0x0d, 0x95, 0x93, 0x9f, 0xf2, 0x63, 0x5f, 0x86, 0xae, 0x34, 0xa1, 0x88, 0xc5, 0x39, 0x49, 0x02, 0xfb, 0x6a, 0xba, 0xbc, 0x23, 0x88, 0x61, 0x3b, 0x0e, 0xd9, 0x56, 0xd4, 0x55, 0x80, 0x77, 0x90, 0x28, 0x85, 0xd1, 0xa9, 0x1a, 0xe8, 0xfa, 0x96, 0x9a, 0xba, 0x0f, 0xb2, 0x23, 0x80, 0xf8, 0xb0, 0x4e, 0x21, 0x95, 0x0b, 0x80, 0x45, 0xe9, 0x32, 0xde, 0x24, 0xb9, 0x2c, 0x82, 0x25, 0xc8, 0xc0, 0xf2, 0x1f, 0x71, 0x5f, 0x79, 0xa1, 0x89, 0x93, 0x59, 0x7a, 0x16, 0xc8, 0xbe, 0x63, 0xde, 0x67, 0x98, 0xfb, 0xf6, 0xac, 0xa8, 0x95, 0x27, 0x5b, 0x2a, 0x4f, 0x00, 0xe1, 0xa5, 0xf2, 0x84, 0x1c, 0xaf, 0xc4, 0x83, 0x13, 0x22, 0x63, 0x75, 0x8f, 0xbd, 0xfa, 0x55, 0x76, 0xe6, 0x9b, 0xcd, 0x22, 0x2e, 0x86, 0x05, 0xdc, 0xf2, 0x4c, 0x3b, 0x6e, 0x82, 0x0a, 0x38, 0x6d, 0xf4, 0xc7, 0xed, 0x9d, 0x77, 0x39, 0x55, 0xe1, 0x27, 0x18, 0xa0, 0x67, 0xfa, 0xce, 0x15, 0x5c, 0x71, 0x99, 0xcc, 0x88, 0x5d, 0x0c, 0x0a, 0xfe, 0x52, 0x9a, 0xa0, 0x89, 0x79, 0x29, 0x5f, 0x4b, 0xd2, 0xc8, 0x03, 0x3d, 0x80, 0x96, 0x61, 0xa3, 0xae, 0xa2, 0xdd, 0x5f, 0x05, 0x20, 0x7e, 0x80, 0xb3, 0xb6, 0x38, 0x11, 0x54, 0x5e, 0xd3, 0x2c, 0xfc, 0x68, 0xd6, 0x01, 0x34, 0x60, 0x30, 0xfa, 0x83, 0xca, 0x06, 0x20, 0xa9, 0x3c, 0xf6, 0x82, 0xdb, 0x0f, 0xfe, 0x1a, 0xe7, 0x13, 0x5e, 0x2c, 0x75, 0x50, 0xd9, 0xa5, 0x93, 0x96, 0x2c, 0x28, 0xf2, 0xfa, 0x46, 0xca, 0xaf, 0xe7, 0x13, 0x37, 0x04, 0x6e, 0xc4, 0xaf, 0xd6, 0xa3, 0x23, 0x04, 0xfe, 0x49, 0x88, 0x5a, 0x61, 0x4b, 0xb1, 0xc3, 0xe9, 0xf2, 0x57, 0x6c, 0xdd, 0x92, 0x36, 0x32, 0xe9, 0x77, 0x67, 0x0c, 0xab, 0x40, 0xde, 0xef, 0xf0, 0x74, 0x6f, 0x15, 0xc7, 0x4d, 0xd5, 0x00, 0xe2, 0x0c, 0x46, 0xd0, 0x3c, 0x2a, 0x83, 0x92, 0xea, 0xeb, 0x67, 0x4e, 0x08, 0x31, 0x19, 0xcd, 0x8a, 0xca, 0x87, 0x23, 0x3f, 0x5d, 0x9d, 0x55, 0xb7, 0x67, 0xf2, 0x3e, 0x33, 0x98, 0xe5, 0x96, 0x47, 0x28, 0xb9, 0xec, 0x46, 0x3c, 0x11, 0x9e, 0x5d, 0xc8, 0x20, 0xce, 0xf1, 0x3e, 0xa1, 0x78, 0x03, 0xf4, 0x94, 0xa1, 0xdc, 0xb9, 0xd3, 0x1e, 0x68, 0x8c, 0x95, 0x2c, 0x1c, 0x5b, 0xe8, 0x3e, 0xb2, 0xc0, 0x2c, 0x7f, 0x6d, 0xeb, 0xe7, 0x93, 0x12, 0xcb, 0x32, 0x35, 0x48, 0xab, 0xe6, 0xb8, 0x15, 0x5a, 0x1a, 0x6f, 0xb9, 0x56, 0x26, 0xcf, 0x94, 0xee, 0x6b, 0x79, 0x41, 0x57, 0xe7, 0x6c, 0xc2, 0x2f, 0x30, 0xd9, 0x4a, 0xc6, 0x37, 0xb4, 0x5f, 0xce, 0xd2, 0x3a, 0x95, 0x9e, 0xe1, 0xe9, 0x87, 0x27, 0xaa, 0x52, 0x4c, 0x12, 0xb8, 0xce, 0xbd, 0xf1, 0x59, 0x4d, 0x21, 0xbd, 0xcc, 0x4e, 0x6d, 0x40, 0xb6, 0xad, 0x58, 0xe3, 0xea, 0x19, 0x56, 0x78, 0xc6, 0x41, 0xd2, 0xaa, 0xdb, 0x13, 0x00, 0x69, 0x84, 0x84, 0x4e, 0x73, 0xe3, 0x23, 0xc6, 0x9d, 0x63, 0xf5, 0x34, 0x00, 0x7b, 0xc7, 0x4b, 0x89, 0x64, 0xc8, 0xde, 0x19, 0x2c, 0x19, 0xa1, 0x8c, 0x3b, 0x07, 0xa0, 0xa2, 0xf7, 0xcb, 0x6b, 0xc0, 0x79, 0xb0, 0x0f, 0x94, 0x8c, 0x5e, 0xb7, 0x3a, 0x99, 0x52, 0xa0, 0x35, 0x8b, 0x94, 0xa9, 0xf8, 0xb6, 0x01, 0xb1, 0xdc, 0x41, 0xe8, 0x0c, 0xbb, 0x1b, 0x8d, 0x71, 0x4f, 0x71, 0x3a, 0xd7, 0xb4, 0xfa, 0xc6, 0x7d, 0x12, 0xe9, 0xa6, 0xdd, 0x83, 0x18, 0x6f, 0x51, 0x64, 0x91, 0xe1, 0xd0, 0xf7, 0x09, 0xac, 0x11, 0x69, 0x70, 0xdb, 0x87, 0x42, 0x5c, 0x2e, 0xa5, 0x92, 0xbc, 0x21, 0xe3, 0x55, 0x5c, 0x4e, 0x3e, 0xd3, 0x29, 0xc1, 0x15, 0x59, 0xd2, 0xa8, 0xf5, 0x02, 0x37, 0xbf, 0xf6, 0xd9, 0x83, 0x91, 0x7c, 0x62, 0x40, 0x21, 0x4e, 0x0c, 0xeb, 0xc3, 0x70, 0x9c, 0xa5, 0x87, 0xde, 0x27, 0x36, 0xff, 0x16, 0xc8, 0xbe, 0x8c, 0xf4, 0x97, 0xea, 0x0b, 0x1a, 0x31, 0xbe, 0xb9, 0x20, 0x88, 0x8d, 0x9f, 0xda, 0x0b, 0x0e, 0x1d, 0xa7, 0x73, 0x69, 0x7c, 0x1d, 0x0e, 0xef, 0x66, 0x26, 0xb6, 0x3a, 0xe1, 0x8e, 0xf2, 0x90, 0xa5, 0x77, 0x63, 0x83, 0x2f, 0xd2, 0x11, 0x6d, 0x3b, 0x48, 0xb5, 0x6d, 0xcc, 0x9e, 0x97, 0x25, 0x7c, 0xca, 0x03, 0x65, 0x8d, 0xa3, 0x31, 0x0a, 0xf1, 0x44, 0x7d, 0xba, 0x5e, 0xcb, 0x9d, 0xb5, 0x91, 0x35, 0x4f, 0xec, 0x42, 0xf5, 0xba, 0x10, 0x42, 0x72, 0xa6, 0x95, 0xe0, 0x30, 0xe1, 0x1d, 0xf0, 0xcb, 0x6b, 0x0a, 0x56, 0x12, 0xd6, 0x8c, 0x47, 0x47, 0x27, 0xfb, 0xff, 0xcf, 0x01, 0x18, 0x82, 0xa5, 0x50, 0x18, 0x2f, 0xd3, 0xbe, 0x64, 0x66, 0x5b, 0x22, 0xfa, 0xfc, 0x4a, 0x56, 0x2a, 0x7e, 0xa4, 0xa3, 0x9e, 0xc3, 0x53, 0xbb, 0x37, 0x1f, 0x0d, 0xfc, 0xc2, 0x79, 0x03, 0x7a, 0x45, 0xd6, 0x9b, 0x18, 0x30, 0x05, 0xc1, 0xbc, 0xcb, 0x2a, 0x0b, 0x4e, 0xa5, 0x36, 0x7d, 0xf0, 0xdf, 0xae, 0x19, 0x83, 0xee, 0x97, 0x07, 0xc2, 0x74, 0xc1, 0x74, 0x10, 0x4a, 0x14, 0xad, 0xfd, 0xb4, 0x8a, 0x75, 0x99, 0x69, 0x88, 0xda, 0x4a, 0x4e, 0x6b, 0xa8, 0xb2, 0x08, 0xd7, 0x0b, 0xb1, 0x1f, 0x46, 0x90, 0xa2, 0xc3, 0xdc, 0xf0, 0x67, 0x76, 0xdc, 0x3a, 0xf8, 0xa9, 0x48, 0x3a, 0x68, 0x79, 0xaa, 0x46, 0x03, 0x7c, 0x16, 0xd6, 0x45, 0xac, 0x50, 0xff, 0x52, 0xe5, 0x88, 0xfa, 0xf7, 0x4d, 0x94, 0x46, 0xf4, 0x41, 0x97, 0xbf, 0xf0, 0x01, 0x8a, 0xc9, 0x72, 0x47, 0x36, 0x16, 0x98, 0x74, 0xe9, 0xd4, 0x15, 0x2d, 0x86, 0xbe, 0xf8, 0xed, 0xde, 0x9a, 0x8f, 0x05, 0x35, 0x06, 0x24, 0x89, 0xe1, 0xf4, 0xc4, 0xfe, 0xad, 0x40, 0x8c, 0x1c, 0x67, 0xbc, 0xe7, 0x54, 0xea, 0x9d, 0x20, 0x10, 0x13, 0xe2, 0x8f, 0x43, 0x6c, 0x1e, 0x89, 0x5b, 0xb2, 0x32, 0xd0, 0x72, 0x9a, 0xba, 0x2e, 0x3f, 0x72, 0x7f, 0xd5, 0x84, 0x3d, 0x58, 0xc9, 0xd9, 0xbd, 0x29, 0x66, 0x21, 0x5d, 0xa0, 0x5e, 0x7b, 0x40, 0xd7, 0xe5, 0xf6, 0xe4, 0x23, 0xdb, 0x75, 0x11, 0x8e, 0xc2, 0x34, 0x6a, 0xcf, 0x81, 0xca, 0x07, 0x1d, 0x7e, 0x6f, 0xd7, 0xe1, 0xf6, 0x60, 0x95, 0x59, 0x24, 0xe9, 0x38, 0x9d, 0x47, 0xae, 0x6b, 0x2e, 0xfd, 0xe5, 0x5b, 0x90, 0x77, 0xa4, 0xd6, 0x8b, 0xba, 0x7b, 0x5a, 0x36, 0xc7, 0x28, 0x69, 0x46, 0xf5, 0x0c, 0xe4, 0x64, 0x2e, 0xd4, 0x8e, 0xa8, 0x61, 0xe1, 0xff, 0x24, 0x2b, 0x65, 0xec, 0x02, 0x7e, 0x33, 0xcd, 0x10, 0x14, 0x64, 0x46, 0x73, 0x97, 0xa5, 0x57, 0xf8, 0xfa, 0x31, 0x59, 0x22, 0xc0, 0x83, 0x40, 0x5f, 0x07, 0x03, 0x26, 0xb6, 0x68, 0x01, 0x90, 0xbe, 0x7f, 0x59, 0xe1, 0xd6, 0xa9, 0x09, 0x9d, 0x35, 0xc9, 0x6f, 0x63, 0xb2, 0x27, 0x75, 0x62, 0xc2, 0x25, 0xdd, 0x77, 0xd0, 0xa6, 0x5b, 0x57, 0x29, 0xa8, 0xc0, 0xe4, 0x7e, 0x40, 0x18, 0xb2, 0x62, 0xb1, 0x46, 0xd4, 0x0c, 0x9c, 0x51, 0x60, 0x59, 0xb8, 0x1c, 0x8a, 0x7a, 0xbf, 0x79, 0xe1, 0x3b, 0x32, 0x56, 0xd2, 0x49, 0xff, 0x4f, 0x61, 0xb0, 0x1f, 0xbc, 0x2f, 0x71, 0x39, 0xd8, 0xd0, 0x59, 0x09, 0x2b, 0xf5, 0x8e, 0x79, 0xac, 0xc0, 0xd4, 0xd2, 0xfd, 0x54, 0x0b, 0x27, 0x0a, 0xf7, 0x94, 0xfd, 0xb8, 0x4f, 0xb8, 0x7e, 0x63, 0xa7, 0xe7, 0xb4, 0x1e, 0xab, 0x9d, 0xed, 0x89, 0x04, 0x50, 0xc7, 0xc5, 0xb6, 0x3d, 0xa6, 0x0b, 0x16, 0xbd, 0x78, 0x92, 0x71, 0x21, 0xaa, 0xee, 0x47, 0x37, 0x96, 0x10, 0xdd, 0x42, 0xb3, 0x2a, 0x78, 0x34, 0xa7, 0xe7, 0x07, 0x8e, 0x4d, 0x66, 0xce, 0x90, 0xad, 0x6b, 0x40, 0xd7, 0x04, 0xaa, 0xf2, 0x5d, 0x4e, 0x18, 0x3d, 0xfd, 0x8a, 0x20, 0x9e, 0x22, 0x54, 0xb4, 0xd1, 0xb1, 0xcb, 0x54, 0x02, 0x1b, 0x84, 0x38, 0xad, 0x45, 0xff, 0x38, 0xd4, 0x9a, 0x9b, 0x38, 0x79, 0xb5, 0x23, 0xde, 0xee, 0xba, 0xb8, 0x1b, 0xe4, 0xc8, 0x28, 0x33, 0x89, 0xc7, 0xca, 0xfb, 0xa6, 0x5c, 0x7b, 0xdc, 0x9b, 0x4d, 0x2d, 0xd5, 0x96, 0xd3, 0x85, 0xe9, 0x20, 0x49, 0xb9, 0xe7, 0x5c, 0x2d, 0xc6, 0x9c, 0x5c, 0xf3, 0x18, 0xe6, 0x9e, 0x2d, 0x3a, 0x13, 0x78, 0x03, 0xad, 0x00, 0xeb, 0x86, 0x3d, 0x15, 0x31, 0x5a, 0xd8, 0xfe, 0x6f, 0x50, 0xdc, 0xc6, 0x06, 0x22, 0x56, 0xe5, 0x93, 0xfc, 0xf5, 0x6a, 0xdc, 0x0e, 0x05, 0xa9, 0xab, 0xa8, 0x4a, 0xea, 0x1e, 0x28, 0x9e, 0x62, 0x75, 0xd7, 0x0f, 0xb0, 0x84, 0x76, 0x0a, 0x74, 0x97, 0x98, 0x2b, 0xea, 0x3e, 0xd9, 0x7d, 0xa7, 0x6d, 0xac, 0x66, 0x25, 0x4b, 0xec, 0x53, 0x9f, 0x9f, 0x78, 0x00, 0xc3, 0x60, 0x3d, 0x5e, 0xa7, 0xe9, 0x12, 0x26, 0x1e, 0x4a, 0x0c, 0xf5, 0x74, 0x36, 0x36, 0x02, 0x6e, 0x8e, 0x92, 0xee, 0xeb, 0xe6, 0x80, 0x40, 0x2b, 0x4f, 0x86, 0x57, 0xff, 0x4c, 0xad, 0x10, 0xb0, 0x99, 0x5b, 0xce, 0xd8, 0x85, 0x06, 0xf1, 0x42, 0xa9, 0x5d, 0xee, 0xb9, 0x8d, 0x12, 0x0d, 0xbc, 0x26, 0xcd, 0x23, 0xe2, 0xee, 0x85, 0x9c, 0x11, 0x3d, 0xb9, 0x22, 0x63, 0x73, 0xd4, 0xdf, 0xf4, 0x00, 0xfb, 0xa0, 0x45, 0x95, 0x66, 0x7c, 0xbf, 0x8e, 0x52, 0xeb, 0x80, 0xeb, 0x1c, 0xc4, 0x6c, 0x90, 0x4d, 0x80, 0xc8, 0x08, 0x56, 0xf3, 0xa2, 0x44, 0x55, 0x43, 0xe2, 0x8b, 0x27, 0x79, 0x6f, 0xe5, 0x3b, 0x19, 0x06, 0x16, 0x7b, 0xb1, 0xee, 0xee, 0x38, 0x73, 0xb2, 0xce, 0xa1, 0x2e, 0x19, 0x88, 0x1f, 0x52, 0x10, 0xf5, 0xfd, 0x2c, 0x8e, 0x91, 0x7f, 0x6e, 0xc7, 0x42, 0xed, 0x83, 0xe2, 0xd4, 0xb0, 0xc4, 0x95, 0x9f, 0x6a, 0xb7, 0x32, 0x1b, 0x81, 0xbe, 0xa2, 0xd1, 0x22, 0x7f, 0x07, 0x91, 0xaf, 0xa2, 0x67, 0xc8, 0x38, 0x2c, 0x18, 0x6a, 0x43, 0x44, 0xcb, 0xc6, 0xee, 0x81, 0x19, 0xcd, 0xeb, 0x54, 0x91, 0xa0, 0xb5, 0xbd, 0x62, 0x14, 0x4a, 0xef, 0xfc, 0x15, 0x56, 0xc6, 0xc5, 0xc5, 0xa5, 0x39, 0xf9, 0x06, 0x5e, 0x02, 0x83, 0x18, 0x33, 0xc1, 0xdc, 0x85, 0xe2, 0x7b, 0x24, 0x19, 0xaf, 0xdb, 0x47, 0xd2, 0x8e, 0x8f, 0x0f, 0xf1, 0xf3, 0x76, 0xc7, 0x52, 0xda, 0xb1, 0x99, 0x55, 0x7d, 0x07, 0x6a, 0x37, 0x2b, 0x2f, 0xc4, 0xa1, 0x0a, 0xd3, 0xb9, 0xe0, 0xed, 0x6d, 0x5f, 0x3b, 0xea, 0x2a, 0x74, 0x9a, 0xf8, 0x15, 0xc1, 0x69, 0x4c, 0x62, 0x30, 0xcd, 0xb5, 0x87, 0xff, 0x7b, 0x5a, 0x71, 0x47, 0xc2, 0x0e, 0xed, 0x7f, 0xc6, 0x32, 0x62, 0xa8, 0x86, 0xbe, 0x77, 0x09, 0x92, 0x00, 0xdd, 0x6f, 0x3f, 0x2f, 0xda, 0x70, 0xea, 0x30, 0xa2, 0xb7, 0x0c, 0x08, 0x1a, 0xbf, 0x5f, 0x5b, 0xd4, 0x76, 0xcf, 0x11, 0xab, 0xf5, 0xa2, 0x03, 0x83, 0x89, 0xa0, 0x63, 0xbc, 0xd6, 0x99, 0x6a, 0x4b, 0x18, 0x90, 0xc0, 0x6b, 0x51, 0x11, 0xdf, 0x40, 0x54, 0x8c, 0x60, 0xcc, 0x75, 0xfb, 0xa3, 0xaf, 0x4b, 0xda, 0x40, 0x6e, 0x37, 0x0e, 0xbb, 0x52, 0x1f, 0x91, 0xba, 0xd2, 0x05, 0x46, 0x62, 0x4f, 0x12, 0x44, 0xec, 0xe7, 0x88, 0xb7, 0x22, 0x6f, 0x08, 0xf8, 0xff, 0x4b, 0x91, 0xa3, 0x36, 0x7b, 0xce, 0xf2, 0x2b, 0x82, 0x8b, 0x98, 0x72, 0xda, 0x01, 0xf9, 0x6f, 0x58, 0x65, 0x27, 0x17, 0xcf, 0x3c, 0xc2, 0x3e, 0xa2, 0x32, 0x03, 0xf5, 0x87, 0x97, 0x86, 0xda, 0x4d, 0x26, 0x19, 0x8e, 0xd2, 0x7e, 0x3f, 0xf1, 0x4a, 0xf0, 0x70, 0xaf, 0xb2, 0x31, 0xe4, 0x36, 0xc6, 0x3f, 0x97, 0x59, 0x99, 0xca, 0x88, 0x69, 0xdc, 0x99, 0x35, 0x64, 0x44, 0x28, 0xba, 0xab, 0xe0, 0xd3, 0x13, 0x5b, 0xaf, 0xb8, 0x6c, 0xdf, 0xfc, 0xa3, 0x66, 0x99, 0x84, 0x43, 0xca, 0x04, 0x24, 0x15, 0x63, 0xd2, 0x8f, 0xbf, 0x02, 0x52, 0xa1, 0x4e, 0xda, 0x80, 0x1d, 0x9f, 0x2c, 0xda, 0xf5, 0x41, 0x95, 0x17, 0x9d, 0x55, 0x3a, 0x53, 0xc5, 0xb0, 0xeb, 0x1b, 0x2d, 0x31, 0xab, 0xe2, 0x4c, 0x4b, 0x3c, 0xb2, 0xcd, 0x14, 0x5b, 0x12, 0xf6, 0x28, 0x70, 0x98, 0xe2, 0x43, 0xa8, 0xb7, 0x29, 0x40, 0x4d, 0xaa, 0x24, 0xdd, 0x6c, 0xfb, 0x2f, 0x35, 0x5d, 0x40, 0x0f, 0x32, 0x80, 0x53, 0xd1, 0xe7, 0xd5, 0xf6, 0x2a, 0xbd, 0x0d, 0x97, 0xa1, 0xb1, 0x3b, 0x46, 0xc1, 0x8c, 0x0d, 0x01, 0x71, 0xf2, 0xcb, 0x0b, 0x64, 0xaa, 0x7b, 0xa4, 0xdd, 0xc4, 0xe1, 0x5c, 0x23, 0x7a, 0x21, 0xa5, 0x4f, 0xd6, 0x86, 0xf7, 0x39, 0x60, 0x0b, 0x5f, 0x33, 0xe4, 0x8f, 0xac, 0xc4, 0x72, 0x4e, 0x5d, 0xe8, 0x40, 0x3b, 0x5b, 0xbc, 0x12, 0x9e, 0xe7, 0xb9, 0x2e, 0xb1, 0x98, 0xbf, 0x43, 0x35, 0x52, 0xfa, 0x23, 0x81, 0x92, 0x8d, 0xd7, 0xdf, 0xef, 0x01, 0x0e, 0x69, 0xdf, 0x44, 0xe4, 0x67, 0xb4, 0x20, 0x54, 0x28, 0x60, 0xb4, 0x94, 0xd4, 0x9c, 0x5d, 0x14, 0x8c, 0xc0, 0x68, 0x46, 0x71, 0x4e, 0xf9, 0x17, 0xfd, 0x22, 0x50, 0x03, 0x67, 0xce, 0x71, 0xe4, 0x80, 0x30, 0xc4, 0x9d, 0x13, 0x26, 0x45, 0x45, 0x82, 0x0d, 0x76, 0xd5, 0xfe, 0x1c, 0x1f, 0x19, 0xc5, 0x75, 0x4d, 0xf4, 0xa5, 0x91, 0x8e, 0x3a, 0x2f, 0xb0, 0x80, 0xf9, 0x33, 0xc0, 0x20, 0x74, 0x20, 0xdc, 0xf8, 0x45, 0xab, 0x87, 0x76, 0x02, 0x2d, 0xdf, 0xd4, 0x08, 0x98, 0xb6, 0xd4, 0x6d, 0x90, 0x65, 0xf2, 0x12, 0xfb, 0x87, 0xd6, 0x92, 0xa6, 0x9a, 0xbc, 0x5a, 0xcb, 0x5e, 0xc6, 0xf4, 0x99, 0x81, 0x37, 0xf9, 0x61, 0x7f, 0xd9, 0xe0, 0x97, 0x86, 0x75, 0x13, 0xe7, 0x92, 0xbe, 0x94, 0xb7, 0xee, 0xb4, 0x04, 0x61, 0xed, 0x4c, 0x0f, 0x3e, 0x22, 0xa9, 0x2b, 0x9e, 0xfe, 0xf8, 0xe6, 0x69, 0x5b, 0x7c, 0xe0, 0xc7, 0x29, 0xf2, 0x30, 0x96, 0x44, 0x23, 0x3a, 0xaf, 0x86, 0x15, 0x63, 0xbf, 0xf6, 0xfc, 0x35, 0x9c, 0x07, 0x6c, 0x76, 0xca, 0xb8, 0xaa, 0xf2, 0x93, 0xfa, 0x9e, 0x27, 0x2a, 0x6a, 0x4b, 0xd0, 0xdf, 0x1a, 0xc1, 0x1a, 0xd9, 0x0f, 0x5d, 0xee, 0x7a, 0x11, 0x51, 0xf7, 0xd5, 0xa7, 0x0b, 0x73, 0xe1, 0x99, 0x26, 0xbe, 0xb2, 0xb9, 0x7e, 0x5d, 0x68, 0xa2, 0x32, 0x7a, 0x2e, 0x79, 0xf4, 0xaf, 0xaa, 0xa4, 0x7b, 0x42, 0x6e, 0xb8, 0x1e, 0xe7, 0xeb, 0x05, 0xd2, 0x2b, 0xe8, 0x10, 0xa0, 0x12, 0xfb, 0x8a, 0xb7, 0xa8, 0x20, 0xa1, 0xbb, 0x7e, 0x04, 0x06, 0xbf, 0x34, 0xf6, 0xa5, 0x4f, 0x1b, 0x87, 0xf7, 0xd5, 0xfa, 0x61, 0xac, 0x59, 0x94, 0xc0, 0x34, 0x49, 0x25, 0x82, 0x59, 0xe5, 0x0d, 0xe3, 0xb7, 0x54, 0xb5, 0xcf, 0x7b, 0x6e, 0x54, 0xe3, 0xeb, 0x8a, 0xa5, 0x01, 0x6a, 0xcb, 0x60, 0xea, 0x3c, 0xc9, 0x5b, 0xaf, 0x26, 0x7a, 0x70, 0x50, 0x22, 0x9f, 0x05, 0x66, 0x3e, 0xcf, 0x81, 0x78, 0x4a, 0xf0, 0x25, 0x1e, 0x1f, 0x36, 0xb6, 0x88, 0x81, 0x29, 0x14, 0xa7, 0x08, 0x67, 0x05, 0x4c, 0xd6, 0x51, 0xef, 0x23, 0xbe, 0x1a, 0xfb, 0x14, 0xcb, 0x6c, 0x23, 0x69, 0x8e, 0xca, 0xa7, 0x1f, 0x7b, 0xdf, 0xc8, 0x6e, 0x75, 0xb6, 0x8f, 0x5a, 0x56, 0x1e, 0x35, 0x01, 0x81, 0xd7, 0x21, 0xb5, 0x65, 0xbc, 0x98, 0xf1, 0x2c, 0xda, 0x85, 0x96, 0x57, 0x53, 0x15, 0x02, 0xb3, 0xdc, 0xed, 0x30, 0x3c, 0xa9, 0xc8, 0x79, 0x16, 0x82, 0x54, 0xdb, 0x0c, 0x16, 0x7f, 0x99, 0xc3, 0x9d, 0x40, 0x76, 0xb1, 0x1f, 0xce, 0x7a, 0xe2, 0x8b, 0x8d, 0xa7, 0xf3, 0x00, 0x3b, 0x51, 0x60, 0x64, 0x84, 0x16, 0xe8, 0xa7, 0x4b, 0x1b, 0x36, 0x09, 0xf1, 0xd1, 0x58, 0xca, 0x4d, 0xdb, 0x14, 0x21, 0x43, 0x94, 0xcb, 0xcd, 0xfd, 0x3a, 0x0c, 0xc2, 0x08, 0x55, 0x80, 0x89, 0x77, 0x64, 0x44, 0xc9, 0xce, 0x2f, 0xad, 0x53, 0x7a, 0xd6, 0x7c, 0xde, 0x5a, 0xef, 0x61, 0x40, 0xbe, 0xb2, 0xe5, 0x71, 0x71, 0x25, 0xa3, 0x53, 0xc8, 0x0f, 0x92, 0x91, 0xcd, 0x81, 0xeb, 0x33, 0x60, 0x9f, 0xee, 0x41, 0xd9, 0x08, 0x71, 0x3d, 0x24, 0xa9, 0xbf, 0x44, 0x11, 0x17, 0xd2, 0x3c, 0x65, 0x94, 0xc4, 0x0e, 0xad, 0x1a, 0x59, 0x82, 0x96, 0xef, 0xb7, 0xf7, 0xe0, 0xe9, 0x3a, 0x13, 0xa2, 0xe0, 0xbf, 0x13, 0xbc, 0xe7, 0x7a, 0x43, 0x57, 0xfc, 0x6e, 0xd1, 0x69, 0x52, 0xf0, 0xe9, 0xac, 0x1f, 0xd0, 0xc2, 0xc6, 0x8b, 0x46, 0x78, 0xb1, 0xa5, 0x3d, 0x38, 0x57, 0x65, 0x52, 0xb0, 0xa3, 0x2b, 0xd1, 0x4b, 0xf4, 0x4f, 0x00, 0x86, 0x38, 0xad, 0x41, 0x75, 0xcf, 0xcc, 0x84, 0xe8, 0x8c, 0xd7, 0x4d, 0x12, 0xa5, 0x06, 0xbb, 0x5f, 0xee, 0x20, 0x82, 0x6d, 0x74, 0xea, 0xca, 0xd3, 0x4c, 0x44, 0x06, 0x6d, 0x9b, 0x6a, 0x9a, 0x2b, 0x48, 0x27, 0x59, 0x19, 0xd7, 0x3e, 0xdb, 0x8f, 0xcc, 0x55, 0x08, 0xf4, 0xb2, 0x30, 0x34, 0x8a, 0xa3, 0x6b, 0x69, 0x3b, 0x2a, 0x4e, 0x22, 0xd4, 0x24, 0x97, 0xfb, 0xcf, 0x0b, 0x75, 0x76, 0xed, 0xb1, 0x41, 0x5e, 0xf2, 0x8c, 0x04, 0xc4, 0x4d, 0x8b, 0x6f, 0xb8, 0x9a, 0x18, 0xe3, 0x57, 0x86, 0x71, 0xbd, 0x36, 0x2f, 0x66, 0x93, 0xda, 0xf0, 0xf7, 0xa9, 0xa2, 0x45, 0x26, 0x5a, 0x11, 0x37, 0x93, 0x34, 0x93, 0x22, 0xee, 0xd5, 0x3c, 0x98, 0x15, 0x8a, 0x0a, 0x8b, 0xe7, 0x62, 0xdf, 0x2c, 0xb2, 0x3f, 0x39, 0x4a, 0x7d, 0xf0, 0x01, 0xbf, 0xd7, 0xab, 0xad, 0x9c, 0x61, 0x8c, 0x09, 0x20, 0x64, 0xf5, 0x95, 0xf9, 0x7d, 0xfd, 0xa1, 0xe7, 0x47, 0x36, 0x49, 0x9b, 0x1b, 0xb8, 0xba, 0xff, 0x30, 0x22, 0x3e, 0xca, 0x8e, 0x8d, 0x4e, 0x4d, 0x5d, 0xa1, 0x83, 0x35, 0x08, 0x01, 0xc1, 0x2e, 0xaf, 0x91, 0xc7, 0x17, 0x40, 0xfe, 0x48, 0x9b, 0x04, 0x69, 0x34, 0x90, 0xe0, 0x6f, 0xec, 0x31, 0x11, 0x0d, 0x90, 0xa0, 0x32, 0xf3, 0xd9, 0x7b, 0xda, 0x7e, 0x05, 0x5d, 0x0e, 0xe0, 0xfd, 0xbf, 0x92, 0x37, 0x17, 0xf5, 0x13, 0xae, 0x2e, 0x64, 0xfe, 0x47, 0xa8, 0x49, 0xca, 0x77, 0xa4, 0x38, 0x3b, 0xe9, 0x0a, 0x19, 0x43, 0xd1, 0x8f, 0xc1, 0xb3, 0xf8, 0x8f, 0x88, 0x7d, 0xe1, 0xc0, 0xc5, 0xf0, 0xee, 0xe9, 0xbc, 0x44, 0x72, 0x65, 0xb6, 0x04, 0xf4, 0xfe, 0x61, 0x32, 0x82, 0x17, 0x7c, 0xe9, 0xe8, 0xd7, 0x64, 0xc3, 0xba, 0xc6, 0x44, 0x91, 0x6e, 0x1f, 0xad, 0xe2, 0xcc, 0x07, 0x41, 0x93, 0xc2, 0xbf, 0x3a, 0xa4, 0xd9, 0x26, 0x25, 0xae, 0x9a, 0x62, 0xff, 0xff, 0x08, 0x13, 0xa9, 0x3c, 0xdf, 0xe7, 0x58, 0x2b, 0xc1, 0x91, 0xb1, 0x01, 0x49, 0x1b, 0x61, 0x77, 0xcf, 0xe0, 0xe2, 0xed, 0x6f, 0xae, 0xc3, 0xb3, 0x43, 0x4a, 0x4d, 0x5a, 0x10, 0xcf, 0x2d, 0xc7, 0x7a, 0xb2, 0xa6, 0x18, 0x01, 0x00, 0xd6, 0xf3, 0x77, 0x6f, 0x6c, 0x16, 0x2d, 0x1a, 0xc5, 0xf1, 0xd9, 0x35, 0xcc, 0x53, 0x5b, 0x6f, 0xbd, 0x27, 0x87, 0x12, 0x92, 0x2a, 0x72, 0xa2, 0xdd, 0x58, 0x07, 0x7c, 0xd8, 0x73, 0x6a, 0x0a, 0x87, 0x35, 0x6a, 0x11, 0xa9, 0xd3, 0xaf, 0xf9, 0xaf, 0x5e, 0x62, 0xe0, 0xe7, 0x98, 0x52, 0x7b, 0xdc, 0x03, 0x9e, 0x8a, 0xac, 0x3b, 0xb2, 0xdd, 0x76, 0x5a, 0x58, 0x5e, 0x9e, 0xfd, 0xcd, 0x0a, 0xc3, 0x8a, 0xb8, 0x95, 0xe7, 0x82, 0x46, 0x42, 0x29, 0xe9, 0xa1, 0xc0, 0x5c, 0x65, 0x88, 0x9a, 0x15, 0xe0, 0x2d, 0xe8, 0x9d, 0x6c, 0x9d, 0x2f, 0x08, 0x6a, 0xbd, 0x58, 0x8f, 0xd5, 0x98, 0xf7, 0x52, 0x2e, 0x56, 0xb2, 0x10, 0x20, 0x22, 0xa8, 0x33, 0x65, 0x59, 0x04, 0x0f, 0x3b, 0xa7, 0xb3, 0x89, 0x67, 0x8b, 0x22, 0x1d, 0xa2, 0xa4, 0x58, 0xbd, 0xca, 0xad, 0x53, 0x00, 0x49, 0x92, 0x16, 0x0f, 0xab, 0xfc, 0xb6, 0x83, 0x83, 0x32, 0x9e, 0x59, 0x1d, 0x2f, 0xde, 0x9f, 0x66, 0x33, 0x7d, 0x81, 0x6d, 0x16, 0xe2, 0xf9, 0x2f, 0x0e, 0x87, 0x70, 0x5c, 0xcc, 0x82, 0x48, 0x9f, 0x43, 0x69, 0xf0, 0x97, 0x21, 0x18, 0x73, 0x9c, 0xba, 0x50, 0xb5, 0xfa, 0x81, 0x84, 0x0f, 0x03, 0x1e, 0x6b, 0x6c, 0x8f, 0x1d, 0xa0, 0x2a, 0x9d, 0xfc, 0xf2, 0xff, 0x5a, 0xa3, 0x66, 0xd1, 0x3b, 0xc8, 0x68, 0xe7, 0x95, 0xb7, 0xc0, 0x2b, 0x4f, 0x7e, 0x48, 0xe2, 0x43, 0x7a, 0x87, 0xb4, 0x9a, 0xb0, 0x07, 0x2d, 0xdd, 0xe8, 0x84, 0xd0, 0x54, 0xe6, 0x64, 0xc4, 0xc5, 0xfd, 0x04, 0x4b, 0x57, 0xf3, 0x7d, 0xd7, 0xcf, 0x2b, 0xef, 0x1b, 0xf6, 0x6a, 0xc6, 0x19, 0x92, 0x2c, 0x72, 0xd3, 0x42, 0x26, 0x25, 0x74, 0xcb, 0xb3, 0x0b, 0x7b, 0x1a, 0xfe, 0x1c, 0xe3, 0x28, 0xbb, 0x27, 0xe9, 0x26, 0xb7, 0xce, 0x62, 0x69, 0x46, 0x02, 0x1a, 0x12, 0x71, 0xc4, 0x73, 0xb3, 0x25, 0x97, 0x20, 0xbc, 0x43, 0xf0, 0xae, 0x58, 0x79, 0x07, 0xc6, 0xe2, 0xc2, 0x23, 0xc5, 0x1b, 0xfa, 0x83, 0xdf, 0x86, 0xdc, 0xaa, 0x0a, 0x64, 0x76, 0xa2, 0xfb, 0xc5, 0xe2, 0x7b, 0xe3, 0x4c, 0x26, 0x5c, 0x39, 0x9d, 0x7b, 0xd6, 0x0b, 0xd4, 0x1f, 0x74, 0x36, 0x47, 0x4d, 0xe3, 0xfa, 0xe9, 0x72, 0xd1, 0x5e, 0x28, 0x39, 0x9c, 0xd8, 0x07, 0x45, 0xfa, 0x58, 0x2d, 0x4e, 0xd9, 0x13, 0xaf, 0x13, 0xf2, 0x59, 0xea, 0x9d, 0xf1, 0x52, 0x54, 0x69, 0xb4, 0xd6, 0x49, 0xd1, 0x10, 0xeb, 0x8d, 0xb0, 0xb7, 0x2f, 0x29, 0x06, 0xdc, 0x83, 0xd6, 0x7e, 0xd3, 0xf9, 0x50, 0x05, 0xbe, 0x3c, 0x60, 0x3a, 0xd1, 0xc7, 0xe3, 0xfb, 0x87, 0x31, 0x0d, 0xeb, 0xb7, 0xbd, 0xbc, 0x79, 0x68, 0x7d, 0x25, 0x86, 0x4c, 0x86, 0x56, 0x20, 0x42, 0x26, 0x58, 0xf8, 0x94, 0xa2, 0x95, 0x10, 0xea, 0x20, 0x50, 0xcf, 0x6d, 0x9c, 0x06, 0x43, 0x35, 0xf4, 0x0f, 0xd2, 0x41, 0x76, 0xa4, 0xb2, 0x1e, 0x3e, 0x91, 0x3a, 0xb0, 0x20, 0xa9, 0x94, 0xa8, 0x26, 0x45, 0xbf, 0xbf, 0x5b, 0x98, 0x1c, 0x79, 0x47, 0x37, 0xe5, 0x89, 0x4a, 0xbb, 0xf0, 0x86, 0xa3, 0x61, 0x59, 0x36, 0xe7, 0xd8, 0xc3, 0x4a, 0x45, 0x80, 0x8f, 0xa2, 0x1b, 0x82, 0xf3, 0x6f, 0x3d, 0x4e, 0x56, 0xe1, 0x98, 0xaf, 0xc8, 0xfd, 0xe4, 0x32, 0x74, 0x1f, 0x8b, 0x4a, 0xf1, 0xd1, 0x5a, 0x09, 0x3c, 0x89, 0x7e, 0x4f, 0x79, 0x49, 0xb5, 0x51, 0x6a, 0x1e, 0x2a, 0xe6, 0x38, 0x41, 0x5e, 0xcb, 0x0e, 0x2d, 0xb1, 0x9d, 0xcf, 0x4a, 0x49, 0x84, 0xe7, 0xf9, 0x96, 0xce, 0x14, 0xee, 0xb5, 0x98, 0x6a, 0xd8, 0x86, 0x2d, 0x90, 0xbe, 0x81, 0x3d, 0x01, 0x0f, 0xb0, 0x9d, 0x74, 0x70, 0x8e, 0xb5, 0xe5, 0x7a, 0xf1, 0xcd, 0xc4, 0x48, 0x67, 0x87, 0xbd, 0x7c, 0xcf, 0xa9, 0xbb, 0x27, 0x02, 0x1c, 0x92, 0x3f, 0x3e, 0xc9, 0x77, 0x77, 0xa5, 0xbf, 0xe8, 0x36, 0x15, 0x4b, 0x5c, 0xad, 0x6a, 0x8c, 0xcb, 0xa5, 0x25, 0xf0, 0x40, 0x12, 0x2b, 0x97, 0xa7, 0xa3, 0x32, 0x61, 0x75, 0x50, 0x8f, 0x54, 0xd0, 0xda, 0x35, 0x09, 0x18, 0xde, 0x36, 0x9a, 0x05, 0xd5, 0xeb, 0xfe, 0xe4, 0x0d, 0xb7, 0x85, 0xaa, 0x5f, 0xba, 0x2e, 0xdc, 0x16, 0xbd, 0xf7, 0x37, 0xef, 0x84, 0xab, 0x9e, 0x16, 0x6b, 0x51, 0x5e, 0xdd, 0xb4, 0x77, 0x0d, 0xc6, 0x24, 0x5f, 0xe4, 0x12, 0xf1, 0x90, 0x64, 0xe1, 0x43, 0xde, 0x3a, 0x7b, 0x9f, 0x5a, 0x9c, 0x0a, 0x0b, 0xec, 0x8d, 0xb9, 0xc5, 0x21, 0xa5, 0x02, 0xd8, 0x32, 0xf6, 0x4d, 0x99, 0x6c, 0x64, 0x0e, 0xc3, 0xab, 0xd2, 0x7f, 0x3c, 0xa9, 0x13, 0x92, 0xf2, 0x39, 0xf6, 0x18, 0xd4, 0x32, 0xa3, 0x82, 0xa0, 0x54, 0x30, 0xd0, 0x67, 0xda, 0x68, 0x05, 0xf2, 0xb5, 0xa8, 0x37, 0xd9, 0x14, 0xd1, 0x16, 0x90, 0xfb, 0x96, 0xf7, 0xb9, 0xac, 0x72, 0x84, 0x41, 0x02, 0xeb, 0xbb, 0x89, 0x69, 0x6e, 0x17, 0x8e, 0xfe, 0x60, 0xb2, 0x05, 0x34, 0x2d, 0x56, 0x69, 0xca, 0xaa, 0xff, 0x50, 0xb9, 0x13, 0xf7, 0xdd, 0x2b, 0x3d, 0x9b, 0xc6, 0xcf, 0xe6, 0x1e, 0x5d, 0x25, 0xb8, 0x13, 0x6b, 0x39, 0xf4, 0x36, 0x98, 0x03, 0x7a, 0x04, 0x3a, 0x8a, 0x49, 0xdb, 0xf8, 0xed, 0x0d, 0x22, 0xc5, 0x54, 0x65, 0x93, 0x1e, 0x9e, 0x5c, 0xe2, 0xf5, 0xbc, 0xc3, 0x09, 0x20, 0x6a, 0x70, 0xe0, 0x4c, 0x91, 0x7b, 0x99, 0x17, 0xf5, 0xf4, 0x5e, 0xb5, 0xc9, 0xe7, 0x25, 0x0b, 0x96, 0xa6, 0x55, 0xae, 0x74, 0x47, 0xca, 0x92, 0xbe, 0x47, 0x11, 0x35, 0x9c, 0xa8, 0xd8, 0x73, 0x40, 0x56, 0x1d, 0xfb, 0x7f, 0xc8, 0x62, 0x60, 0xa6, 0x90, 0x05, 0x69, 0xc2, 0xcd, 0xea, 0x57, 0xf8, 0xb7, 0x24, 0x32, 0x8d, 0xa1, 0x83, 0xfa, 0x33, 0x01, 0xd6, 0x6e, 0x67, 0x85, 0x03, 0xf3, 0x2a, 0x86, 0x0b, 0xb5, 0xcf, 0x54, 0xf5, 0xe5, 0xb6, 0x54, 0x67, 0x72, 0x6c, 0x16, 0x14, 0xf0, 0xc4, 0xa9, 0x11, 0x3e, 0x94, 0x97, 0xf7, 0x32, 0xe4, 0x68, 0x08, 0x06, 0x2e, 0x8f, 0xbc, 0x50, 0xaf, 0xd8, 0x77, 0x59, 0x87, 0x91, 0x00, 0x03, 0xd7, 0xa6, 0x4f, 0xfc, 0x10, 0x3a, 0xba, 0x94, 0x8d, 0x80, 0x1f, 0xa5, 0x5f, 0x68, 0xec, 0xda, 0x98, 0x36, 0x28, 0x12, 0xcc, 0xa6, 0x5f, 0x1d, 0x52, 0xcc, 0x7b, 0xeb, 0x24, 0x11, 0x97, 0x3a, 0x9f, 0xc2, 0xd9, 0x34, 0x7f, 0x73, 0xc9, 0x05, 0x0a, 0x7a, 0xaa, 0xac, 0x14, 0x57, 0x23, 0x50, 0x7b, 0x6c, 0x3f, 0xf1, 0xa6, 0x5e, 0x87, 0xe1, 0x8e, 0x4f, 0x44, 0xca, 0xf6, 0x69, 0x08, 0xd8, 0x9c, 0x98, 0xb2, 0x74, 0x58, 0x28, 0xaa, 0xc9, 0x82, 0xf6, 0xd7, 0xa7, 0x82, 0x4c, 0x31, 0x9c, 0xe8, 0x00, 0x77, 0x38, 0xfd, 0x14, 0x59, 0x37, 0xab, 0x43, 0xc6, 0xe8, 0xbb, 0x56, 0x7b, 0xdb, 0x1a, 0x42, 0x07, 0x6f, 0x70, 0xc4, 0xe8, 0x2c, 0x3f, 0x43, 0xb1, 0x22, 0x5e, 0xe5, 0x7d, 0xf8, 0x74, 0x14, 0xb4, 0x65, 0xd3, 0x6c, 0x90, 0x33, 0x27, 0x1b, 0x8c, 0x04, 0xc7, 0x3f, 0x76, 0xe6, 0x09, 0xe0, 0x3d, 0x2b, 0x4a, 0x8d, 0xd8, 0x81, 0x16, 0x1d, 0xcb, 0x60, 0x43, 0x8b, 0x99, 0xc9, 0xd4, 0x4d, 0x70, 0xb8, 0xd9, 0x50, 0x51, 0xb1, 0xea, 0x9e, 0xcc, 0x17, 0x76, 0x30, 0x3f, 0x2d, 0xdc, 0xcb, 0xfb, 0x8d, 0x32, 0x7f, 0x3f, 0x86, 0x56, 0xe5, 0xd1, 0xda, 0x51, 0x58, 0x75, 0xd1, 0xc7, 0xb5, 0x61, 0x7a, 0x09, 0xe0, 0x4a, 0xbe, 0xc5, 0x23, 0xe7, 0x6e, 0x5f, 0x41, 0xea, 0xc9, 0x0d, 0xba, 0x7b, 0x2a, 0x62, 0xfc, 0x48, 0xc9, 0x2a, 0xec, 0xe6, 0x5c, 0xc4, 0x46, 0x75, 0x9d, 0xb2, 0x02, 0x45, 0x33, 0x8a, 0x69, 0xda, 0xf5, 0xd5, 0xa2, 0xdc, 0xb9, 0x02, 0x4a, 0x3f, 0xbd, 0xc1, 0x21, 0x59, 0x5f, 0xde, 0xf0, 0xd9, 0xed, 0x43, 0x27, 0x43, 0x61, 0x92, 0x96, 0xe9, 0xf7, 0xd3, 0x7f, 0xc6, 0x64, 0x1a, 0x1b, 0x09, 0x2f, 0xa4, 0xa5, 0xb7, 0xfd, 0x5e, 0x23, 0xdf, 0x72, 0xdf, 0x18, 0x8a, 0xbe, 0x70, 0xe4, 0x5f, 0x2d, 0x65, 0x45, 0xa4, 0x13, 0xbb, 0x1a, 0xdb, 0x2e, 0x7b, 0x71, 0xfa, 0x95, 0x9c, 0x3e, 0xe0, 0x88, 0xcc, 0x23, 0x0b, 0x02, 0x78, 0xaf, 0xb5, 0xa8, 0x8f, 0xdd, 0x4c, 0xd5, 0x1d, 0x6a, 0x03, 0x85, 0xf7, 0x9c, 0xf1, 0x8b, 0xdc, 0x9f, 0x61, 0x2c, 0x03, 0xed, 0x53, 0xcc, 0xa9, 0xcb, 0xff, 0x4f, 0x82, 0x48, 0xf2, 0xd6, 0xa0, 0xb3, 0x9e, 0x6f, 0x7a, 0x2e, 0x26, 0x49, 0x0b, 0x78, 0xbf, 0xf7, 0xab, 0x56, 0x19, 0xea, 0x96, 0x75, 0xbf, 0x0d, 0x46, 0x2b, 0xad, 0xfd, 0x73, 0x36, 0x14, 0x12, 0xc0, 0xc6, 0x82, 0x7e, 0x1f, 0x5f, 0x95, 0x41, 0x1e, 0xa8, 0xaf, 0xfb, 0x02, 0x93, 0x65, 0xb4, 0x01, 0x27, 0x73, 0x25, 0xb5, 0x1f, 0x8a, 0x1c, 0x2e, 0x9d, 0x78, 0xf9, 0x5c, 0xf8, 0xa4, 0xcc, 0x2b, 0x6a, 0x21, 0x20, 0xe8, 0x84, 0x45, 0x19, 0xb1, 0x8a, 0xac, 0x9b, 0x3a, 0xc0, 0x72, 0x7c, 0x0d, 0x1d, 0xa3, 0xd4, 0x36, 0x06, 0x4b, 0x0a, 0x75, 0xb9, 0x7c, 0xee, 0x67, 0xf1, 0x4d, 0x55, 0x14, 0x71, 0x25, 0x2d, 0xff, 0xb1, 0x75, 0x7e, 0x8c, 0xa4, 0x1b, 0x1a, 0x4f, 0x89, 0x44, 0x8a, 0xa0, 0xeb, 0xbc, 0xba, 0x66, 0x1a, 0x8f, 0x02, 0x35, 0xc5, 0xaf, 0x9e, 0x55, 0x80, 0xe0, 0xee, 0x2f, 0x21, 0x92, 0x51, 0x43, 0x0e, 0xac, 0x16, 0x51, 0xbf, 0x34, 0x33, 0xf0, 0xca, 0x16, 0x3d, 0x55, 0x8f, 0xb6, 0xf4, 0x07, 0x85, 0xb6, 0x67, 0x0e, 0x4e, 0xd7, 0xae, 0xd2, 0x59, 0xc5, 0x62, 0x89, 0x62, 0xef, 0x27, 0xfa, 0x2b, 0x35, 0x86, 0x4a, 0x57, 0x31, 0xc3, 0x94, 0xb4, 0x81, 0xd0, 0x11, 0x15, 0x63, 0xd7, 0xbe, 0x3c, 0x2f, 0x8b, 0x21, 0xbd, 0x1a, 0x82, 0x6d, 0xef, 0x2d, 0x03, 0x49, 0xac, 0xe2, 0xc0, 0x09, 0x5b, 0x5b, 0xd5, 0x9a, 0xed, 0xb8, 0xfc, 0xa8, 0x54, 0x6c, 0xb9, 0xdf, 0xa8, 0x3c, 0x44, 0x30, 0xe6, 0x20, 0xef, 0xad, 0xa5, 0x5e, 0x29, 0xfc, 0x9e, 0x69, 0x39, 0x08, 0xec, 0x94, 0x6a, 0xa7, 0xab, 0xdc, 0xdd, 0x4b, 0x5c, 0x4e, 0xa1, 0xfc, 0xd1, 0x7d, 0x46, 0xb9, 0xc9, 0x9e, 0xef, 0x9c, 0xec, 0x45, 0xec, 0x40, 0x19, 0x3c, 0x8c, 0xdd, 0xa3, 0x11, 0x39, 0x53, 0xb7, 0x6c, 0x97, 0x35, 0xf6, 0xd6, 0x9a, 0x61, 0xf0, 0x43, 0xc9, 0x1a, 0x6c, 0xdf, 0x51, 0xe6, 0x8c, 0x2c, 0x21, 0x58, 0xc1, 0x9d, 0xe5, 0x87, 0xef, 0xab, 0x21, 0xc8, 0xc8, 0xc6, 0x30, 0x92, 0x92, 0x99, 0x5b, 0x42, 0xe5, 0xfb, 0xab, 0x72, 0xce, 0xe1, 0xf4, 0x10, 0xd0, 0xa6, 0x29, 0x29, 0x84, 0x6f, 0x13, 0xbc, 0xf9, 0xdc, 0x36, 0xae, 0x07, 0x71, 0x4a, 0x3a, 0xe4, 0x75, 0xaf, 0xce, 0xc7, 0x83, 0x64, 0xbd, 0xc8, 0x44, 0xfe, 0xfb, 0x82, 0x96, 0x7d, 0x0c, 0x0b, 0xe4, 0xdb, 0xa0, 0xd0, 0x67, 0x3d, 0xec, 0xfd, 0x25, 0xb1, 0x53, 0x7e, 0x48, 0x33, 0x17, 0x96, 0xd3, 0x42, 0xf1, 0x00, 0xa4, 0x66, 0x9d, 0xe2, 0xa4, 0x1c, 0x6a, 0xfd, 0xce, 0x38, 0xbc, 0xe4, 0x59, 0x11, 0x74, 0xf4, 0xab, 0xa0, 0x66, 0x50, 0x55, 0x3d, 0xdf, 0x1e, 0x7a, 0xb6, 0x96, 0xa2, 0x59, 0x84, 0x0d, 0xec, 0x27, 0x93, 0x8a, 0xcf, 0x3a, 0x38, 0x11, 0x20, 0xfa, 0x89, 0x6e, 0x97, 0xe5, 0x54, 0x07, 0x00, 0x92, 0x6a, 0x7f, 0x62, 0xd2, 0xdc, 0x09, 0x8b, 0x20, 0x98, 0x58, 0xf9, 0x80, 0xc7, 0xd1, 0x37, 0xe2, 0x4b, 0x8d, 0xef, 0x1c, 0x61, 0x05, 0x28, 0x12, 0xd3, 0x7a, 0x72, 0x36, 0xbe, 0x38, 0x0a, 0x13, 0x66, 0x89, 0x64, 0xa7, 0x48, 0xaf, 0xff, 0x0f, 0xdd, 0x7b, 0xba, 0x50, 0xad, 0x80, 0x76, 0x96, 0x0a, 0xef, 0x10, 0xa9, 0xd0, 0x31, 0x73, 0x57, 0x4d, 0xcd, 0x80, 0x00, 0xb4, 0x93, 0xf3, 0xfa, 0xb1, 0xb6, 0xdf, 0x3c, 0x65, 0x58, 0x78, 0x24, 0xad, 0x0e, 0x3b, 0x0b, 0xa9, 0x84, 0x63, 0x80, 0x04, 0x30, 0x05, 0xb1, 0x0f, 0x3a, 0x66, 0x51, 0xcb, 0x9b, 0x68, 0x0c, 0xd8, 0x37, 0x53, 0x58, 0x79, 0x9c, 0xc4, 0x4c, 0xd4, 0x02, 0xfd, 0x49, 0xe8, 0x70, 0x0e, 0x2e, 0xd3, 0x94, 0x8e, 0x62, 0x23, 0xa4, 0x2a, 0xea, 0x63, 0xa7, 0x9f, 0x4d, 0x97, 0x5c, 0xd5, 0x3e, 0x91, 0x77, 0x6e, 0x27, 0xc1, 0x26, 0xc3, 0x8f, 0x80, 0xe4, 0xab, 0x19, 0x6f, 0xf8, 0x0c, 0x8d, 0xc8, 0xbe, 0x4b, 0x79, 0x78, 0xeb, 0x0e, 0xd6, 0x3d, 0x96, 0x0a, 0x57, 0xec, 0x43, 0x93, 0xb2, 0x7d, 0x05, 0x25, 0x2f, 0x45, 0xa9, 0xf5, 0xf4, 0xcf, 0x97, 0xc7, 0xe4, 0x77, 0xdd, 0x33, 0xc1, 0x42, 0x64, 0x14, 0x66, 0xdb, 0x68, 0xbb, 0xb3, 0x4e, 0x37, 0x8a, 0x1a, 0x22, 0xc9, 0xc6, 0xcc, 0x12, 0x85, 0x3d, 0xd4, 0x36, 0xc3, 0x30, 0xee, 0x73, 0xc2, 0x0c, 0x91, 0xe0, 0x7b, 0x41, 0x58, 0x18, 0x88, 0xb6, 0x43, 0xb1, 0x07, 0x26, 0xe7, 0xf7, 0x75, 0xc7, 0x2b, 0xbb, 0x8f, 0x9f, 0x55, 0xe1, 0xe7, 0xf6, 0x33, 0xc9, 0x5f, 0xd2, 0x59, 0x73, 0x81, 0x2e, 0xdd, 0x09, 0x06, 0xcf, 0xc5, 0x52, 0x67, 0x95, 0xee, 0xfe, 0x28, 0xba, 0x34, 0x07, 0xd7, 0x5d, 0xdf, 0xa7, 0x04, 0x14, 0x81, 0x8e, 0x2f, 0x3d, 0x68, 0xf9, 0x95, 0x11, 0x5f, 0x11, 0x3d, 0x1a, 0xd8, 0x9b, 0xe0, 0x51, 0xf4, 0x41, 0xbb, 0xcc, 0xfb, 0xe9, 0xe6, 0x5b, 0x45, 0xb8, 0x69, 0x33, 0x99, 0xb7, 0xe5, 0xf7, 0x2e, 0x7b, 0xc0, 0x78, 0x3c, 0xa6, 0xe8, 0x91, 0x5f, 0x20, 0x61, 0x96, 0x5d, 0x82, 0x17, 0xf4, 0xd4, 0x9f, 0xb7, 0x0c, 0x47, 0x76, 0x7d, 0xd8, 0x19, 0x27, 0x59, 0x34, 0xb3, 0x1b, 0xcc, 0xec, 0xc4, 0x4b, 0x1d, 0xac, 0x04, 0x6a, 0x50, 0x9a, 0xe6, 0xa1, 0x43, 0x08, 0xc8, 0x11, 0x32, 0xdf, 0xba, 0x58, 0x3b, 0x28, 0xbb, 0x1f, 0x76, 0x1e, 0x4e, 0xb1, 0x85, 0x8d, 0x66, 0xca, 0x6e, 0xc2, 0x0b, 0xe8, 0x28, 0x74, 0xc4, 0xaa, 0x4c, 0x19, 0x7c, 0x90, 0x69, 0x36, 0x00, 0x07, 0x0c, 0xbb, 0x41, 0xaf, 0xfe, 0x9c, 0xa0, 0x16, 0xe1, 0xeb, 0x78, 0x7e, 0x77, 0xe8, 0xa6, 0x53, 0x43, 0x2d, 0xa2, 0xfa, 0x5e, 0x61, 0xa0, 0xb9, 0xb2, 0x77, 0x9e, 0x4f, 0xf0, 0x4c, 0x11, 0x1a, 0xb1, 0xba, 0x49, 0x64, 0x2d, 0xcc, 0xc0, 0x5f, 0xda, 0x9d, 0xa0, 0x79, 0x6a, 0x3b, 0xc1, 0x8b, 0x0c, 0x87, 0xe0, 0x6b, 0x1d, 0x1a, 0x4b, 0x0c, 0xc2, 0x99, 0x95, 0xab, 0x24, 0xbf, 0x2f, 0x5b, 0xd2, 0x8d, 0xff, 0x88, 0x18, 0x3c, 0x45, 0x4b, 0x63, 0x24, 0xc1, 0x89, 0x78, 0xdd, 0xbd, 0x5b, 0x25, 0xa7, 0xc1, 0x9e, 0x51, 0x29, 0x48, 0xc2, 0xcf, 0xd1, 0x88, 0x76, 0x7f, 0xd0, 0xf6, 0x6d, 0x91, 0x9a, 0x29, 0x4e, 0x6e, 0x4b, 0xbe, 0x1e, 0x8a, 0xd5, 0xca, 0x72, 0x22, 0x8b, 0x20, 0x97, 0x0a, 0x82, 0xdf, 0xab, 0x02, 0x41, 0x22, 0xe6, 0x12, 0xed, 0xcd, 0xc2, 0x14, 0x30, 0xa7, 0xb5, 0xea, 0x87, 0x54, 0xb9, 0x3b, 0xf0, 0x09, 0xd8, 0x3e, 0x8c, 0xc4, 0xdf, 0x74, 0xfb, 0x02, 0xee, 0x6d, 0x87, 0x00, 0xb2, 0x36, 0x63, 0xf1, 0x48, 0x31, 0x77, 0x5d, 0xfc, 0xaa, 0xd8, 0x72, 0x5d, 0x99, 0x5b, 0xf7, 0x70, 0x9b, 0xa1, 0x3d, 0xb2, 0xd8, 0xdc, 0xef, 0x0a, 0x53, 0xcb, 0xff, 0xa0, 0x28, 0x81, 0x31, 0xa0, 0xd3, 0xd8, 0x59, 0xe7, 0xf8, 0x88, 0x60, 0x1e, 0xd2, 0x8f, 0x56, 0x33, 0x71, 0x6f, 0xf9, 0xfb, 0xa8, 0xca, 0x4c, 0x4d, 0x22, 0x1a, 0x2b, 0xb4, 0xd6, 0x60, 0xd6, 0x8e, 0x05, 0xf3, 0xf8, 0x82, 0x74, 0x14, 0x24, 0xe3, 0x29, 0x4e, 0x1e, 0xea, 0xa9, 0xcc, 0xce, 0x8c, 0xf8, 0x6b, 0x6f, 0x91, 0xee, 0x22, 0x32, 0x04, 0x9a, 0xd9, 0x75, 0x43, 0x10, 0xf8, 0x56, 0xb2, 0x54, 0xac, 0x2d, 0xab, 0xd8, 0x42, 0xf1, 0x4c, 0x96, 0xc2, 0x7f, 0xf0, 0x72, 0x6e, 0x21, 0xa6, 0xea, 0x58, 0xd6, 0x1a, 0xe4, 0x19, 0x67, 0xb3, 0xb3, 0xe3, 0x85, 0xf3, 0x9e, 0x41, 0x70, 0x17, 0x78, 0x3f, 0xfd, 0xe8, 0xd5, 0x6c, 0xac, 0x01, 0x47, 0x30, 0x6a, 0xa5, 0xec, 0x25, 0x31, 0xb9, 0xb4, 0x09, 0xd8, 0x70, 0xde, 0x18, 0x9e, 0x7d, 0xa7, 0x17, 0xa2, 0x3c, 0x87, 0x53, 0xda, 0xf6, 0xf3, 0x5a, 0x58, 0xbb, 0x44, 0xaf, 0x48, 0xb1, 0x90, 0xcd, 0x1c, 0xfe, 0x9c, 0x86, 0x2c, 0x39, 0x41, 0x6c, 0x1e, 0x7a, 0x03, 0x6d, 0xf5, 0x55, 0x8f, 0x37, 0x8c, 0xcc, 0xb3, 0x29, 0x59, 0x48, 0x7f, 0xaa, 0xdc, 0x16, 0xfb, 0x87, 0xd6, 0xd0, 0xbb, 0x3a, 0xb9, 0x1e, 0x21, 0x18, 0x90, 0xd0, 0x88, 0xe7, 0x80, 0xee, 0x2c, 0x34, 0xaf, 0x81, 0x52, 0x28, 0x15, 0x90, 0xff, 0x61, 0x17, 0x65, 0xdd, 0x38, 0x43, 0x00, 0x4e, 0xb9, 0xb1, 0x1b, 0x7d, 0x46, 0xb7, 0x9b, 0xe3, 0x12, 0xc7, 0xa7, 0xcb, 0x3f, 0x52, 0x2b, 0x85, 0x8c, 0x82, 0xd1, 0x60, 0x5f, 0x9a, 0x3c, 0x04, 0xc3, 0x01, 0xb6, 0xad, 0x49, 0x44, 0xde, 0x13, 0xdd, 0x6a, 0x8f, 0x84, 0xbe, 0x40, 0x95, 0x3b, 0x2b, 0x39, 0x00, 0x6f, 0xa3, 0xfa, 0x02, 0x51, 0xaf, 0xe8, 0x82, 0x31, 0x5a, 0xd3, 0x13, 0x49, 0x25, 0xee, 0xfe, 0xb9, 0x6b, 0xa3, 0x86, 0x3d, 0x81, 0x1b, 0xf9, 0x0d, 0x01, 0x23, 0x6e, 0xe4, 0xb3, 0xcb, 0x30, 0x34, 0x3b, 0x47, 0xa2, 0xa0, 0x7c, 0xca, 0x09, 0x9f, 0x8f, 0x98, 0x4d, 0x39, 0xef, 0x20, 0x0b, 0x14, 0xe5, 0xdb, 0xbc, 0x7b, 0xb0, 0x60, 0x9f, 0x1c, 0x1c, 0xf1, 0x8a, 0x94, 0x38, 0xc7, 0x01, 0xe5, 0x5e, 0x5d, 0x07, 0x3f, 0x79, 0x2f, 0xfe, 0xf9, 0xec, 0x2b, 0x09, 0x48, 0x63, 0xc4, 0x72, 0x18, 0xef, 0x00, 0x72, 0x29, 0xd0, 0x86, 0x8d, 0x65, 0xdc, 0x6c, 0x7c, 0x67, 0x53, 0x4d, 0xf9, 0xdf, 0xdf, 0xa9, 0x23, 0x98, 0xc0, 0x65, 0xad, 0x16, 0x12, 0x47, 0x2f, 0xd2, 0x61, 0x71, 0x24, 0xa5, 0x96, 0x95, 0xe2, 0x11, 0xf3, 0x55, 0x7f, 0x3f, 0x8a, 0xa0, 0xd4, 0xc1, 0x2d, 0x09, 0xed, 0x4d, 0x46, 0x15, 0x01, 0x6b, 0x69, 0xce, 0xc3, 0xc9, 0x7f, 0xa8, 0xe2, 0x10, 0x40, 0xa6, 0x93, 0x95, 0xbd, 0xe9, 0x38, 0x6d, 0x07, 0xfa, 0x99, 0x5d, 0x7c, 0xf7, 0x2f, 0x24, 0x58, 0xdc, 0xbb, 0xe3, 0xee, 0x6f, 0x3d, 0x23, 0x11, 0xbf, 0x0f, 0xf0, 0xef, 0xf4, 0x7a, 0x9c, 0x37, 0x9a, 0x31, 0x55, 0x59, 0x6e, 0x8f, 0xc8, 0xaa, 0x0f, 0xad, 0x57, 0xec, 0x80, 0x0b, 0x5f, 0xd6, 0xff, 0xd3, 0x52, 0x1e, 0x7c, 0xa8, 0xde, 0xe3, 0x84, 0xc2, 0x66, 0xca, 0x15, 0xc7, 0x21, 0x9b, 0x92, 0x77, 0x64, 0x03, 0xc6, 0xd9, 0xba, 0x61, 0x40, 0x9b, 0xe5, 0x93, 0x5f, 0x4d, 0x55, 0xdb, 0xb9, 0xb6, 0x42, 0x7c, 0x8c, 0x03, 0xf5, 0xe9, 0x5a, 0x70, 0x05, 0xf7, 0x2c, 0xcd, 0xbd, 0x55, 0x34, 0x54, 0xc9, 0x91, 0x83, 0x39, 0x0f, 0x62, 0x88, 0x5c, 0xe2, 0xfd, 0x49, 0xf0, 0x52, 0xa6, 0x4e, 0xc5, 0x80, 0xb6, 0xa1, 0x57, 0x16, 0x35, 0xce, 0xac, 0xb4, 0xab, 0xd5, 0x4f, 0x38, 0x96, 0x96, 0xc5, 0xc6, 0x64, 0xa1, 0x35, 0xa4, 0x28, 0x57, 0xd6, 0x3a, 0x07, 0x0b, 0xb9, 0x2b, 0xc7, 0x19, 0x7a, 0x99, 0xec, 0x4b, 0xa9, 0xcd, 0xe5, 0xc1, 0x12, 0xa0, 0xe6, 0xf1, 0xf3, 0xa0, 0xc0, 0x4e, 0x7d, 0x06, 0xc6, 0x53, 0x40, 0x40, 0x0e, 0x99, 0x24, 0x77, 0x66, 0x6e, 0xae, 0x0a, 0xf2, 0x57, 0x49, 0xdb, 0xcd, 0x95, 0x66, 0xf8, 0xb6, 0xa4, 0x05, 0x25, 0x59, 0x53, 0x46, 0xbf, 0xf2, 0x5f, 0x72, 0x77, 0xf1, 0xd0, 0xc0, 0x2e, 0xa8, 0x14, 0x85, 0x8a, 0x64, 0x42, 0x15, 0x93, 0xa3, 0xaf, 0x0c, 0x06, 0x63, 0xd8, 0x93, 0x93, 0x2e, 0xac, 0x7c, 0xae, 0x24, 0xb7, 0xe4, 0xd2, 0x6c, 0xbe, 0x7d, 0x1b, 0x29, 0xe7, 0xce, 0xfe, 0x1c, 0x33, 0x66, 0xc6, 0xb1, 0x08, 0x65, 0x97, 0xf2, 0x78, 0x2a, 0xb7, 0xae, 0x54, 0x1b, 0x2c, 0xa3, 0x3d, 0x92, 0x48, 0x96, 0x49, 0x83, 0xee, 0x37, 0xdc, 0x04, 0xe9, 0x2a, 0x39, 0x79, 0x7a, 0xd6, 0x2a, 0xce, 0x26, 0xfb, 0x0e, 0xa7, 0xd0, 0x8d, 0x01, 0x67, 0xf3, 0x5f, 0x10, 0x79, 0xd8, 0xc2, 0xae, 0x1e, 0x6d, 0x2a, 0xd0, 0x5a, 0x72, 0x66, 0xad, 0xd2, 0xa6, 0xfb, 0x99, 0x0c, 0xc8, 0x3f, 0xda, 0x2b, 0x03, 0x72, 0xda, 0x27, 0x25, 0xba, 0x7c, 0x43, 0x13, 0xd1, 0xe0, 0xff, 0x8f, 0x8c, 0x90, 0x6b, 0x69, 0x66, 0x4a, 0xd2, 0x7c, 0x01, 0x12, 0x15, 0xe0, 0x31, 0xe9, 0xa4, 0x77, 0x89, 0xf6, 0xe8, 0xdb, 0xb3, 0xb7, 0x08, 0x97, 0x3a, 0xa0, 0xd8, 0xfa, 0x5f, 0x0d, 0x05, 0x32, 0x5e, 0x57, 0x73, 0x80, 0x43, 0xd8, 0xd3, 0x6b, 0x93, 0x07, 0x30, 0x22, 0xb6, 0xc8, 0xf9, 0xe1, 0xa5, 0xb3, 0x61, 0x67, 0x2c, 0xb0, 0xe6, 0xe5, 0xc2, 0x26, 0xa7, 0x8e, 0x8a, 0x74, 0x36, 0xa1, 0xf4, 0x15, 0x33, 0x0f, 0xe5, 0xd1, 0x8a, 0x3e, 0x89, 0x7b, 0x2d, 0x21, 0x02, 0x1c, 0xac, 0xcd, 0x4f, 0x50, 0xdd, 0xe0, 0xcc, 0x22, 0x3b, 0xed, 0x79, 0xc0, 0x3e, 0xd8, 0x09, 0x81, 0x66, 0x50, 0x9e, 0x75, 0xd6, 0x47, 0x50, 0x42, 0x1a, 0x10, 0xe3, 0x88, 0x5c, 0xa0, 0x71, 0xbb, 0xff, 0xdc, 0x3e, 0x4b, 0xa3, 0x9b, 0x7f, 0x35, 0xd5, 0xc4, 0x98, 0x45, 0x19, 0x5f, 0xbd, 0xf3, 0x79, 0x5d, 0x0a, 0xe1, 0x6f, 0xbd, 0xbc, 0xf6, 0x1e, 0x67, 0xb2, 0xfe, 0xad, 0x08, 0x5b, 0x56, 0xc8, 0x38, 0x9b, 0x5c, 0xeb, 0x85, 0xa0, 0xa8, 0xfa, 0x81, 0x50, 0x31, 0x1f, 0xc3, 0x92, 0x3b, 0x13, 0xae, 0xf7, 0x86, 0x48, 0x29, 0x47, 0x8b, 0xe0, 0x1d, 0xf9, 0x83, 0xec, 0x7c, 0x19, 0x30, 0x4a, 0xb5, 0xcb, 0x9b, 0x71, 0xab, 0xb3, 0x8b, 0x70, 0xce, 0x1e, 0x9e, 0x81, 0x62, 0x0e, 0x0f, 0x42, 0xe7, 0xf2, 0xc0, 0x37, 0x1f, 0x0a, 0x82, 0xbd, 0xd9, 0xef, 0x81, 0xb5, 0x24, 0xfd, 0x5e, 0x78, 0x49, 0x48, 0x43, 0x15, 0xf1, 0x1b, 0x5c, 0x71, 0xc4, 0x7f, 0xc6, 0x89, 0x2d, 0x41, 0x36, 0x72, 0x83, 0xba, 0x90, 0xb2, 0x43, 0x1b, 0x53, 0x68, 0xaf, 0x35, 0x2a, 0xf8, 0x7b, 0x8c, 0xde, 0xc8, 0xf6, 0x17, 0x70, 0x0a, 0x36, 0xd4, 0x51, 0x98, 0x83, 0x1b, 0xbf, 0x3c, 0x44, 0x1a, 0x59, 0x78, 0x73, 0xda, 0xc9, 0xb5, 0x33, 0x99, 0x64, 0xa0, 0xf7, 0x10, 0xe4, 0xb1, 0xd8, 0xb4, 0x81, 0x6c, 0x15, 0xf1, 0xe7, 0x56, 0x6b, 0x30, 0xae, 0x9d, 0xa4, 0xc4, 0xfc, 0x5b, 0x30, 0x73, 0xfc, 0x18, 0xea, 0xc4, 0xfe, 0x28, 0x68, 0xc7, 0x5f, 0xd3, 0x36, 0x04, 0x39, 0x8b, 0x86, 0x0b, 0xf7, 0x74, 0x51, 0x07, 0x21, 0x20, 0x28, 0xe8, 0x47, 0xf2, 0x68, 0xc1, 0x8d, 0x41, 0xe9, 0x01, 0x8d, 0x28, 0xe5, 0xcf, 0x0e, 0x12, 0x39, 0x4e, 0xd0, 0x6d, 0x2f, 0x84, 0xa0, 0x8c, 0x50, 0xb1, 0xf5, 0xa9, 0x4a, 0x16, 0x16, 0x1a, 0x72, 0xbe, 0x72, 0xce, 0x44, 0x2e, 0x40, 0xdb, 0x68, 0xec, 0xac, 0xe6, 0x11, 0x91, 0xd7, 0xc2, 0x9d, 0xb8, 0x36, 0x42, 0xa3, 0x05, 0x65, 0x08, 0xb8, 0x51, 0x50, 0xe2, 0x98, 0x8c, 0x19, 0x3e, 0xbc, 0x34, 0xf4, 0xfc, 0x65, 0xcb, 0x33, 0xe7, 0x9b, 0x56, 0xad, 0xdf, 0xc3, 0x2d, 0x24, 0x1d, 0x5a, 0x53, 0xb1, 0x9d, 0xf5, 0x5a, 0x3d, 0x2d, 0xbe, 0xde, 0x98, 0x92, 0xaf, 0x1d, 0x65, 0x25, 0xae, 0xe9, 0x95, 0x55, 0x4e, 0xce, 0x91, 0x6d, 0x4c, 0xf8, 0xff, 0xda, 0x20, 0x22, 0xed, 0x0c, 0xab, 0xc4, 0x6a, 0xee, 0x5b, 0xa2, 0x7b, 0x08, 0xed, 0xa2, 0x8b, 0x46, 0x37, 0xb7, 0x11, 0x74, 0x4c, 0x52, 0x9a, 0xfd, 0x1e, 0xe6, 0x7c, 0xbc, 0xfb, 0x3f, 0x04, 0xb6, 0xed, 0xcc, 0x23, 0x4a, 0xad, 0x86, 0xe3, 0x4f, 0x49, 0x2a, 0x70, 0x04, 0x9d, 0x3f, 0x5e, 0x43, 0x90, 0xbd, 0x8d, 0x65, 0x23, 0x06, 0xf4, 0x46, 0x73, 0x4a, 0x84, 0xb5, 0x8b, 0x32, 0x21, 0xb3, 0xaa, 0x03, 0x44, 0x98, 0x55, 0xea, 0xc6, 0xea, 0x98, 0xb0, 0x96, 0xa7, 0x2e, 0xb8, 0x67, 0xbb, 0xee, 0xde, 0x59, 0xce, 0x82, 0x11, 0x74, 0x53, 0xa6, 0x14, 0x34, 0xe0, 0x88, 0xa7, 0xb6, 0xd2, 0x7c, 0x76, 0xa4, 0x3e, 0x57, 0x70, 0xa1, 0x94, 0xdb, 0x20, 0x06, 0xc3, 0x6a, 0xcb, 0x0b, 0xf2, 0x86, 0xb5, 0x35, 0xe1, 0x50, 0x72, 0x97, 0x1d, 0x0b, 0xb4, 0xbb, 0xee, 0x20, 0x6b, 0x53, 0x3b, 0x80, 0x77, 0x95, 0x53, 0x12, 0x60, 0xe8, 0xbe, 0xf8, 0x93, 0xd8, 0x7e, 0x24, 0x04, 0x69, 0x6d, 0xe6, 0xe4, 0xf3, 0x6a, 0x14, 0x58, 0x0a, 0x45, 0x04, 0x30, 0xd7, 0x97, 0x7d, 0x66, 0x76, 0xb0, 0xf4, 0x4a, 0x71, 0xa1, 0xd6, 0xa4, 0x73, 0x70, 0x86, 0xd0, 0x03, 0x40, 0x3d, 0x8c, 0x6b, 0x0b, 0xc4, 0xd5, 0xd4, 0x67, 0x7f, 0x2f, 0xf5, 0x0e, 0xa1, 0xa1, 0x2c, 0x02, 0x18, 0xa7, 0xce, 0xb5, 0xcf, 0x94, 0x86, 0xe4, 0x0f, 0x27, 0xbb, 0xdd, 0x9b, 0x19, 0x1a, 0x40, 0x5e, 0x57, 0x75, 0x8c, 0xd9, 0x62, 0xaa, 0xcb, 0xcf, 0xe9, 0x83, 0x02, 0x9c, 0x30, 0x5b, 0xfd, 0xa7, 0xd8, 0x8e, 0x08, 0x0c, 0x6a, 0x54, 0x94, 0x1b, 0x68, 0x7e, 0xf8, 0xce, 0xbd, 0x26, 0xa4, 0xff, 0xc9, 0xda, 0x5c, 0xeb, 0x93, 0xc6, 0x34, 0x12, 0x1c, 0x9d, 0xd5, 0xd5, 0x09, 0x5a, 0x4a, 0xe4, 0xcc, 0xe0, 0x5c, 0x1c, 0x8f, 0x7d, 0x7d, 0x77, 0x02, 0x12, 0x2d, 0xda, 0xf7, 0xa8, 0x1d, 0x44, 0x60, 0x48, 0xd6, 0x7c, 0xb0, 0x96, 0x8f, 0x73, 0xc8, 0xb2, 0xcf, 0x34, 0xf7, 0x1b, 0x84, 0x57, 0xed, 0x0e, 0x42, 0xc4, 0x2c, 0x93, 0x56, 0xd8, 0xfc, 0xdc, 0xe7, 0x1f, 0x30, 0x26, 0x7d, 0x8f, 0xf1, 0x45, 0xce, 0x63, 0xe8, 0xe2, 0x0c, 0x8a, 0x97, 0xc7, 0xdf, 0xb2, 0xfc, 0x5c, 0x63, 0x81, 0x9e, 0x2e, 0xcd, 0x28, 0xd4, 0x52, 0xdb, 0xf2, 0x0e, 0xaa, 0x23, 0x36, 0x60, 0xa5, 0xc6, 0x43, 0x37, 0xa8, 0xd4, 0xc4, 0x21, 0x85, 0xac, 0x5d, 0xa8, 0x59, 0x83, 0xc8, 0xec, 0x96, 0x3e, 0x4d, 0x0a, 0xf8, 0x0e, 0x27, 0x16, 0x36, 0x47, 0xc2, 0xe6, 0x8a, 0xef, 0xd0, 0x15, 0xa8, 0x03, 0xfc, 0x55, 0xc4, 0xa9, 0x10, 0xfd, 0x80, 0x76, 0x37, 0xb9, 0x3e, 0xbe, 0x5c, 0xe3, 0xde, 0xe1, 0x01, 0x63, 0x75, 0x64, 0x4c, 0x53, 0x38, 0x89, 0x33, 0x7c, 0xff, 0x63, 0xe5, 0x2b, 0xc1, 0xd5, 0xd5, 0x46, 0x1f, 0x00, 0xae, 0xf2, 0xbf, 0x25, 0x2a, 0x26, 0x10, 0x86, 0x62, 0x5d, 0xae, 0x30, 0xd3, 0xc3, 0x7c, 0x70, 0x22, 0x42, 0xde, 0xa5, 0xc1, 0xed, 0x58, 0x60, 0x0f, 0x39, 0x99, 0x38, 0x0a, 0x08, 0x70, 0x78, 0xbb, 0x2d, 0xb1, 0x81, 0xe8, 0xf5, 0x1e, 0xa1, 0x83, 0x6d, 0x02, 0x98, 0xcc, 0xb4, 0x34, 0xa4, 0x3d, 0xbf, 0x29, 0xe7, 0xf5, 0xbc, 0x4f, 0x10, 0x70, 0x66, 0xc9, 0x57, 0x8c, 0x18, 0x2e, 0xed, 0x3e, 0xc3, 0x09, 0x2a, 0x10, 0x71, 0x02, 0x9d, 0xfa, 0x68, 0xb7, 0x48, 0x32, 0x69, 0x62, 0xc8, 0x26, 0xf5, 0x09, 0x97, 0xa3, 0x5d, 0xfb, 0x4d, 0x39, 0xb6, 0x7d, 0x9a, 0x03, 0x3f, 0x65, 0x7b, 0xbc, 0x2c, 0x4c, 0x32, 0xa5, 0x26, 0x57, 0x37, 0x89, 0x44, 0xc9, 0xc3, 0x00, 0x04, 0x02, 0xa0, 0xff, 0x84, 0xf0, 0x71, 0x47, 0x27, 0x15, 0x6e, 0x71, 0xcd, 0x8a, 0xdd, 0xa1, 0xfd, 0x92, 0x2f, 0x7a, 0x3b, 0xbc, 0x27, 0xed, 0x4c, 0xd4, 0xb4, 0x22, 0x88, 0xca, 0x8b, 0xbd, 0x6f, 0xb7, 0xfa, 0xdf, 0x60, 0x90, 0xba, 0x83, 0x56, 0xe9, 0x34, 0x16, 0x30, 0x22, 0x7b, 0x53, 0xd0, 0xa1, 0x6c, 0xea, 0x4e, 0x22, 0x2c, 0x8d, 0xf0, 0x88, 0x18, 0x15, 0xbd, 0x76, 0x3c, 0x53, 0x9a, 0xb0, 0xaa, 0x05, 0xc7, 0xff, 0x39, 0x83, 0x12, 0xab, 0xeb, 0x51, 0x6e, 0x96, 0xbb, 0x99, 0x00, 0x95, 0xe1, 0xfd, 0xaa, 0x3b, 0x6b, 0x44, 0x77, 0xba, 0x9d, 0xce, 0x48, 0xe4, 0xb2, 0x8b, 0x32, 0xdd, 0x3b, 0x68, 0x11, 0x98, 0xf4, 0xec, 0x29, 0xcb, 0x86, 0xb9, 0x19, 0xd6, 0x8c, 0xdd, 0x78, 0xfb, 0xa7, 0x4d, 0x52, 0x2c, 0xa9, 0x79, 0x3c, 0xdd, 0xc3, 0x54, 0x40, 0x65, 0x0e, 0xf7, 0xf9, 0x6c, 0x13, 0x8e, 0xad, 0x93, 0x6f, 0x42, 0x3c, 0xd0, 0x86, 0xd0, 0xa3, 0x4f, 0x87, 0x1f, 0xdb, 0xe6, 0x38, 0xf4, 0xfc, 0xac, 0xa2, 0x3d, 0x50, 0xd4, 0x5e, 0x23, 0xe3, 0xe1, 0xd0, 0xab, 0x49, 0x90, 0x7f, 0x88, 0xb2, 0xba, 0x0d, 0x1c, 0xe6, 0x74, 0xc3, 0xaf, 0x44, 0x11, 0xd4, 0xc2, 0xac, 0xc7, 0x5a, 0x73, 0xf1, 0x15, 0x90, 0x6d, 0xfe, 0xa5, 0x0e, 0x3e, 0xdb, 0xb1, 0xe7, 0x65, 0x4a, 0x9e, 0x77, 0x88, 0xcc, 0xb0, 0x3c, 0x5d, 0x8b, 0xbe, 0xb9, 0xbe, 0x79, 0x0d, 0x18, 0x09, 0x4e, 0x4c, 0xfb, 0x94, 0xd1, 0x11, 0x16, 0x04, 0x73, 0x45, 0x2c, 0xeb, 0xa1, 0xa5, 0xdc, 0x6d, 0x3e, 0x0e, 0x1f, 0x80, 0x9f, 0xc8, 0x59, 0xe3, 0x63, 0x03, 0x46, 0xb8, 0x9a, 0x94, 0xee, 0xc8, 0x62, 0x23, 0x8d, 0xb3, 0x5e, 0xdb, 0x4b, 0xb2, 0x48, 0xca, 0xe6, 0x9c, 0x1e, 0x45, 0x8b, 0x94, 0xf3, 0xf8, 0x71, 0xc1, 0x1f, 0xcd, 0x7f, 0xa1, 0xa0, 0x42, 0xb8, 0x6a, 0xcb, 0x76, 0x32, 0x4e, 0x3a, 0x06, 0x83, 0x8d, 0xe9, 0x5b, 0xe3, 0x6d, 0xf0, 0x9d, 0x10, 0x4a, 0xf1, 0x52, 0x09, 0xc4, 0x78, 0x96, 0x19, 0x8d, 0x52, 0xae, 0x42, 0xa6, 0x7e, 0xb2, 0x2d, 0x5b, 0x84, 0x3b, 0xc7, 0x4d, 0x16, 0x15, 0x92, 0xfd, 0xb2, 0x6a, 0x5a, 0x40, 0xe6, 0x2c, 0x88, 0xcb, 0xb5, 0x21, 0xa1, 0x86, 0x4b, 0xef, 0x52, 0xd8, 0x25, 0x67, 0x0b, 0x62, 0xf0, 0x2c, 0xe4, 0xab, 0xb7, 0x9b, 0x0b, 0x7a, 0x6e, 0x97, 0x60, 0xbd, 0x78, 0xde, 0x5b, 0x23, 0x80, 0x4b, 0x8f, 0xbc, 0x97, 0x08, 0x9e, 0x19, 0xf5, 0x03, 0x25, 0x37, 0x3b, 0x4f, 0xd0, 0x6b, 0x74, 0x62, 0x8a, 0x19, 0x1e, 0x5c, 0x00, 0xf0, 0xfa, 0x55, 0x99, 0xd5, 0x21, 0xd6, 0x1d, 0x95, 0xa7, 0xea, 0x7b, 0x6f, 0x29, 0xf5, 0x57, 0xc1, 0xd3, 0x1c, 0x14, 0x98, 0x38, 0xe4, 0x1f, 0xad, 0x41, 0xf0, 0xdf, 0x5a, 0x50, 0x31, 0xfe, 0x8e, 0xca, 0xae, 0x5c, 0x62, 0x64, 0xd9, 0xe1, 0x77, 0x9b, 0xb7, 0xf3, 0x66, 0x00, 0x53, 0x37, 0x3a, 0x11, 0x55, 0xdb, 0xf8, 0x2b, 0x2c, 0xaa, 0xb0, 0xab, 0xd4, 0x07, 0x44, 0x65, 0x7a, 0x95, 0x41, 0xf7, 0x31, 0xb0, 0x9e, 0xd7, 0x06, 0x0a, 0x08, 0x78, 0x7c, 0x69, 0xc0, 0xf3, 0xa9, 0x2b, 0x32, 0x26, 0x68, 0xde, 0x5a, 0x4c, 0x45, 0x12, 0x08, 0xed, 0xb6, 0x5b, 0xc7, 0x21, 0x23, 0x8e, 0xf6, 0xcc, 0x5a, 0x0f, 0x50, 0x7e, 0x92, 0x17, 0xcc, 0x1a, 0x2c, 0xb9, 0xa4, 0x7a, 0xf8, 0x6d, 0x04, 0x17, 0xf6, 0xe2, 0xd6, 0x22, 0x4f, 0x05, 0x5c, 0xf5, 0xe7, 0xb6, 0x1f, 0x5f, 0xe3, 0x46, 0x24, 0x6a, 0xe0, 0xf1, 0xcb, 0x99, 0x01, 0x94, 0x0a, 0xb8, 0x0c, 0xf1, 0x5d, 0x77, 0xab, 0x19, 0xd7, 0x31, 0x7d, 0xc2, 0x9c, 0xd2, 0x22, 0xbd, 0x04, 0xde, 0x57, 0xb5, 0x4c, 0xe3, 0x34, 0x18, 0x01, 0x22, 0x62, 0xc6, 0x09, 0xbb, 0x98, 0x85, 0x51, 0x14, 0x37, 0xd8, 0xef, 0x70, 0xa9, 0x5b, 0xf8, 0x7c, 0xe6, 0xcf, 0xb3, 0x7b, 0x9e, 0xeb, 0xdd, 0xee, 0x9e, 0xcd, 0x8e, 0xad, 0x2b, 0x48, 0x81, 0x9b, 0x85, 0x39, 0x49, 0xbd, 0x67, 0x08, 0xe1, 0xba, 0x6c, 0x40, 0x0e, 0x89, 0x29, 0xd0, 0x4e, 0x59, 0x7c, 0x37, 0x65, 0xf9, 0xcf, 0xac, 0x90, 0x99, 0x31, 0x18, 0x06, 0xe4, 0xee, 0x82, 0xb3, 0x74, 0x31, 0x3e, 0xa6, 0x9b, 0x81, 0xf6, 0xbf, 0x1a, 0x81, 0x8b, 0xad, 0x5c, 0xda, 0xd0, 0xeb, 0x1d, 0x7e, 0x9a, 0x93, 0xff, 0x7d, 0x34, 0xc9, 0x08, 0x74, 0x69, 0xe3, 0x1a, 0xd8, 0x6f, 0xe4, 0x39, 0xc0, 0x28, 0x1a, 0x82, 0xf9, 0xe6, 0xf8, 0x60, 0x6a, 0x3a, 0xcf, 0xa7, 0xca, 0x0d, 0x5b, 0x8b, 0xe9, 0x08, 0xd5, 0xd4, 0x24, 0xeb, 0x40, 0x83, 0x78, 0xf2, 0x14, 0x63, 0xda, 0xfa, 0xa5, 0xa6, 0x3f, 0x34, 0x82, 0xda, 0xb3, 0x62, 0x24, 0xd9, 0xd5, 0x35, 0xc7, 0x41, 0x61, 0x37, 0xa2, 0xc6, 0x7f, 0x66, 0x9c, 0xc0, 0x31, 0x2a, 0xd3, 0xcf, 0x6e, 0x8d, 0x74, 0xa2, 0x01, 0xa5, 0xd2, 0xa1, 0x64, 0xc1, 0x43, 0x2a, 0x41, 0xc0, 0xd1, 0x88, 0xea, 0x6e, 0x28, 0x62, 0xdf, 0xdc, 0x35, 0x5e, 0x48, 0x04, 0x7e, 0x91, 0x9d, 0x16, 0xc3, 0x7c, 0xf3, 0x56, 0x2d, 0x86, 0xfb, 0xcc, 0x49, 0x7b, 0xf3, 0xfe, 0xb0, 0xa0, 0x29, 0xed, 0x34, 0x42, 0xc3, 0xc7, 0x6c, 0x0d, 0x6e, 0x32, 0x8b, 0x2c, 0x1f, 0x40, 0x59, 0xb7, 0x63, 0x13, 0x46, 0x2f, 0x4b, 0x0d, 0xda, 0x28, 0xec, 0xa9, 0xcb, 0x36, 0xfd, 0x08, 0x82, 0x60, 0xe9, 0xc9, 0x15, 0x30, 0xb8, 0xb5, 0x87, 0xf8, 0x83, 0x4b, 0xab, 0x10, 0xb6, 0x61, 0xdf, 0x29, 0xef, 0xc4, 0x6c, 0x24, 0x18, 0x54, 0x6e, 0x6c, 0x9c, 0xd6, 0x9f, 0x05, 0xea, 0x26, 0x3d, 0x0c, 0xf5, 0x2b, 0x24, 0xc6, 0x1d, 0x43, 0x47, 0xc3, 0x60, 0x00, 0x73, 0xc7, 0x6f, 0x47, 0xb5, 0x8e, 0xd1, 0x49, 0x1e, 0x8a, 0xec, 0x4f, 0x1b, 0xc0, 0xc0, 0xf3, 0x83, 0x89, 0x4d, 0xa3, 0x57, 0x14, 0x39, 0xb8, 0x9b, 0x94, 0x42, 0x54, 0x53, 0xd2, 0x1c, 0xa7, 0x8b, 0x70, 0x73, 0xc0, 0x33, 0x90, 0xb1, 0x94, 0xc3, 0x4b, 0xdd, 0x2d, 0x60, 0x0b, 0x6d, 0xac, 0xc2, 0x11, 0x1c, 0xe8, 0xf6, 0xa4, 0x69, 0xbd, 0x4f, 0x26, 0xaf, 0x91, 0x87, 0x56, 0xb0, 0x45, 0xfb, 0x83, 0xe6, 0x88, 0x4a, 0x0f, 0xb6, 0xfb, 0x73, 0x92, 0xba, 0x4a, 0x06, 0x35, 0xf2, 0xea, 0x7b, 0x81, 0x85, 0x14, 0x29, 0xbc, 0x9a, 0x1e, 0x55, 0x70, 0x8a, 0x3b, 0xaf, 0xa6, 0x10, 0xfd, 0x48, 0xc6, 0x39, 0xaf, 0xeb, 0xa8, 0xff, 0x41, 0x72, 0x8c, 0x94, 0x15, 0x6c, 0x34, 0x8d, 0xb2, 0xa7, 0xd4, 0x42, 0x73, 0x47, 0x83, 0xb1, 0x9d, 0x00, 0xcc, 0x27, 0xfa, 0xd9, 0xe5, 0x17, 0x88, 0x57, 0x95, 0xa9, 0xb6, 0xc2, 0xf9, 0x13, 0xd6, 0x55, 0xbf, 0x8b, 0x91, 0x6d, 0xe1, 0x68, 0x3c, 0x72, 0xae, 0x27, 0x54, 0xe1, 0x9d, 0x92, 0x5b, 0xd0, 0x21, 0x3e, 0x4f, 0xf3, 0x18, 0xeb, 0xa4, 0x95, 0xa6, 0xe0, 0x0c, 0x8f, 0x0a, 0x7d, 0x46, 0x45, 0xb9, 0x7f, 0xd7, 0xa7, 0xd6, 0x84, 0x47, 0x04, 0xc1, 0x56, 0xbb, 0xd3, 0xc5, 0x55, 0x4c, 0x73, 0x32, 0x90, 0xa3, 0x94, 0xaa, 0xe6, 0xf1, 0x0f, 0x7e, 0xbd, 0xfc, 0x6a, 0x3f, 0x54, 0x26, 0xe8, 0xb4, 0x9e, 0xaa, 0x39, 0x0a, 0x0f, 0x60, 0x4f, 0x2f, 0xa8, 0x6f, 0xdd, 0xd1, 0xbd, 0x97, 0x75, 0x1d, 0x28, 0xbc, 0xe5, 0x12, 0xe2, 0x33, 0xfc, 0xa1, 0xb4, 0x38, 0x02, 0x17, 0x76, 0x50, 0x85, 0xcf, 0x27, 0xac, 0x2e, 0x89, 0x9a, 0xe2, 0x40, 0x49, 0xc2, 0x7b, 0x35, 0x73, 0x4e, 0x09, 0xf2, 0xfc, 0x94, 0x02, 0x03, 0x1c, 0xe8, 0x61, 0x26, 0x3d, 0xb0, 0xc7, 0x1d, 0x9c, 0x10, 0x5a, 0x33, 0x43, 0x90, 0x1a, 0xd9, 0x09, 0xac, 0x37, 0x52, 0x63, 0x1b, 0xf6, 0xd0, 0xfe, 0xda, 0x53, 0x78, 0x4c, 0xf4, 0x91, 0xc7, 0x10, 0xa1, 0x07, 0xe1, 0x20, 0x63, 0xc8, 0x75, 0xe1, 0x55, 0xb1, 0x2a, 0x3a, 0x66, 0xea, 0x09, 0xcf, 0x3d, 0xe6, 0x1c, 0x67, 0x58, 0x5b, 0x12, 0x20, 0x0d, 0x60, 0xdf, 0x90, 0xcd, 0x65, 0x4e, 0x79, 0x47, 0x07, 0xa6, 0xe8, 0xc2, 0xdc, 0x3c, 0x74, 0x83, 0x04, 0x26, 0xf6, 0x65, 0xa2, 0x0c, 0xfc, 0xc0, 0xcb, 0x3f, 0x02, 0x7d, 0xb1, 0x21, 0x05, 0xc1, 0x77, 0x6b, 0xd9, 0xa0, 0x37, 0x3c, 0x2d, 0xc6, 0x73, 0xdd, 0x71, 0x5c, 0xc7, 0x06, 0xc4, 0x53, 0xfc, 0xf0, 0x33, 0x36, 0xab, 0xe2, 0x5f, 0x24, 0x11, 0xeb, 0x5d, 0x8e, 0x8a, 0xb4, 0xb3, 0x72, 0x6b, 0xfa, 0xe2, 0xef, 0x16, 0x63, 0xd8, 0x32, 0x14, 0x34, 0x01, 0xa4, 0x24, 0xd2, 0x29, 0x68, 0xff, 0x5f, 0x9f, 0x89, 0x99, 0xc6, 0x5f, 0x78, 0x29, 0xdb, 0xf9, 0x8f, 0xf5, 0x6d, 0x06, 0x12, 0xc7, 0x42, 0xd5, 0x81, 0x2d, 0x7e, 0x52, 0xf0, 0x47, 0x65, 0x61, 0xfd, 0x9b, 0xb4, 0x5f, 0xe8, 0xfb, 0xdf, 0x91, 0x9c, 0x52, 0x6f, 0x5a, 0xea, 0x0d, 0xd3, 0x79, 0x99, 0x14, 0xc5, 0x87, 0x9f, 0xe5, 0x65, 0xbb, 0x6b, 0x14, 0x90, 0xdb, 0xd5, 0xcd, 0x75, 0x76, 0x28, 0xeb, 0xab, 0x52, 0x5d, 0xde, 0xfa, 0xa0, 0xce, 0xc4, 0x6d, 0xeb, 0xe0, 0xc4, 0xb0, 0x39, 0xb0, 0x66, 0x75, 0x4a, 0x1f, 0xb3, 0x00, 0x31, 0x9a, 0xe6, 0x7a, 0x6a, 0xb7, 0x96, 0x2a, 0x4d, 0x11, 0x74, 0xd4, 0x84, 0x1c, 0x29, 0x50, 0xed, 0x05, 0x9c, 0xbe, 0xdf, 0xc8, 0x93, 0xc1, 0xa9, 0x76, 0x81, 0xf3, 0xd0, 0xed, 0x32, 0xa7, 0x39, 0x92, 0x8b, 0xf7, 0x4e, 0xb9, 0x61, 0x06, 0x74, 0x99, 0x38, 0xa3, 0x12, 0x24, 0x80, 0x3e, 0x4b, 0xbc, 0xd6, 0x93, 0x1d, 0x7e, 0x58, 0xa0, 0xff, 0xb2, 0x11, 0x51, 0xd8, 0x7d, 0xd0, 0xf8, 0x62, 0xf1, 0x97, 0x00, 0x85, 0x1e, 0x9b, 0x48, 0x2e, 0x18, 0x67, 0x56, 0x80, 0xfc, 0xb8, 0x94, 0x88, 0x95, 0x3b, 0x1d, 0xcb, 0x13, 0xcc, 0x4a, 0xff, 0x69, 0x0f, 0x7a, 0x38, 0xab, 0x09, 0xdb, 0x20, 0x9d, 0x4e, 0xd2, 0x57, 0x96, 0x82, 0x85, 0xae, 0x4d, 0xba, 0x56, 0xd8, 0xdf, 0x3b, 0x09, 0x03, 0x12, 0xcd, 0xea, 0xcb, 0x46, 0x7c, 0x2e, 0xaf, 0xd8, 0x42, 0x22, 0xfe, 0xad, 0x04, 0xb0, 0x8b, 0xec, 0x89, 0x67, 0xb4, 0x11, 0x07, 0xdb, 0x7f, 0xc9, 0x1d, 0x46, 0x22, 0x00, 0xc6, 0x38, 0xbb, 0x71, 0x03, 0xf3, 0xf4, 0xb4, 0x55, 0xb1, 0x1e, 0x34, 0x2d, 0x5c, 0x42, 0xdf, 0x8a, 0xcd, 0x57, 0x3c, 0xb8, 0x1e, 0xa5, 0x9e, 0xee, 0x4d, 0x2d, 0x6b, 0x30, 0x68, 0xd7, 0x83, 0x0d, 0x85, 0xf8, 0x80, 0x5d, 0x52, 0x28, 0x95, 0x25, 0x3e, 0x06, 0x96, 0x8c, 0xef, 0x61, 0xa0, 0x14, 0xce, 0xe5, 0xd7, 0x2f, 0x59, 0x3e, 0x83, 0xd1, 0x85, 0xf5, 0xbf, 0x97, 0x5a, 0xf2, 0xd5, 0x8d, 0xb3, 0x61, 0xf9, 0x1e, 0xa3, 0x9d, 0x7e, 0x13, 0x51, 0x00, 0x2a, 0x25, 0xde, 0xc1, 0xb6, 0xb4, 0x39, 0xa3, 0x1d, 0x50, 0x79, 0xff, 0x1c, 0x2c, 0x6b, 0xd4, 0xe4, 0xb0, 0x29, 0xca, 0xeb, 0xf0, 0xf2, 0xa0, 0x52, 0x63, 0x75, 0x33, 0x18, 0xe7, 0x8f, 0x44, 0x31, 0xf4, 0x8f, 0x47, 0x48, 0xb4, 0x8a, 0xcd, 0x0f, 0x5c, 0xac, 0x6e, 0xad, 0xfc, 0xbf, 0xf1, 0x4f, 0x01, 0xd4, 0x2e, 0xa4, 0x78, 0xcf, 0x3f, 0x12, 0x71, 0x9a, 0xa6, 0xe2, 0xf3, 0x2b, 0x8d, 0x7b, 0xf9, 0x30, 0x27, 0xc3, 0xe6, 0x5d, 0x9c, 0x1a, 0x86, 0x39, 0x41, 0xf0, 0xec, 0xcd, 0xbf, 0xb8, 0x77, 0x73, 0x73, 0x16, 0xe2, 0xf3, 0x93, 0xa5, 0x87, 0x3d, 0xb4, 0x36, 0x50, 0x7a, 0xe5, 0x1a, 0x95, 0x5c, 0x68, 0x59, 0xa4, 0x5a, 0x29, 0x3c, 0xc9, 0xec, 0x74, 0x97, 0xa2, 0x2c, 0xd6, 0x97, 0xa6, 0x17, 0x76, 0x45, 0x36, 0x6a, 0x83, 0x1f, 0xf5, 0x21, 0x91, 0x91, 0xdb, 0x04, 0xd1, 0xb4, 0x6b, 0x2a, 0xfc, 0x83, 0xfe, 0x27, 0x38, 0xb8, 0x5a, 0xa8, 0x01, 0x4c, 0x79, 0xd1, 0xf0, 0x3e, 0xbf, 0xc5, 0xa3, 0x18, 0x99, 0x0a, 0xad, 0x48, 0x24, 0x09, 0x72, 0x46, 0xe2, 0xbd, 0xbd, 0x7e, 0xcb, 0x89, 0xf0, 0x12, 0x30, 0xa9, 0xf9, 0x4e, 0x16, 0xab, 0xc3, 0x6a, 0x27, 0xf8, 0x3d, 0x44, 0x0d, 0x0a, 0x6b, 0xad, 0xac, 0x33, 0x31, 0x37, 0xd8, 0x45, 0x6e, 0x5b, 0xd9, 0x42, 0x49, 0x69, 0xe6, 0x6d, 0xef, 0x65, 0x84, 0x10, 0x17, 0x3f, 0x9a, 0xd4, 0xbc, 0xf8, 0x48, 0xd4, 0x5e, 0xac, 0x8e, 0x0d, 0x53, 0x5d, 0xae, 0x85, 0xce, 0x6f, 0x31, 0x1b, 0xdc, 0xba, 0xc1, 0xca, 0xe5, 0xa5, 0x5a, 0x2a, 0x0d, 0x28, 0x5f, 0x18, 0xdf, 0x39, 0xde, 0x35, 0xaa, 0x81, 0x8b, 0xea, 0x40, 0xbe, 0x27, 0x9f, 0xea, 0xd1, 0x22, 0x63, 0x72, 0xe4, 0x03, 0x5b, 0x6c, 0xba, 0xbc, 0x86, 0x53, 0x04, 0x5c, 0x48, 0xac, 0x44, 0xc7, 0x9f, 0x7b, 0xb1, 0xce, 0x05, 0x65, 0x0d, 0x58, 0xf2, 0x23, 0x92, 0xa5, 0x47, 0x32, 0x4a, 0x90, 0x1f, 0xf7, 0x1b, 0x68, 0x71, 0x68, 0xc4, 0xc0, 0xeb, 0x11, 0xa3, 0x02, 0x91, 0xe5, 0xcd, 0xd3, 0x26, 0xb8, 0x4a, 0x38, 0x3c, 0x89, 0x4d, 0x50, 0xf6, 0x6c, 0xd9, 0xca, 0xee, 0xbb, 0x5d, 0xad, 0x88, 0x3a, 0x50, 0x41, 0xa1, 0xe3, 0x12, 0x77, 0xcc, 0xa4, 0x05, 0x48, 0x47, 0xa8, 0xc0, 0x7e, 0x80, 0xf6, 0x14, 0x1c, 0x08, 0x9a, 0xe0, 0xc4, 0x63, 0x89, 0x14, 0xe0, 0x39, 0xe8, 0x91, 0x18, 0xb9, 0x3d, 0xfd, 0x7c, 0x70, 0xa4, 0xda, 0xcd, 0x57, 0xa2, 0x33, 0x02, 0x69, 0x0e, 0x81, 0xe7, 0x47, 0x3a, 0xa9, 0xdc, 0x72, 0x5d, 0x97, 0x1a, 0x23, 0xca, 0x8c, 0xb9, 0xe4, 0xa4, 0x4f, 0x7b, 0x0c, 0x7f, 0xbe, 0xf8, 0xfb, 0x0f, 0x91, 0x89, 0x89, 0xbd, 0x54, 0xc9, 0x2b, 0xb0, 0x97, 0xe9, 0x7a, 0x01, 0xa2, 0xe2, 0xbe, 0x59, 0x2f, 0x8c, 0x13, 0x86, 0x20, 0x2d, 0xcd, 0x6e, 0x80, 0x95, 0x05, 0x03, 0x45, 0xa7, 0x3e, 0x07, 0x9a, 0x68, 0x82, 0x71, 0xf4, 0xa7, 0xc8, 0x54, 0x18, 0xdc, 0xba, 0x78, 0x95, 0x73, 0x6a, 0x1c, 0xc9, 0x0f, 0x56, 0x09, 0xaf, 0x8e, 0x65, 0x1f, 0xb5, 0x51, 0xa2, 0x14, 0xbd, 0x40, 0x2e, 0x3c, 0x98, 0xd7, 0xdc, 0xd9, 0x46, 0x16, 0xa8, 0xee, 0xb6, 0x7f, 0x1a, 0xe0, 0x25, 0x40, 0x6b, 0x8e, 0x66, 0xcb, 0x0b, 0x80, 0x12, 0x2d, 0xd7, 0xaf, 0x5d, 0xf4, 0xe1, 0xca, 0x34, 0xa0, 0xaf, 0xc3, 0x53, 0x31, 0x4b, 0xb7, 0x86, 0x22, 0x7a, 0x0a, 0xde, 0xf0, 0xbb, 0x72, 0x16, 0xdd, 0x19, 0xc1, 0xa8, 0xf7, 0x0c, 0x06, 0x0c, 0x6b, 0xbd, 0x2c, 0xd7, 0x85, 0xe7, 0x11, 0x63, 0xc3, 0xe8, 0x3b, 0x65, 0x62, 0xa4, 0xdd, 0x49, 0xea, 0x70, 0xd3, 0x24, 0xc8, 0x6d, 0x60, 0x56, 0x96, 0x97, 0xea, 0xbe, 0xd5, 0x44, 0x04, 0x4f, 0x75, 0x62, 0x8c, 0x27, 0xb4, 0x65, 0xf4, 0xe3, 0x37, 0xba, 0x22, 0xf9, 0xa2, 0xd7, 0x55, 0x56, 0xed, 0x1b, 0x8d, 0x63, 0xc9, 0x75, 0x4b, 0x7d, 0xb9, 0xbb, 0x01, 0x51, 0xd5, 0x8e, 0x19, 0xee, 0x67, 0xa2, 0x53, 0xe3, 0x62, 0xc6, 0xc5, 0x21, 0x75, 0x04, 0xd7, 0x3b, 0x21, 0xf1, 0x16, 0x9f, 0x2f, 0x9a, 0x3f, 0x74, 0xc9, 0x07, 0x54, 0x08, 0xc6, 0xdd, 0x76, 0x6c, 0x37, 0xe1, 0xb6, 0xf0, 0x47, 0x3a, 0xb7, 0xf6, 0xe9, 0xd9, 0xb5, 0x22, 0xeb, 0xdc, 0xbf, 0x4c, 0x29, 0x64, 0x13, 0x7e, 0xe7, 0x82, 0x91, 0xb7, 0x06, 0xe4, 0x96, 0xf4, 0x39, 0xee, 0x79, 0x29, 0x45, 0xd5, 0xb4, 0xd3, 0x45, 0xe9, 0x58, 0xf6, 0x8c, 0x7a, 0x7e, 0xf4, 0xf5, 0xe3, 0x02, 0x28, 0x52, 0xce, 0x67, 0x90, 0x97, 0x16, 0xc6, 0x30, 0xfa, 0x70, 0xf0, 0x3a, 0xe5, 0x25, 0xd3, 0xb7, 0xa5, 0xe3, 0x2c, 0xf9, 0xb8, 0xa1, 0x48, 0x85, 0x06, 0x7c, 0x20, 0x58, 0x02, 0x10, 0x84, 0xfe, 0xed, 0x9b, 0x41, 0x47, 0xfb, 0x23, 0x9a, 0x61, 0x65, 0x6f, 0xa8, 0x9a, 0x7d, 0x90, 0x33, 0xfa, 0x81, 0xae, 0x5d, 0x5c, 0x4f, 0x2e, 0xaa, 0x96, 0xdb, 0x17, 0xbd, 0x0a, 0x55, 0x2e, 0x7f, 0x9b, 0xc9, 0x19, 0x34, 0x90, 0x74, 0xef, 0xeb, 0x8d, 0x23, 0x10, 0xb3, 0xab, 0x34, 0x44, 0x32, 0xf8, 0x72, 0x88, 0x77, 0xff, 0xb3, 0xd2, 0x2a, 0x0d, 0x51, 0xae, 0x5f, 0x8e, 0xcb, 0x48, 0x6c, 0x0d, 0xd9, 0x33, 0x75, 0x1f, 0x96, 0x2b, 0xfa, 0xb4, 0x40, 0xc4, 0x88, 0x9b, 0x26, 0xe1, 0xef, 0xed, 0x05, 0xce, 0x88, 0x9a, 0x2c, 0x2e, 0x64, 0x3c, 0xfc, 0x24, 0x98, 0x55, 0xe5, 0x71, 0xb3, 0xa9, 0xb6, 0x4a, 0xd1, 0xde, 0x1b, 0x61, 0xf3, 0xab, 0x50, 0x61, 0xff, 0xf1, 0x93, 0x80, 0x37, 0x49, 0x5f, 0x97, 0x17, 0x0e, 0xc7, 0x57, 0x95, 0xa7, 0xa6, 0x3b, 0x6f, 0x76, 0x25, 0x50, 0xff, 0x5c, 0x9b, 0x2e, 0xf9, 0xd2, 0x3e, 0x3f, 0x1e, 0x0a, 0xa3, 0x61, 0x52, 0x4f, 0xff, 0xc3, 0xc2, 0x4c, 0x26, 0x31, 0x98, 0x85, 0x63, 0x17, 0xe3, 0x08, 0x33, 0x0d, 0x9c, 0xa9, 0xc9, 0xaa, 0x7e, 0x88, 0x68, 0x4b, 0xbf, 0x0f, 0xae, 0x06, 0x83, 0x62, 0x73, 0x35, 0x8e, 0x9c, 0x98, 0x50, 0x55, 0xfd, 0x86, 0x6d, 0x4c, 0x3c, 0x42, 0xc9, 0xc1, 0x9d, 0x71, 0x5f, 0xdd, 0xe4, 0xd5, 0x65, 0xae, 0x8c, 0xd1, 0x3d, 0x2e, 0x56, 0x7d, 0xc8, 0xf5, 0x11, 0xda, 0x17, 0x2f, 0x58, 0x42, 0xbf, 0x80, 0x8f, 0xd5, 0xe3, 0x20, 0x47, 0x26, 0x9f, 0xcd, 0xfe, 0xc9, 0x7a, 0x58, 0x93, 0xfc, 0xac, 0xfd, 0x05, 0x1b, 0xb7, 0x85, 0x3d, 0x56, 0xb3, 0xb9, 0x0b, 0x0c, 0x56, 0xde, 0x93, 0xa1, 0x32, 0xf9, 0x46, 0x1f, 0x1c, 0xaa, 0x5b, 0xc9, 0x2b, 0x9c, 0xe8, 0x82, 0x17, 0x9b, 0x09, 0x49, 0x80, 0xc5, 0x91, 0x04, 0x45, 0xf2, 0x67, 0x17, 0xb6, 0x99, 0xce, 0xe1, 0x39, 0x29, 0x12, 0x60, 0x5a, 0x4a, 0xad, 0x35, 0xb0, 0x70, 0x7d, 0x77, 0x43, 0x40, 0xf2, 0xc5, 0xb6, 0x18, 0x93, 0x87, 0x5b, 0x7f, 0x04, 0xca, 0x9e, 0xfd, 0x32, 0x63, 0x7f, 0x81, 0xcf, 0x23, 0x27, 0x3f, 0xac, 0xaa, 0x28, 0x87, 0xda, 0xa4, 0x66, 0xf9, 0xc8, 0x17, 0x03, 0x79, 0x23, 0xd1, 0x68, 0x8b, 0x8e, 0xd1, 0x0a, 0x4f, 0x8e, 0xf1, 0x9e, 0xc0, 0x44, 0xcc, 0xb2, 0xac, 0x88, 0x6a, 0x01, 0xf8, 0x24, 0xa0, 0x60, 0x8b, 0x85, 0x9c, 0xae, 0xda, 0x37, 0xe7, 0x6e, 0x6e, 0xc8, 0xc4, 0xa7, 0x39, 0x5c, 0x4e, 0x20, 0x26, 0x32, 0xfa, 0x70, 0xef, 0xb4, 0xfe, 0x5c, 0x28, 0x1c, 0xb6, 0xdd, 0xc2, 0xea, 0x57, 0x07, 0x1c, 0x0a, 0xd3, 0xc1, 0x8b, 0x72, 0x00, 0x61, 0x28, 0xfc, 0xbb, 0x99, 0x36, 0x14, 0x16, 0x76, 0x28, 0xae, 0x92, 0xd5, 0x6d, 0x27, 0xc7, 0xa3, 0xc6, 0x53, 0x08, 0xaf, 0xee, 0xf7, 0x33, 0x39, 0xb8, 0xcf, 0x6b, 0x73, 0xe4, 0x22, 0x03, 0x76, 0x94, 0x8b, 0x45, 0x2c, 0x7c, 0xaa, 0x3e, 0x67, 0x26, 0xbf, 0xf3, 0xc5, 0x4d, 0x85, 0x37, 0xd2, 0x24, 0xf3, 0x5b, 0xde, 0xa1, 0x77, 0x69, 0xce, 0xd7, 0xc6, 0x87, 0x69, 0x1f, 0xe1, 0x53, 0xed, 0xbe, 0x38, 0x3e, 0xea, 0xbe, 0x9f, 0x81, 0x2c, 0xf4, 0xd2, 0xeb, 0xaf, 0xa5, 0xb1, 0x7a, 0x5e, 0xcd, 0xf9, 0x88, 0x81, 0x0f, 0x6b, 0x14, 0x9f, 0xd4, 0x02, 0xc4, 0x56, 0xd2, 0xfb, 0x0b, 0xe0, 0x17, 0xa2, 0x18, 0xdb, 0xd7, 0x0b, 0x4d, 0x49, 0x3a, 0x30, 0x8d, 0xe9, 0x6c, 0x11, 0x07, 0x44, 0x51, 0x8d, 0xdf, 0xd0, 0xb5, 0x10, 0x1c, 0xe3, 0xd7, 0x73, 0x15, 0xbc, 0x84, 0xf8, 0xfa, 0xba, 0x46, 0x3b, 0x60, 0xaf, 0xe4, 0x1c, 0x08, 0x5f, 0xe0, 0x7d, 0xb9, 0x10, 0x1b, 0x34, 0xb0, 0x31, 0x75, 0x72, 0xeb, 0xc1, 0x1d, 0xd9, 0xd0, 0xdb, 0x0e, 0x57, 0x05, 0x71, 0x0d, 0xbb, 0x19, 0xf6, 0xfe, 0x86, 0x44, 0x18, 0x4e, 0xd4, 0xdf, 0x76, 0xa1, 0x94, 0xcd, 0x0f, 0x3e, 0x43, 0xd9, 0xd5, 0x60, 0x3f, 0x84, 0xc0, 0x7c, 0x48, 0x17, 0xea, 0x2a, 0xab, 0xb3, 0x94, 0xd4, 0x19, 0x80, 0x1f, 0xdf, 0xaa, 0x40, 0xf0, 0x4d, 0xf8, 0x38, 0xb6, 0x91, 0x50, 0x08, 0x69, 0xec, 0x7e, 0x09, 0x84, 0xe2, 0xa0, 0x4a, 0x62, 0x8a, 0x1d, 0x01, 0xdf, 0x3b, 0xb4, 0x03, 0x9f, 0x53, 0xf5, 0xd3, 0x10, 0xb5, 0x42, 0xec }; gint * chafa_gen_noise_matrix (gfloat magnitude) { gint *matrix; gint i; matrix = g_malloc (CHAFA_NOISE_TEXTURE_ARRAY_LEN * sizeof (gint)); for (i = 0; i < CHAFA_NOISE_TEXTURE_ARRAY_LEN; i++) { matrix [i] = ((gfloat) blue_noise_src [i] - 128.0f) * magnitude + 0.5f; } return matrix; } chafa-1.18.2/chafa/internal/chafa-noise.h000066400000000000000000000024001517447374300200640ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_NOISE_H__ #define __CHAFA_NOISE_H__ G_BEGIN_DECLS #define CHAFA_NOISE_TEXTURE_DIM 64 #define CHAFA_NOISE_TEXTURE_N_CHANNELS 3 #define CHAFA_NOISE_TEXTURE_N_PIXELS (CHAFA_NOISE_TEXTURE_DIM * CHAFA_NOISE_TEXTURE_DIM) #define CHAFA_NOISE_TEXTURE_ARRAY_LEN (CHAFA_NOISE_TEXTURE_N_PIXELS * CHAFA_NOISE_TEXTURE_N_CHANNELS) gint *chafa_gen_noise_matrix (gfloat magnitude); G_END_DECLS #endif /* __CHAFA_NOISE_H__ */ chafa-1.18.2/chafa/internal/chafa-palette.c000066400000000000000000001022351517447374300204070ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* abs */ #include /* memcpy, memset */ #include /* pow, cbrt, log, sqrt, atan2, cos, sin */ #include "chafa.h" #include "internal/chafa-private.h" #define DEBUG(x) /* ------------------------ * * Quality level parameters * * ------------------------ */ typedef struct { gfloat min_quality; gint algorithm; /* Currently unused */ /* Number of samples to extract from the input. Samples are evenly * distributed across the image. This value is advisory -- we may extract * slightly more or fewer. If the samples are close together (small step * size), or too many samples are below the alpha threshold, we revert * to 1:1 population sampling. */ gint n_samples; /* Number of high-order bits to grab from each color channel when * populating the initial bins. This determines the number of bins: * * n_bins = 2^(bits_per_ch * 3) * * In order to limit cache pollution, we use u16 to store bin indexes, * limiting us to 65536 bins. The upper limit for bits_per_ch is thus 5, * resulting in 32768 bins. We could use an extra bit for green (i.e. * RGB565), but it's probably not worth the effort, and it increases the * risk of oversaturating the L2 cache, at which point we become slower * than your average dog. We'd also have to respect the G_MAXUINT16 * sentinel (effectively limiting us to 65535 bins). */ gint bits_per_ch; } QualityParams; static const QualityParams quality_params [] = { { .0f, 0, (1 << 14), 3 }, /* -w 1 */ { .1f, 0, (1 << 15), 3 }, /* -w 2 */ { .2f, 0, (1 << 16), 4 }, /* -w 3 */ { .3f, 0, (1 << 17), 4 }, /* -w 4 */ { .45f, 0, (1 << 18), 4 }, /* -w 5 */ { .6f, 0, (1 << 19), 5 }, /* -w 6 */ { .7f, 0, (1 << 20), 5 }, /* -w 7 */ { .8f, 0, (1 << 21), 5 }, /* -w 8 */ { .95f, 0, (1 << 26), 5 }, /* -w 9 */ { -.1f, -1, -1, -1 } }; static const QualityParams * get_quality_params (gfloat quality) { const QualityParams *params = &quality_params [0]; gint i; for (i = 0; quality_params [i].algorithm >= 0 && quality >= quality_params [i].min_quality; i++) { params = &quality_params [i]; } return params; } /* ---------------- * * Color candidates * * ---------------- */ /* Some situations (like fill symbols) call for both a best and a second-best * match. ChafaColorCandidates is used to track and return these. */ static void init_candidates (ChafaColorCandidates *candidates) { candidates->index [0] = candidates->index [1] = -1; candidates->error [0] = candidates->error [1] = G_MAXINT; } static gboolean update_candidates (ChafaColorCandidates *candidates, gint index, gint error) { if (error < candidates->error [0]) { candidates->index [1] = candidates->index [0]; candidates->index [0] = index; candidates->error [1] = candidates->error [0]; candidates->error [0] = error; return TRUE; } else if (error < candidates->error [1]) { candidates->index [1] = index; candidates->error [1] = error; return TRUE; } return FALSE; } /* -------------------- * * Fixed system palette * * -------------------- */ static const guint32 term_colors_256 [CHAFA_PALETTE_INDEX_MAX] = { /* First 16 colors; these are usually set by the terminal and can vary quite a * bit. We try to strike a balance. */ 0x000000, 0x800000, 0x007000, 0x707000, 0x000070, 0x700070, 0x007070, 0xc0c0c0, 0x404040, 0xff0000, 0x00ff00, 0xffff00, 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff, /* 240 universal colors; a 216-entry color cube followed by 24 grays */ 0x000000, 0x00005f, 0x000087, 0x0000af, 0x0000d7, 0x0000ff, 0x005f00, 0x005f5f, 0x005f87, 0x005faf, 0x005fd7, 0x005fff, 0x008700, 0x00875f, 0x008787, 0x0087af, 0x0087d7, 0x0087ff, 0x00af00, 0x00af5f, 0x00af87, 0x00afaf, 0x00afd7, 0x00afff, 0x00d700, 0x00d75f, 0x00d787, 0x00d7af, 0x00d7d7, 0x00d7ff, 0x00ff00, 0x00ff5f, 0x00ff87, 0x00ffaf, 0x00ffd7, 0x00ffff, 0x5f0000, 0x5f005f, 0x5f0087, 0x5f00af, 0x5f00d7, 0x5f00ff, 0x5f5f00, 0x5f5f5f, 0x5f5f87, 0x5f5faf, 0x5f5fd7, 0x5f5fff, 0x5f8700, 0x5f875f, 0x5f8787, 0x5f87af, 0x5f87d7, 0x5f87ff, 0x5faf00, 0x5faf5f, 0x5faf87, 0x5fafaf, 0x5fafd7, 0x5fafff, 0x5fd700, 0x5fd75f, 0x5fd787, 0x5fd7af, 0x5fd7d7, 0x5fd7ff, 0x5fff00, 0x5fff5f, 0x5fff87, 0x5fffaf, 0x5fffd7, 0x5fffff, 0x870000, 0x87005f, 0x870087, 0x8700af, 0x8700d7, 0x8700ff, 0x875f00, 0x875f5f, 0x875f87, 0x875faf, 0x875fd7, 0x875fff, 0x878700, 0x87875f, 0x878787, 0x8787af, 0x8787d7, 0x8787ff, 0x87af00, 0x87af5f, 0x87af87, 0x87afaf, 0x87afd7, 0x87afff, 0x87d700, 0x87d75f, 0x87d787, 0x87d7af, 0x87d7d7, 0x87d7ff, 0x87ff00, 0x87ff5f, 0x87ff87, 0x87ffaf, 0x87ffd7, 0x87ffff, 0xaf0000, 0xaf005f, 0xaf0087, 0xaf00af, 0xaf00d7, 0xaf00ff, 0xaf5f00, 0xaf5f5f, 0xaf5f87, 0xaf5faf, 0xaf5fd7, 0xaf5fff, 0xaf8700, 0xaf875f, 0xaf8787, 0xaf87af, 0xaf87d7, 0xaf87ff, 0xafaf00, 0xafaf5f, 0xafaf87, 0xafafaf, 0xafafd7, 0xafafff, 0xafd700, 0xafd75f, 0xafd787, 0xafd7af, 0xafd7d7, 0xafd7ff, 0xafff00, 0xafff5f, 0xafff87, 0xafffaf, 0xafffd7, 0xafffff, 0xd70000, 0xd7005f, 0xd70087, 0xd700af, 0xd700d7, 0xd700ff, 0xd75f00, 0xd75f5f, 0xd75f87, 0xd75faf, 0xd75fd7, 0xd75fff, 0xd78700, 0xd7875f, 0xd78787, 0xd787af, 0xd787d7, 0xd787ff, 0xd7af00, 0xd7af5f, 0xd7af87, 0xd7afaf, 0xd7afd7, 0xd7afff, 0xd7d700, 0xd7d75f, 0xd7d787, 0xd7d7af, 0xd7d7d7, 0xd7d7ff, 0xd7ff00, 0xd7ff5f, 0xd7ff87, 0xd7ffaf, 0xd7ffd7, 0xd7ffff, 0xff0000, 0xff005f, 0xff0087, 0xff00af, 0xff00d7, 0xff00ff, 0xff5f00, 0xff5f5f, 0xff5f87, 0xff5faf, 0xff5fd7, 0xff5fff, 0xff8700, 0xff875f, 0xff8787, 0xff87af, 0xff87d7, 0xff87ff, 0xffaf00, 0xffaf5f, 0xffaf87, 0xffafaf, 0xffafd7, 0xffafff, 0xffd700, 0xffd75f, 0xffd787, 0xffd7af, 0xffd7d7, 0xffd7ff, 0xffff00, 0xffff5f, 0xffff87, 0xffffaf, 0xffffd7, 0xffffff, 0x080808, 0x121212, 0x1c1c1c, 0x262626, 0x303030, 0x3a3a3a, 0x444444, 0x4e4e4e, 0x585858, 0x626262, 0x6c6c6c, 0x767676, 0x808080, 0x8a8a8a, 0x949494, 0x9e9e9e, 0xa8a8a8, 0xb2b2b2, 0xbcbcbc, 0xc6c6c6, 0xd0d0d0, 0xdadada, 0xe4e4e4, 0xeeeeee, /* Special colors */ 0x808080, /* Transparent */ 0xffffff, /* Terminal's default foreground */ 0x000000, /* Terminal's default background */ }; static ChafaPaletteColor fixed_palette_256 [CHAFA_PALETTE_INDEX_MAX]; static guchar color_cube_216_channel_index [256]; static gboolean palette_initialized; static const ChafaColor * get_fixed_palette_color (guint index, ChafaColorSpace color_space) { return &fixed_palette_256 [index].col [color_space]; } void chafa_init_palette (void) { gint i; if (palette_initialized) return; for (i = 0; i < CHAFA_PALETTE_INDEX_MAX; i++) { chafa_unpack_color (term_colors_256 [i], &fixed_palette_256 [i].col [0]); chafa_color_rgb_to_din99d (&fixed_palette_256 [i].col [0], &fixed_palette_256 [i].col [1]); fixed_palette_256 [i].col [0].ch [3] = 0xff; /* Fully opaque */ fixed_palette_256 [i].col [1].ch [3] = 0xff; /* Fully opaque */ } /* Transparent color */ fixed_palette_256 [CHAFA_PALETTE_INDEX_TRANSPARENT].col [0].ch [3] = 0x00; fixed_palette_256 [CHAFA_PALETTE_INDEX_TRANSPARENT].col [1].ch [3] = 0x00; for (i = 0; i < 0x5f / 2; i++) color_cube_216_channel_index [i] = 0; for ( ; i < (0x5f + 0x87) / 2; i++) color_cube_216_channel_index [i] = 1; for ( ; i < (0x87 + 0xaf) / 2; i++) color_cube_216_channel_index [i] = 2; for ( ; i < (0xaf + 0xd7) / 2; i++) color_cube_216_channel_index [i] = 3; for ( ; i < (0xd7 + 0xff) / 2; i++) color_cube_216_channel_index [i] = 4; for ( ; i <= 0xff; i++) color_cube_216_channel_index [i] = 5; palette_initialized = TRUE; } static gint update_candidates_with_color_index_diff (ChafaColorCandidates *candidates, ChafaColorSpace color_space, const ChafaColor *color, gint index) { const ChafaColor *palette_color; gint error; palette_color = get_fixed_palette_color (index, color_space); error = chafa_color_diff_fast (color, palette_color); update_candidates (candidates, index, error); return error; } static void pick_color_fixed_216_cube (const ChafaColor *color, ChafaColorSpace color_space, ChafaColorCandidates *candidates) { gint i; g_assert (color_space == CHAFA_COLOR_SPACE_RGB); i = 16 + (color_cube_216_channel_index [color->ch [0]] * 6 * 6 + color_cube_216_channel_index [color->ch [1]] * 6 + color_cube_216_channel_index [color->ch [2]]); update_candidates_with_color_index_diff (candidates, color_space, color, i); } static void pick_color_fixed_24_grays (const ChafaColor *color, ChafaColorSpace color_space, ChafaColorCandidates *candidates) { const ChafaColor *palette_color; gint error, last_error = G_MAXINT; gint step, i; g_assert (color_space == CHAFA_COLOR_SPACE_RGB); i = 232 + 12; last_error = update_candidates_with_color_index_diff (candidates, color_space, color, i); palette_color = get_fixed_palette_color (i + 1, color_space); error = chafa_color_diff_fast (color, palette_color); if (error < last_error) { update_candidates (candidates, i, error); last_error = error; step = 1; i++; } else { step = -1; } do { i += step; palette_color = get_fixed_palette_color (i, color_space); error = chafa_color_diff_fast (color, palette_color); if (error > last_error) break; update_candidates (candidates, i, error); last_error = error; } while (i >= 232 && i <= 255); } static void pick_color_fixed_16 (const ChafaColor *color, ChafaColorSpace color_space, ChafaColorCandidates *candidates) { gint i; for (i = 0; i < 16; i++) { update_candidates_with_color_index_diff (candidates, color_space, color, i); } } static void pick_color_fixed_8 (const ChafaColor *color, ChafaColorSpace color_space, ChafaColorCandidates *candidates) { gint i; for (i = 0; i < 8; i++) { update_candidates_with_color_index_diff (candidates, color_space, color, i); } } static void pick_color_fixed_256 (const ChafaColor *color, ChafaColorSpace color_space, ChafaColorCandidates *candidates) { gint i; if (color_space == CHAFA_COLOR_SPACE_RGB) { pick_color_fixed_216_cube (color, color_space, candidates); pick_color_fixed_24_grays (color, color_space, candidates); /* Do this last so ties are broken in favor of high-index colors. */ pick_color_fixed_16 (color, color_space, candidates); } else { for (i = 0; i < 256; i++) { update_candidates_with_color_index_diff (candidates, color_space, color, i); } } } static void pick_color_fixed_240 (const ChafaColor *color, ChafaColorSpace color_space, ChafaColorCandidates *candidates) { gint i; if (color_space == CHAFA_COLOR_SPACE_RGB) { pick_color_fixed_216_cube (color, color_space, candidates); pick_color_fixed_24_grays (color, color_space, candidates); } else { /* Check color cube, but not lower 16, bg or fg. Slow! */ for (i = 16; i < 256; i++) { update_candidates_with_color_index_diff (candidates, color_space, color, i); } } } /* Pick the best approximation of color from a palette consisting of * fg_color and bg_color */ static void pick_color_fixed_fgbg (const ChafaColor *color, const ChafaColor *fg_color, const ChafaColor *bg_color, ChafaColorCandidates *candidates) { gint error; error = chafa_color_diff_fast (color, fg_color); update_candidates (candidates, CHAFA_PALETTE_INDEX_FG, error); error = chafa_color_diff_fast (color, bg_color); update_candidates (candidates, CHAFA_PALETTE_INDEX_BG, error); } /* ----------------------------------- * * Pairwise nearest neighbor quantizer * * ----------------------------------- */ /* Implementation inspired by nQuant by Mark Tyler, Dmitry Groshev and * Miller Cy Chan. * * There's a nice description of the PNN algorithm and several fast * variants in DOI:10.1117/1.1412423 and DOI:10.1117/1.1604396. */ #define RED_WEIGHT_32f .299f #define GREEN_WEIGHT_32f .587f #define BLUE_WEIGHT_32f .114f #define RATIO .5f static const ChafaVec3f32 pnn_coeffs [3] = { CHAFA_VEC3F32_INIT (RED_WEIGHT_32f, GREEN_WEIGHT_32f, BLUE_WEIGHT_32f), CHAFA_VEC3F32_INIT (-0.14713f, -0.28886f, 0.436f), CHAFA_VEC3F32_INIT (0.615f, -0.51499f, -0.10001f) }; typedef guint16 PnnBinIndex; typedef struct { ChafaVec3f32 accum; gfloat err; gfloat count; PnnBinIndex nearest, next, prev, tm, mtm; } PnnBin; /* 3 <= bits_per_ch <= 8. However, we're limited to <= 5 bits elsewhere. */ static gint color_to_index (const ChafaColor *color, gint bits_per_ch) { guint8 mask = 0xff << (8 - bits_per_ch); return ((color->ch [0] & mask) << (bits_per_ch * 2 - (8 - bits_per_ch))) | ((color->ch [1] & mask) << (bits_per_ch - (8 - bits_per_ch))) | ((color->ch [2] & mask) >> (8 - bits_per_ch)); } static gfloat quanfn (gfloat count, gint quan_rt) { if (quan_rt > 0) { if (quan_rt > 1) return (gfloat) (gint) sqrtf (count); return sqrtf (count); } if (quan_rt < 0) return (gfloat) (gint) cbrtf (count); return count; } static void find_nearest (PnnBin *bins, PnnBinIndex index, const ChafaVec3f32 *rgb_weights) { PnnBin *bin1 = &bins [index]; gfloat err = G_MAXFLOAT; PnnBinIndex nearest = 0; PnnBinIndex i, j; for (i = bin1->next; i; i = bins [i].next) { gfloat bin2_count = bins [i].count; gfloat nerr2 = (bin1->count * bin2_count) / (bin1->count + bin2_count); gfloat nerr = .0f; ChafaVec3f32 tv; if (nerr2 >= err) continue; chafa_vec3f32_sub (&tv, &bins [i].accum, &bin1->accum); chafa_vec3f32_hadamard (&tv, &tv, &tv); chafa_vec3f32_hadamard (&tv, &tv, rgb_weights); chafa_vec3f32_mul_scalar (&tv, &tv, nerr2 * (1 - RATIO)); nerr += chafa_vec3f32_sum_to_scalar (&tv); if (nerr >= err) continue; for (j = 0; j < 3; j++) { chafa_vec3f32_sub (&tv, &bins [i].accum, &bin1->accum); chafa_vec3f32_hadamard (&tv, &tv, &pnn_coeffs [j]); chafa_vec3f32_hadamard (&tv, &tv, &tv); chafa_vec3f32_mul_scalar (&tv, &tv, nerr2 * RATIO); nerr += chafa_vec3f32_sum_to_scalar (&tv); if (nerr >= err) break; } if (nerr < err) { err = nerr; nearest = i; } } bin1->err = err; bin1->nearest = nearest; } static void vec3f32_add_color (ChafaVec3f32 *out, const ChafaColor *col) { out->v [0] += col->ch [0]; out->v [1] += col->ch [1]; out->v [2] += col->ch [2]; /* Ignore alpha */ } static void color_from_vec3f32_trunc (ChafaColor *col, const ChafaVec3f32 *v) { col->ch [0] = v->v [0]; col->ch [1] = v->v [1]; col->ch [2] = v->v [2]; /* Ignore alpha */ } static gint sample_to_bins (PnnBin *bins, gconstpointer pixels, size_t n_pixels, size_t step, gint bits_per_ch, gint alpha_threshold) { const ChafaColor *p = (const ChafaColor *) pixels; gint n_samples = 0; size_t i; for (i = 0; i < n_pixels; i += step) { const ChafaColor col = p [i]; PnnBin *tb; if (col.ch [3] < alpha_threshold) continue; tb = &bins [color_to_index (&col, bits_per_ch)]; vec3f32_add_color (&tb->accum, &col); tb->count += 1.0f; n_samples++; } return n_samples; } static gint pnn_palette (ChafaPalette *pal, gconstpointer pixels, gsize n_pixels, gint n_cols, gint bits_per_ch, gsize sample_step, gint alpha_threshold) { ChafaVec3f32 rgb_weights = CHAFA_VEC3F32_INIT (RED_WEIGHT_32f, GREEN_WEIGHT_32f, BLUE_WEIGHT_32f); PnnBin *bins = NULL; PnnBinIndex *heap = NULL; gfloat weight = 1.0f; gint quan_rt = 1; gint max_bins, n_bins; gint extbins; gint i, j, k = -1; g_assert (bits_per_ch >= 3); g_assert (bits_per_ch <= 5); max_bins = 1 << (bits_per_ch * 3); bins = g_new0 (PnnBin, max_bins); /* --- Extract samples and assign to bins --- */ if (sample_to_bins (bins, pixels, n_pixels, sample_step, bits_per_ch, alpha_threshold) < 256) { /* Too many transparent pixels. Try again at maximum density */ memset (bins, 0, max_bins * sizeof (PnnBin)); if (sample_to_bins (bins, pixels, n_pixels, 1, bits_per_ch, alpha_threshold) <= 0) goto out; } /* --- Count active bins and average their colors --- */ for (i = 0, n_bins = 0; i < max_bins; i++) { PnnBin *tb = &bins [i]; if (bins [i].count <= .0f) continue; chafa_vec3f32_mul_scalar (&tb->accum, &tb->accum, 1.0f / tb->count); bins [n_bins++] = *tb; } /* --- Set up weights and bin counts --- */ if (n_cols < 16) quan_rt = -1; weight = MIN (0.9f, n_cols * 1.0f / n_bins); if (weight < .03f && rgb_weights.v [1] < 1.0f && rgb_weights.v [1] >= pnn_coeffs [0].v [1]) { chafa_vec3f32_set (&rgb_weights, 1.0f, 1.0f, 1.0f); if (n_cols >= 64) quan_rt = 0; } if (quan_rt > 0 && n_cols < 64) quan_rt = 2; for (j = 0; j < n_bins - 1; j++) { bins [j].next = j + 1; bins [j + 1].prev = j; bins [j].count = quanfn (bins [j].count, quan_rt); } bins [j].count = quanfn (bins [j].count, quan_rt); /* --- Set up heap --- */ heap = g_new0 (PnnBinIndex, max_bins + 1); for (i = 0; i < n_bins; i++) { PnnBinIndex h, l, l2; gfloat err; find_nearest (bins, i, &rgb_weights); err = bins [i].err; heap [0]++; for (l = heap [0]; l > 1; l = l2) { l2 = l >> 1; h = heap [l2]; if (bins [h].err <= err) break; heap [l] = h; } heap [l] = i; } /* --- Merge bins iteratively --- */ extbins = n_bins - n_cols; for (i = 0; i < extbins; ) { ChafaVec3f32 tv1; PnnBin *tb; PnnBin *nb; gfloat n1; gfloat n2; gfloat d; PnnBinIndex b1; gfloat err; for (;;) { PnnBinIndex h, l, l2; b1 = heap [1]; tb = &bins [b1]; if ((tb->tm >= tb->mtm) && (bins [tb->nearest].mtm <= tb->tm)) break; if (tb->mtm == G_MAXUINT16) { b1 = heap [1] = heap [heap [0]]; heap [0]--; } else { find_nearest (bins, b1, &rgb_weights); tb->tm = i; } err = bins [b1].err; for (l = 1, l2 = 2; l2 <= heap [0]; l = l2, l2 = l * 2) { if ((l2 < heap [0]) && (bins [heap [l2]].err > bins [heap [l2 + 1]].err)) l2++; h = heap [l2]; if (err <= bins [h].err) break; heap [l] = h; } heap [l] = b1; } tb = &bins [b1]; nb = &bins [tb->nearest]; n1 = tb->count; n2 = nb->count; d = 1.0f / (n1 + n2); chafa_vec3f32_mul_scalar (&tb->accum, &tb->accum, n1); chafa_vec3f32_mul_scalar (&tv1, &nb->accum, n2); chafa_vec3f32_add (&tb->accum, &tb->accum, &tv1); chafa_vec3f32_round (&tb->accum, &tb->accum); chafa_vec3f32_mul_scalar (&tb->accum, &tb->accum, d); tb->count += n2; tb->mtm = ++i; bins [nb->prev].next = nb->next; bins [nb->next].prev = nb->prev; nb->mtm = G_MAXUINT16; } /* --- Export final colors --- */ for (i = 0, k = 0; ; k++) { ChafaColor col = { 0 }; color_from_vec3f32_trunc (&col, &bins [i].accum); col.ch [3] = 0xff; pal->colors [k].col [CHAFA_COLOR_SPACE_RGB] = col; i = bins [i].next; if (!i) break; } out: g_free (heap); g_free (bins); /* We may produce fewer colors than requested */ return k + 1; } static void gen_din99d_color_space (ChafaPalette *palette) { gint i; for (i = 0; i < palette->n_colors; i++) { chafa_color_rgb_to_din99d (&palette->colors [i].col [CHAFA_COLOR_SPACE_RGB], &palette->colors [i].col [CHAFA_COLOR_SPACE_DIN99D]); } } static void gen_table (ChafaPalette *palette, ChafaColorSpace color_space) { gint i; for (i = 0; i < palette->n_colors; i++) { const ChafaColor *col; if (i == palette->transparent_index) continue; col = &palette->colors [i].col [color_space]; chafa_color_table_set_pen_color (&palette->table [color_space], i, col->ch [0] | (col->ch [1] << 8) | (col->ch [2] << 16)); } chafa_color_table_sort (&palette->table [color_space]); } static void clean_up (ChafaPalette *palette_out) { gint i, j; gint best_diff = G_MAXINT; gint best_pair = 1; /* Reserve 0th pen for transparency and move colors up. * Eliminate duplicates and colors that would be the same in * sixel representation (0..100). */ DEBUG (g_printerr ("Colors before: %d\n", palette_out->n_colors)); for (i = 1, j = 1; i < palette_out->n_colors; i++) { ChafaColor *a, *b; gint diff, t; a = &palette_out->colors [j - 1].col [CHAFA_COLOR_SPACE_RGB]; b = &palette_out->colors [i].col [CHAFA_COLOR_SPACE_RGB]; /* Dividing by 256 is strictly not correct, but it's close enough for * comparison purposes, and a lot faster too. */ t = (gint) (a->ch [0] * 100) / 256 - (gint) (b->ch [0] * 100) / 256; diff = t * t; t = (gint) (a->ch [1] * 100) / 256 - (gint) (b->ch [1] * 100) / 256; diff += t * t; t = (gint) (a->ch [2] * 100) / 256 - (gint) (b->ch [2] * 100) / 256; diff += t * t; if (diff == 0) { DEBUG (g_printerr ("%d and %d are the same\n", j - 1, i)); continue; } else if (diff < best_diff) { best_pair = j - 1; best_diff = diff; } palette_out->colors [j++] = palette_out->colors [i]; } palette_out->n_colors = j; DEBUG (g_printerr ("Colors after: %d\n", palette_out->n_colors)); g_assert (palette_out->n_colors >= 0 && palette_out->n_colors <= 256); if (palette_out->transparent_index < 256) { if (palette_out->n_colors < 256) { DEBUG (g_printerr ("Color 0 moved to end (%d)\n", palette_out->n_colors)); palette_out->colors [palette_out->n_colors] = palette_out->colors [palette_out->transparent_index]; palette_out->n_colors++; } else { /* Delete one color to make room for transparency */ palette_out->colors [best_pair] = palette_out->colors [palette_out->transparent_index]; DEBUG (g_printerr ("Color 0 replaced %d\n", best_pair)); } } } /* --- * * API * * --- */ void chafa_palette_init (ChafaPalette *palette_out, ChafaPaletteType type) { gint i; chafa_init_palette (); palette_out->type = type; palette_out->transparent_index = CHAFA_PALETTE_INDEX_TRANSPARENT; for (i = 0; i < CHAFA_PALETTE_INDEX_MAX; i++) { palette_out->colors [i].col [CHAFA_COLOR_SPACE_RGB] = *get_fixed_palette_color (i, CHAFA_COLOR_SPACE_RGB); palette_out->colors [i].col [CHAFA_COLOR_SPACE_DIN99D] = *get_fixed_palette_color (i, CHAFA_COLOR_SPACE_DIN99D); } switch (type) { case CHAFA_PALETTE_TYPE_FIXED_FGBG: palette_out->first_color = CHAFA_PALETTE_INDEX_FG; palette_out->n_colors = 2; break; case CHAFA_PALETTE_TYPE_FIXED_8: palette_out->n_colors = 8; break; case CHAFA_PALETTE_TYPE_FIXED_16: palette_out->n_colors = 16; break; case CHAFA_PALETTE_TYPE_FIXED_240: palette_out->first_color = 16; palette_out->n_colors = 240; break; case CHAFA_PALETTE_TYPE_FIXED_256: palette_out->first_color = 0; palette_out->n_colors = 256; break; case CHAFA_PALETTE_TYPE_DYNAMIC_256: for (i = 0; i < CHAFA_COLOR_SPACE_MAX; i++) chafa_color_table_init (&palette_out->table [i]); break; } } void chafa_palette_deinit (ChafaPalette *palette) { gint i; if (palette->type == CHAFA_PALETTE_TYPE_DYNAMIC_256) { for (i = 0; i < CHAFA_COLOR_SPACE_MAX; i++) chafa_color_table_deinit (&palette->table [i]); } } gint chafa_palette_get_first_color (const ChafaPalette *palette) { return palette->first_color; } gint chafa_palette_get_n_colors (const ChafaPalette *palette) { return palette->n_colors; } void chafa_palette_copy (const ChafaPalette *src, ChafaPalette *dest) { memcpy (dest, src, sizeof (*dest)); } /* pixels must point to RGBA8888 data to sample */ /* FIXME: Rowstride etc? */ void chafa_palette_generate (ChafaPalette *palette_out, gconstpointer pixels, gsize n_pixels, ChafaColorSpace color_space, gfloat quality) { const QualityParams *params; gsize step; if (palette_out->type != CHAFA_PALETTE_TYPE_DYNAMIC_256) return; /* --- Determine quality parameters --- */ if (quality < 0.0f) quality = 0.5f; quality = CLAMP (quality, 0.0f, 1.0f); params = get_quality_params (quality); step = n_pixels / params->n_samples; /* If step is small, revert to dense sampling. We're going to fetch * every cache line anyway, might as well make the most of it. */ if (step <= 4) step = 1; /* --- Generate --- */ palette_out->n_colors = pnn_palette (palette_out, pixels, n_pixels, 255, params->bits_per_ch, step, palette_out->alpha_threshold); clean_up (palette_out); gen_table (palette_out, CHAFA_COLOR_SPACE_RGB); if (color_space == CHAFA_COLOR_SPACE_DIN99D) { gen_din99d_color_space (palette_out); gen_table (palette_out, CHAFA_COLOR_SPACE_DIN99D); } } gint chafa_palette_lookup_nearest (const ChafaPalette *palette, ChafaColorSpace color_space, const ChafaColor *color, ChafaColorCandidates *candidates) { if (palette->type == CHAFA_PALETTE_TYPE_DYNAMIC_256) { gint result; /* Transparency */ if (color->ch [3] < palette->alpha_threshold) return palette->transparent_index; result = chafa_color_table_find_nearest_pen (&palette->table [color_space], color->ch [0] | (color->ch [1] << 8) | (color->ch [2] << 16)); if (candidates) { /* The only consumer of multiple candidates is the cell canvas, and that * supports fixed palettes only. Therefore, in practice we'll never end up here. * Let's not leave a loose end, though... */ candidates->index [0] = result; candidates->index [1] = result; candidates->error [0] = 0; candidates->error [1] = 0; } return result; } else { ChafaColorCandidates candidates_temp; if (!candidates) candidates = &candidates_temp; init_candidates (candidates); if (color->ch [3] < palette->alpha_threshold) { /* Transparency */ candidates->index [0] = palette->transparent_index; candidates->index [1] = palette->transparent_index; candidates->error [0] = 0; candidates->error [1] = 0; } else if (palette->type == CHAFA_PALETTE_TYPE_FIXED_256) pick_color_fixed_256 (color, color_space, candidates); else if (palette->type == CHAFA_PALETTE_TYPE_FIXED_240) pick_color_fixed_240 (color, color_space, candidates); else if (palette->type == CHAFA_PALETTE_TYPE_FIXED_16) pick_color_fixed_16 (color, color_space, candidates); else if (palette->type == CHAFA_PALETTE_TYPE_FIXED_8) pick_color_fixed_8 (color, color_space, candidates); else /* CHAFA_PALETTE_TYPE_FIXED_FGBG */ pick_color_fixed_fgbg (color, &palette->colors [CHAFA_PALETTE_INDEX_FG].col [color_space], &palette->colors [CHAFA_PALETTE_INDEX_BG].col [color_space], candidates); if (palette->transparent_index < 256) { if (candidates->index [0] == palette->transparent_index) { candidates->index [0] = candidates->index [1]; candidates->error [0] = candidates->error [1]; } else { if (candidates->index [0] == CHAFA_PALETTE_INDEX_TRANSPARENT) candidates->index [0] = palette->transparent_index; if (candidates->index [1] == CHAFA_PALETTE_INDEX_TRANSPARENT) candidates->index [1] = palette->transparent_index; } } return candidates->index [0]; } g_assert_not_reached (); } gint chafa_palette_lookup_with_error (const ChafaPalette *palette, ChafaColorSpace color_space, ChafaColor color, ChafaColorAccum *error_inout) { ChafaColorAccum compensated_color; gint index; if (error_inout) { compensated_color.ch [0] = ((gint16) color.ch [0]) + ((error_inout->ch [0] * 0.9f) / 16); compensated_color.ch [1] = ((gint16) color.ch [1]) + ((error_inout->ch [1] * 0.9f) / 16); compensated_color.ch [2] = ((gint16) color.ch [2]) + ((error_inout->ch [2] * 0.9f) / 16); color.ch [0] = CLAMP (compensated_color.ch [0], 0, 255); color.ch [1] = CLAMP (compensated_color.ch [1], 0, 255); color.ch [2] = CLAMP (compensated_color.ch [2], 0, 255); } index = chafa_palette_lookup_nearest (palette, color_space, &color, NULL); if (error_inout) { if (index == palette->transparent_index) { memset (error_inout, 0, sizeof (*error_inout)); } else { ChafaColor found_color = palette->colors [index].col [color_space]; error_inout->ch [0] = ((gint16) compensated_color.ch [0]) - ((gint16) found_color.ch [0]); error_inout->ch [1] = ((gint16) compensated_color.ch [1]) - ((gint16) found_color.ch [1]); error_inout->ch [2] = ((gint16) compensated_color.ch [2]) - ((gint16) found_color.ch [2]); } } return index; } ChafaPaletteType chafa_palette_get_type (const ChafaPalette *palette) { return palette->type; } const ChafaColor * chafa_palette_get_color (const ChafaPalette *palette, ChafaColorSpace color_space, gint index) { return &palette->colors [index].col [color_space]; } void chafa_palette_set_color (ChafaPalette *palette, gint index, const ChafaColor *color) { palette->colors [index].col [CHAFA_COLOR_SPACE_RGB] = *color; chafa_color_rgb_to_din99d (&palette->colors [index].col [CHAFA_COLOR_SPACE_RGB], &palette->colors [index].col [CHAFA_COLOR_SPACE_DIN99D]); } gint chafa_palette_get_alpha_threshold (const ChafaPalette *palette) { return palette->alpha_threshold; } void chafa_palette_set_alpha_threshold (ChafaPalette *palette, gint alpha_threshold) { palette->alpha_threshold = alpha_threshold; } gint chafa_palette_get_transparent_index (const ChafaPalette *palette) { return palette->transparent_index; } void chafa_palette_set_transparent_index (ChafaPalette *palette, gint index) { palette->transparent_index = index; } chafa-1.18.2/chafa/internal/chafa-palette.h000066400000000000000000000060601517447374300204130ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PALETTE_H__ #define __CHAFA_PALETTE_H__ #include #include "internal/chafa-color.h" #include "internal/chafa-color-table.h" G_BEGIN_DECLS typedef enum { CHAFA_PALETTE_TYPE_DYNAMIC_256, CHAFA_PALETTE_TYPE_FIXED_256, CHAFA_PALETTE_TYPE_FIXED_240, CHAFA_PALETTE_TYPE_FIXED_16, CHAFA_PALETTE_TYPE_FIXED_8, CHAFA_PALETTE_TYPE_FIXED_FGBG } ChafaPaletteType; typedef struct { ChafaPaletteType type; ChafaPaletteColor colors [CHAFA_PALETTE_INDEX_MAX]; ChafaColorTable table [CHAFA_COLOR_SPACE_MAX]; gint first_color; gint n_colors; gint alpha_threshold; gint transparent_index; } ChafaPalette; /* Global init */ void chafa_init_palette (void); void chafa_palette_init (ChafaPalette *palette_out, ChafaPaletteType type); void chafa_palette_deinit (ChafaPalette *palette); void chafa_palette_copy (const ChafaPalette *src, ChafaPalette *dest); void chafa_palette_generate (ChafaPalette *palette_out, gconstpointer pixels, gsize n_pixels, ChafaColorSpace color_space, gfloat quality); ChafaPaletteType chafa_palette_get_type (const ChafaPalette *palette); gint chafa_palette_get_first_color (const ChafaPalette *palette); gint chafa_palette_get_n_colors (const ChafaPalette *palette); gint chafa_palette_lookup_nearest (const ChafaPalette *palette, ChafaColorSpace color_space, const ChafaColor *color, ChafaColorCandidates *candidates); gint chafa_palette_lookup_with_error (const ChafaPalette *palette, ChafaColorSpace color_space, ChafaColor color, ChafaColorAccum *error_inout); const ChafaColor *chafa_palette_get_color (const ChafaPalette *palette, ChafaColorSpace color_space, gint index); void chafa_palette_set_color (ChafaPalette *palette, gint index, const ChafaColor *color); gint chafa_palette_get_alpha_threshold (const ChafaPalette *palette); void chafa_palette_set_alpha_threshold (ChafaPalette *palette, gint alpha_threshold); gint chafa_palette_get_transparent_index (const ChafaPalette *palette); void chafa_palette_set_transparent_index (ChafaPalette *palette, gint index); G_END_DECLS #endif /* __CHAFA_PALETTE_H__ */ chafa-1.18.2/chafa/internal/chafa-passthrough-encoder.c000066400000000000000000000113261517447374300227350ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* strlen */ #include "chafa.h" #include "internal/chafa-passthrough-encoder.h" #define ESCAPE_BUF_SIZE 1024 static const gint packet_size_max [CHAFA_PASSTHROUGH_MAX] = { /* Screen's OSC buffer size was increased to 2560 in bfb05c34ba1f961a15ccea04c5. * This was quite a while ago, but it appears it still hasn't made its way into * some of the important OS distributions. */ [CHAFA_PASSTHROUGH_SCREEN] = 200, [CHAFA_PASSTHROUGH_TMUX] = 1000000 }; static void append_begin (ChafaPassthroughEncoder *ptenc) { gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; if (ptenc->mode == CHAFA_PASSTHROUGH_SCREEN) { *chafa_term_info_emit_begin_screen_passthrough (ptenc->term_info, seq) = '\0'; g_string_append (ptenc->out, seq); } else if (ptenc->mode == CHAFA_PASSTHROUGH_TMUX) { *chafa_term_info_emit_begin_tmux_passthrough (ptenc->term_info, seq) = '\0'; g_string_append (ptenc->out, seq); } } static void append_end (ChafaPassthroughEncoder *ptenc) { gchar seq [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; if (ptenc->mode == CHAFA_PASSTHROUGH_SCREEN) { *chafa_term_info_emit_end_screen_passthrough (ptenc->term_info, seq) = '\0'; g_string_append (ptenc->out, seq); } else if (ptenc->mode == CHAFA_PASSTHROUGH_TMUX) { *chafa_term_info_emit_end_tmux_passthrough (ptenc->term_info, seq) = '\0'; g_string_append (ptenc->out, seq); } } static void append_packetized (ChafaPassthroughEncoder *ptenc, const gchar *in, gint len) { while (len > 0) { gssize remain = packet_size_max [ptenc->mode] - ptenc->packet_size; gint n; if (remain == 0) { append_end (ptenc); ptenc->packet_size = 0; remain = packet_size_max [ptenc->mode]; } if (ptenc->packet_size == 0) { append_begin (ptenc); } n = MIN (len, remain); g_string_append_len (ptenc->out, in, n); len -= n; ptenc->packet_size += n; in += n; } } static void append_escaped (ChafaPassthroughEncoder *ptenc, const gchar *in, gint len) { gchar buf [ESCAPE_BUF_SIZE]; gint i, j; for (i = 0, j = 0; i < len; i++) { buf [j++] = in [i]; if (in [i] == 0x1b) buf [j++] = 0x1b; if (j + 2 > ESCAPE_BUF_SIZE) { append_packetized (ptenc, buf, j); j = 0; } } append_packetized (ptenc, buf, j); } void chafa_passthrough_encoder_begin (ChafaPassthroughEncoder *ptenc, ChafaPassthrough passthrough, ChafaTermInfo *term_info, GString *out_str) { ptenc->mode = passthrough; ptenc->term_info = term_info; chafa_term_info_ref (term_info); ptenc->out = out_str; ptenc->packet_size = 0; } void chafa_passthrough_encoder_end (ChafaPassthroughEncoder *ptenc) { if (ptenc->packet_size > 0) chafa_passthrough_encoder_flush (ptenc); chafa_term_info_unref (ptenc->term_info); } void chafa_passthrough_encoder_append_len (ChafaPassthroughEncoder *ptenc, const gchar *in, gint len) { if (ptenc->mode == CHAFA_PASSTHROUGH_NONE) { g_string_append_len (ptenc->out, in, len); } else if (ptenc->mode == CHAFA_PASSTHROUGH_SCREEN) { append_packetized (ptenc, in, len); } else { append_escaped (ptenc, in, len); } } void chafa_passthrough_encoder_append (ChafaPassthroughEncoder *ptenc, const gchar *in) { chafa_passthrough_encoder_append_len (ptenc, in, strlen (in)); } void chafa_passthrough_encoder_flush (ChafaPassthroughEncoder *ptenc) { if (ptenc->packet_size > 0) { append_end (ptenc); ptenc->packet_size = 0; } } void chafa_passthrough_encoder_reset (ChafaPassthroughEncoder *ptenc) { ptenc->packet_size = 0; } chafa-1.18.2/chafa/internal/chafa-passthrough-encoder.h000066400000000000000000000036511517447374300227440ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PASSTHROUGH_ENCODER_H__ #define __CHAFA_PASSTHROUGH_ENCODER_H__ #include "chafa.h" G_BEGIN_DECLS typedef struct { ChafaPassthrough mode; ChafaTermInfo *term_info; GString *out; gint packet_size; } ChafaPassthroughEncoder; void chafa_passthrough_encoder_begin (ChafaPassthroughEncoder *ptenc, ChafaPassthrough passthrough, ChafaTermInfo *term_info, GString *out_str); void chafa_passthrough_encoder_end (ChafaPassthroughEncoder *ptenc); void chafa_passthrough_encoder_append (ChafaPassthroughEncoder *ptenc, const gchar *in); void chafa_passthrough_encoder_append_len (ChafaPassthroughEncoder *ptenc, const gchar *in, gint len); void chafa_passthrough_encoder_flush (ChafaPassthroughEncoder *ptenc); void chafa_passthrough_encoder_reset (ChafaPassthroughEncoder *ptenc); G_END_DECLS #endif /* __CHAFA_PASSTHROUGH_ENCODER_H__ */ chafa-1.18.2/chafa/internal/chafa-pca.c000066400000000000000000000111551517447374300175140ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* memcpy */ #include "internal/chafa-pca.h" #define PCA_POWER_MAX_ITERATIONS 1000 #define PCA_POWER_MIN_ERROR 0.0001f static gfloat pca_converge (const ChafaVec3f32 *vecs_in, gint n_vecs, ChafaVec3f32 *eigenvector_out) { ChafaVec3f32 r = CHAFA_VEC3F32_INIT (.11, .23, .51); gfloat eigenvalue; gint i, j; /* Power iteration */ /* FIXME: r should probably be random, and we should try again * if we pick a bad one */ chafa_vec3f32_normalize (&r, &r); for (j = 0; j < PCA_POWER_MAX_ITERATIONS; j++) { ChafaVec3f32 s = CHAFA_VEC3F32_INIT_ZERO; ChafaVec3f32 t; gfloat err; for (i = 0; i < n_vecs; i++) { gfloat u; u = chafa_vec3f32_dot (&vecs_in [i], &r); chafa_vec3f32_mul_scalar (&t, &vecs_in [i], u); chafa_vec3f32_add (&s, &s, &t); } eigenvalue = chafa_vec3f32_dot (&r, &s); chafa_vec3f32_mul_scalar (&t, &r, eigenvalue); chafa_vec3f32_sub (&t, &t, &s); err = chafa_vec3f32_get_magnitude (&t); chafa_vec3f32_copy (&r, &s); chafa_vec3f32_normalize (&r, &r); if (err < PCA_POWER_MIN_ERROR) break; } chafa_vec3f32_copy (eigenvector_out, &r); return eigenvalue; } static void pca_deflate (ChafaVec3f32 *vecs, gint n_vecs, const ChafaVec3f32 *eigenvector) { gint i; /* Calculate scores, reconstruct with scores and eigenvector, * then subtract from original vectors to generate residuals. * We should be able to get the next component from those. */ for (i = 0; i < n_vecs; i++) { ChafaVec3f32 t; gfloat score; score = chafa_vec3f32_dot (&vecs [i], eigenvector); chafa_vec3f32_mul_scalar (&t, eigenvector, score); chafa_vec3f32_sub (&vecs [i], &vecs [i], &t); } } /** * chafa_vec3f32_array_compute_pca: * @vecs_in: Input vector array * @n_vecs: Number of vectors in array * @n_components: Number of components to compute (1 or 2) * @eigenvectors_out: Pointer to array to store n_components eigenvectors in, or NULL * @eigenvalues_out: Pointer to array to store n_components eigenvalues in, or NULL * @average_out: Pointer to a vector to store array average (for centering), or NULL * * Compute principal components from an array of 3D vectors. This * implementation is naive and probably not that fast, but it should * be good enough for our purposes. **/ void chafa_vec3f32_array_compute_pca (const ChafaVec3f32 *vecs_in, gint n_vecs, gint n_components, ChafaVec3f32 *eigenvectors_out, gfloat *eigenvalues_out, ChafaVec3f32 *average_out) { ChafaVec3f32 *v; ChafaVec3f32 average; ChafaVec3f32 t; gfloat eigenvalue; gint i; v = g_malloc (n_vecs * sizeof (ChafaVec3f32)); memcpy (v, vecs_in, n_vecs * sizeof (ChafaVec3f32)); /* Calculate average */ chafa_vec3f32_average_array (&average, v, n_vecs); /* Recenter around average */ chafa_vec3f32_set_zero (&t); chafa_vec3f32_sub (&t, &t, &average); chafa_vec3f32_add_to_array (v, &t, n_vecs); /* Compute principal components */ for (i = 0; ; ) { eigenvalue = pca_converge (v, n_vecs, &t); if (eigenvectors_out) { chafa_vec3f32_copy (eigenvectors_out, &t); eigenvectors_out++; } if (eigenvalues_out) { *eigenvalues_out = eigenvalue; eigenvalues_out++; } if (++i >= n_components) break; pca_deflate (v, n_vecs, &t); } if (average_out) chafa_vec3f32_copy (average_out, &average); g_free (v); } chafa-1.18.2/chafa/internal/chafa-pca.h000066400000000000000000000025101517447374300175140ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PCA_H__ #define __CHAFA_PCA_H__ #include #include "internal/chafa-vector.h" G_BEGIN_DECLS void chafa_vec3f32_array_compute_pca (const ChafaVec3f32 *vecs_in, gint n_vecs, gint n_components, ChafaVec3f32 *eigenvectors_out, gfloat *eigenvalues_out, ChafaVec3f32 *average_out); G_END_DECLS #endif /* __CHAFA_PCA_H__ */ chafa-1.18.2/chafa/internal/chafa-pixops.c000066400000000000000000000726141517447374300203020ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "internal/chafa-batch.h" #include "internal/chafa-pixops.h" #include "internal/chafa-math-util.h" #include "internal/smolscale/smolscale.h" /* Fixed point multiplier */ #define FIXED_MULT 4096 /* See rgb_to_intensity_fast () */ #define INTENSITY_MAX (256 * 8) /* Normalization: Percentage of pixels to discard at extremes of histogram */ #define INDEXED_16_CROP_PCT 5 #define INDEXED_8_CROP_PCT 10 #define INDEXED_2_CROP_PCT 20 #if 0 /* Disabled because static asserts aren't in C99 */ /* Ensure there's no overflow in normalize_ch() */ G_STATIC_ASSERT (FIXED_MULT * INTENSITY_MAX * (gint64) 255 <= G_MAXINT); G_STATIC_ASSERT (FIXED_MULT * INTENSITY_MAX * (gint64) -255 >= G_MININT); #endif typedef struct { gint32 c [INTENSITY_MAX]; /* Transparent pixels are not sampled, so we must keep count */ gint n_samples; /* Lower and upper bounds */ gint32 min, max; } Histogram; typedef struct { ChafaPixelType src_pixel_type; gconstpointer src_pixels; gint src_width, src_height; gint src_rowstride; ChafaPixel *dest_pixels; gint dest_width, dest_height; const ChafaPalette *palette; const ChafaDither *dither; ChafaColorSpace color_space; gboolean preprocessing_enabled; gint work_factor_int; /* Cached to avoid repeatedly calling palette functions */ ChafaPaletteType palette_type; ChafaColor bg_color_rgb; /* Result of alpha detection is stored here */ gint have_alpha_int; Histogram hist; SmolScaleCtx *scale_ctx; } PrepareContext; typedef struct { Histogram hist; } PreparePixelsBatch1Ret; static gint rgb_to_intensity_fast (const ChafaColor *color) { /* Sum to 8x so we can divide by shifting later */ return color->ch [0] * 3 + color->ch [1] * 4 + color->ch [2]; } static void sum_histograms (const Histogram *hist_in, Histogram *hist_accum) { gint i; hist_accum->n_samples += hist_in->n_samples; for (i = 0; i < INTENSITY_MAX; i++) { hist_accum->c [i] += hist_in->c [i]; } } static void histogram_calc_bounds (Histogram *hist, gint crop_pct) { gint64 pixels_crop; gint i; gint t; pixels_crop = (hist->n_samples * (((gint64) crop_pct * 1024) / 100)) / 1024; /* Find lower bound */ for (i = 0, t = pixels_crop; i < INTENSITY_MAX; i++) { t -= hist->c [i]; if (t <= 0) break; } hist->min = i; /* Find upper bound */ for (i = INTENSITY_MAX - 1, t = pixels_crop; i >= 0; i--) { t -= hist->c [i]; if (t <= 0) break; } hist->max = i; } static gint16 normalize_ch (guint8 v, gint min, gint factor) { gint vt = v; vt -= min; vt *= factor; vt /= FIXED_MULT; vt = CLAMP (vt, 0, 255); return vt; } static void normalize_rgb (ChafaPixel *pixels, const Histogram *hist, gint width, gint dest_y, gint n_rows) { ChafaPixel *p0, *p1; gint factor; /* Make sure range is more or less sane */ if (hist->min == hist->max) return; #if 0 if (min > 512) min = 512; if (max < 1536) max = 1536; #endif /* Adjust intensities */ factor = ((INTENSITY_MAX - 1) * FIXED_MULT) / (hist->max - hist->min); #if 0 g_printerr ("[%d-%d] * %d, crop=%d \n", min, max, factor, pixels_crop); #endif p0 = pixels + dest_y * width; p1 = p0 + n_rows * width; for ( ; p0 < p1; p0++) { p0->col.ch [0] = normalize_ch (p0->col.ch [0], hist->min / 8, factor); p0->col.ch [1] = normalize_ch (p0->col.ch [1], hist->min / 8, factor); p0->col.ch [2] = normalize_ch (p0->col.ch [2], hist->min / 8, factor); } } static void boost_saturation_rgb (ChafaColor *col) { gint ch [3]; gfloat P = sqrtf (col->ch [0] * (gfloat) col->ch [0] * .299f + col->ch [1] * (gfloat) col->ch [1] * .587f + col->ch [2] * (gfloat) col->ch [2] * .144f); ch [0] = P + ((gfloat) col->ch [0] - P) * 2; ch [1] = P + ((gfloat) col->ch [1] - P) * 2; ch [2] = P + ((gfloat) col->ch [2] - P) * 2; col->ch [0] = CLAMP (ch [0], 0, 255); col->ch [1] = CLAMP (ch [1], 0, 255); col->ch [2] = CLAMP (ch [2], 0, 255); } /* pixel must point to top-left pixel of the grain to be dithered */ static void fs_dither_grain (const ChafaDither *dither, const ChafaPalette *palette, ChafaColorSpace color_space, ChafaPixel *pixel, gint image_width, const ChafaColorAccum *error_in, ChafaColorAccum *error_out_0, ChafaColorAccum *error_out_1, ChafaColorAccum *error_out_2, ChafaColorAccum *error_out_3) { gint grain_width = 1 << dither->grain_width_shift; gint grain_height = 1 << dither->grain_height_shift; gint grain_shift = dither->grain_width_shift + dither->grain_height_shift; ChafaColorAccum next_error = { 0 }; ChafaColorAccum accum = { 0 }; ChafaPixel *p; ChafaColor acol; const ChafaColor *col; gint index; gint x, y, i; p = pixel; for (y = 0; y < grain_height; y++) { for (x = 0; x < grain_width; x++, p++) { for (i = 0; i < 3; i++) { gint16 ch = p->col.ch [i]; ch += error_in->ch [i]; if (ch < 0) { next_error.ch [i] += ch; ch = 0; } else if (ch > 255) { next_error.ch [i] += ch - 255; ch = 255; } p->col.ch [i] = ch; accum.ch [i] += ch; } } p += image_width - grain_width; } for (i = 0; i < 3; i++) { accum.ch [i] >>= grain_shift; acol.ch [i] = accum.ch [i]; } /* Don't try to dither alpha */ acol.ch [3] = 0xff; index = chafa_palette_lookup_nearest (palette, color_space, &acol, NULL); col = chafa_palette_get_color (palette, color_space, index); for (i = 0; i < 3; i++) { /* FIXME: Floating point op is slow. Factor this out and make * dither_intensity == 1.0 the fast path. */ next_error.ch [i] = ((next_error.ch [i] >> grain_shift) + (accum.ch [i] - (gint16) col->ch [i]) * dither->intensity); error_out_0->ch [i] += next_error.ch [i] * 7 / 16; error_out_1->ch [i] += next_error.ch [i] * 1 / 16; error_out_2->ch [i] += next_error.ch [i] * 5 / 16; error_out_3->ch [i] += next_error.ch [i] * 3 / 16; } } static void convert_rgb_to_din99d (ChafaPixel *pixels, gint width, gint dest_y, gint n_rows) { ChafaPixel *pixel = pixels + dest_y * width; ChafaPixel *pixel_max = pixel + n_rows * width; /* RGB -> DIN99d */ for ( ; pixel < pixel_max; pixel++) { chafa_color_rgb_to_din99d (&pixel->col, &pixel->col); } } static void simple_dither (const ChafaDither *dither, ChafaPixel *pixels, gint width, gint dest_y, gint n_rows) { ChafaPixel *pixel = pixels + dest_y * width; ChafaPixel *pixel_max = pixel + n_rows * width; gint x, y; for (y = dest_y; pixel < pixel_max; y++) { for (x = 0; x < width; x++) { pixel->col = chafa_dither_color (dither, pixel->col, x, y); pixel++; } } } static void fs_dither (const ChafaDither *dither, const ChafaPalette *palette, ChafaColorSpace color_space, ChafaPixel *pixels, gint width, gint dest_y, gint n_rows) { ChafaPixel *pixel; ChafaColorAccum *error_rows; ChafaColorAccum *error_row [2]; ChafaColorAccum *pp; gint grain_width = 1 << dither->grain_width_shift; gint grain_height = 1 << dither->grain_height_shift; gint width_grains = width >> dither->grain_width_shift; gsize alloc_grains = ((gsize) width_grains + 2) * 2; gint x, y; g_assert (width % grain_width == 0); g_assert (dest_y % grain_height == 0); g_assert (n_rows % grain_height == 0); dest_y >>= dither->grain_height_shift; n_rows >>= dither->grain_height_shift; /* Allocate one extra ChafaColorAccum on each side of each row so the * boundary writes have somewhere harmless to land, and the reads * that immediately follow a freshly-zeroed row still see a defined * value. * * Layout (X = padding): * [ X | error_row [0] .. [width_grains] | X * X | error_row [1] .. [width_grains] | X ] * * The trailing padding of row 0 and the leading padding of row 1 are * distinct. */ error_rows = g_malloc (alloc_grains * sizeof (ChafaColorAccum)); error_row [0] = error_rows + 1; error_row [1] = error_rows + (width_grains + 2) + 1; memset (error_rows, 0, alloc_grains * sizeof (ChafaColorAccum)); for (y = dest_y; y < dest_y + n_rows; y++) { memset (error_row [1] - 1, 0, (gsize) (width_grains + 2) * sizeof (ChafaColorAccum)); if (!(y & 1)) { /* --- Forwards pass --- */ pixel = pixels + (y << dither->grain_height_shift) * width; /* Leftmost */ fs_dither_grain (dither, palette, color_space, pixel, width, error_row [0], error_row [0] + 1, error_row [1] + 1, error_row [1], error_row [1] + 1); if (width_grains >= 2) { pixel += grain_width; for (x = 1; ((x + 1) << dither->grain_width_shift) < width; x++) { fs_dither_grain (dither, palette, color_space, pixel, width, error_row [0] + x, error_row [0] + x + 1, error_row [1] + x + 1, error_row [1] + x, error_row [1] + x - 1); pixel += grain_width; } /* Rightmost */ fs_dither_grain (dither, palette, color_space, pixel, width, error_row [0] + x, error_row [1] + x, error_row [1] + x, error_row [1] + x - 1, error_row [1] + x - 1); } } else { /* --- Backwards pass --- */ if (width_grains >= 2) { pixel = pixels + (y << dither->grain_height_shift) * width + width - grain_width; /* Rightmost */ fs_dither_grain (dither, palette, color_space, pixel, width, error_row [0] + width_grains - 1, error_row [0] + width_grains - 2, error_row [1] + width_grains - 2, error_row [1] + width_grains - 1, error_row [1] + width_grains - 2); pixel -= grain_width; for (x = width_grains - 2; x > 0; x--) { fs_dither_grain (dither, palette, color_space, pixel, width, error_row [0] + x, error_row [0] + x - 1, error_row [1] + x - 1, error_row [1] + x, error_row [1] + x + 1); pixel -= grain_width; } } else { pixel = pixels + (y << dither->grain_height_shift) * width; } /* Leftmost */ fs_dither_grain (dither, palette, color_space, pixel, width, error_row [0], error_row [1], error_row [1], error_row [1] + 1, error_row [1] + 1); } pp = error_row [0]; error_row [0] = error_row [1]; error_row [1] = pp; } g_free (error_rows); } static void dither_and_convert_rgb_to_din99d (const ChafaDither *dither, ChafaPixel *pixels, gint width, gint dest_y, gint n_rows) { ChafaPixel *pixel = pixels + dest_y * width; ChafaPixel *pixel_max = pixel + n_rows * width; gint x, y; for (y = dest_y; pixel < pixel_max; y++) { for (x = 0; x < width; x++) { pixel->col = chafa_dither_color (dither, pixel->col, x, y); chafa_color_rgb_to_din99d (&pixel->col, &pixel->col); pixel++; } } } static void fs_and_convert_rgb_to_din99d (const ChafaDither *dither, const ChafaPalette *palette, ChafaPixel *pixels, gint width, gint dest_y, gint n_rows) { convert_rgb_to_din99d (pixels, width, dest_y, n_rows); fs_dither (dither, palette, CHAFA_COLOR_SPACE_DIN99D, pixels, width, dest_y, n_rows); } static void prepare_pixels_1_inner (PreparePixelsBatch1Ret *ret, PrepareContext *prep_ctx, const guint8 *data_p, ChafaPixel *pixel_out, gint *alpha_sum) { ChafaColor *col = &pixel_out->col; col->ch [0] = data_p [0]; col->ch [1] = data_p [1]; col->ch [2] = data_p [2]; col->ch [3] = data_p [3]; *alpha_sum += (0xff - col->ch [3]); if (prep_ctx->preprocessing_enabled && (prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_16 || prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_8) ) { boost_saturation_rgb (col); } /* Build histogram */ if (col->ch [3] > 127) { gint v = rgb_to_intensity_fast (col); ret->hist.c [v]++; ret->hist.n_samples++; } } static void prepare_pixels_1_worker_nearest (ChafaBatchInfo *batch, PrepareContext *prep_ctx) { ChafaPixel *pixel; gint dest_y; gint px, py; gint x_inc, y_inc; gint alpha_sum = 0; const guint8 *data; gint n_rows; gint rowstride; PreparePixelsBatch1Ret *ret; ret = g_new0 (PreparePixelsBatch1Ret, 1); batch->ret_p = ret; dest_y = batch->first_row; data = prep_ctx->src_pixels; n_rows = batch->n_rows; rowstride = prep_ctx->src_rowstride; x_inc = (prep_ctx->src_width * FIXED_MULT) / (prep_ctx->dest_width); y_inc = (prep_ctx->src_height * FIXED_MULT) / (prep_ctx->dest_height); pixel = prep_ctx->dest_pixels + dest_y * prep_ctx->dest_width; for (py = dest_y; py < dest_y + n_rows; py++) { const guint8 *data_row_p; data_row_p = data + ((py * y_inc) / FIXED_MULT) * rowstride; for (px = 0; px < prep_ctx->dest_width; px++) { const guint8 *data_p = data_row_p + ((px * x_inc) / FIXED_MULT) * 4; prepare_pixels_1_inner (ret, prep_ctx, data_p, pixel++, &alpha_sum); } } if (alpha_sum > 0) g_atomic_int_set (&prep_ctx->have_alpha_int, 1); } static void prepare_pixels_1_worker_smooth (ChafaBatchInfo *batch, PrepareContext *prep_ctx) { ChafaPixel *pixel, *pixel_max; gint alpha_sum = 0; guint8 *scaled_data; const guint8 *data_p; PreparePixelsBatch1Ret *ret; ret = g_new0 (PreparePixelsBatch1Ret, 1); batch->ret_p = ret; scaled_data = g_malloc ((gsize) prep_ctx->dest_width * batch->n_rows * sizeof (guint32)); smol_scale_batch_full (prep_ctx->scale_ctx, scaled_data, batch->first_row, batch->n_rows); data_p = scaled_data; pixel = prep_ctx->dest_pixels + (gsize) batch->first_row * prep_ctx->dest_width; pixel_max = pixel + batch->n_rows * (gsize) prep_ctx->dest_width; while (pixel < pixel_max) { prepare_pixels_1_inner (ret, prep_ctx, data_p, pixel++, &alpha_sum); data_p += 4; } g_free (scaled_data); if (alpha_sum > 0) g_atomic_int_set (&prep_ctx->have_alpha_int, 1); } static void pass_1_post (ChafaBatchInfo *batch, PrepareContext *prep_ctx) { PreparePixelsBatch1Ret *ret = batch->ret_p; if (prep_ctx->preprocessing_enabled) { sum_histograms (&ret->hist, &prep_ctx->hist); } g_free (ret); } static void prepare_pixels_pass_1 (PrepareContext *prep_ctx) { GFunc batch_func; /* First pass * ---------- * * - Scale and convert pixel format * - Apply local preprocessing like saturation boost (optional) * - Generate histogram for later passes (e.g. for normalization) * - Figure out if we have alpha transparency */ batch_func = (GFunc) ((prep_ctx->work_factor_int < 3 && prep_ctx->src_pixel_type == CHAFA_PIXEL_RGBA8_UNASSOCIATED) ? prepare_pixels_1_worker_nearest : prepare_pixels_1_worker_smooth); chafa_process_batches (prep_ctx, (GFunc) batch_func, (GFunc) pass_1_post, prep_ctx->dest_height, chafa_get_n_actual_threads (), 1); /* Generate final histogram */ if (prep_ctx->preprocessing_enabled) { switch (prep_ctx->palette_type) { case CHAFA_PALETTE_TYPE_FIXED_16: histogram_calc_bounds (&prep_ctx->hist, INDEXED_16_CROP_PCT); break; case CHAFA_PALETTE_TYPE_FIXED_8: histogram_calc_bounds (&prep_ctx->hist, INDEXED_8_CROP_PCT); break; default: histogram_calc_bounds (&prep_ctx->hist, INDEXED_2_CROP_PCT); break; } } } static void composite_alpha_on_bg (ChafaColor bg_color, ChafaPixel *pixels, gint width, gint first_row, gint n_rows) { ChafaPixel *p0, *p1; p0 = pixels + (gsize) first_row * width; p1 = p0 + (gsize) n_rows * width; /* FIXME: This is slow and bad. We should fix it with a new Smolscale * compositing mode. */ for ( ; p0 < p1; p0++) { p0->col.ch [0] = (p0->col.ch [0] * (guint32) p0->col.ch [3] + bg_color.ch [0] * (255 - (guint32) p0->col.ch [3])) / 255; p0->col.ch [1] = (p0->col.ch [1] * (guint32) p0->col.ch [3] + bg_color.ch [1] * (255 - (guint32) p0->col.ch [3])) / 255; p0->col.ch [2] = (p0->col.ch [2] * (guint32) p0->col.ch [3] + bg_color.ch [2] * (255 - (guint32) p0->col.ch [3])) / 255; } } static void prepare_pixels_2_worker (ChafaBatchInfo *batch, PrepareContext *prep_ctx) { if (prep_ctx->preprocessing_enabled && (prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_16 || prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_8 || prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_FGBG)) normalize_rgb (prep_ctx->dest_pixels, &prep_ctx->hist, prep_ctx->dest_width, batch->first_row, batch->n_rows); if (prep_ctx->have_alpha_int) composite_alpha_on_bg (prep_ctx->bg_color_rgb, prep_ctx->dest_pixels, prep_ctx->dest_width, batch->first_row, batch->n_rows); if (prep_ctx->color_space == CHAFA_COLOR_SPACE_DIN99D) { if (prep_ctx->dither->mode == CHAFA_DITHER_MODE_ORDERED || prep_ctx->dither->mode == CHAFA_DITHER_MODE_NOISE) { dither_and_convert_rgb_to_din99d (prep_ctx->dither, prep_ctx->dest_pixels, prep_ctx->dest_width, batch->first_row, batch->n_rows); } else if (prep_ctx->dither->mode == CHAFA_DITHER_MODE_DIFFUSION) { fs_and_convert_rgb_to_din99d (prep_ctx->dither, prep_ctx->palette, prep_ctx->dest_pixels, prep_ctx->dest_width, batch->first_row, batch->n_rows); } else { convert_rgb_to_din99d (prep_ctx->dest_pixels, prep_ctx->dest_width, batch->first_row, batch->n_rows); } } else if (prep_ctx->dither->mode == CHAFA_DITHER_MODE_ORDERED || prep_ctx->dither->mode == CHAFA_DITHER_MODE_NOISE) { simple_dither (prep_ctx->dither, prep_ctx->dest_pixels, prep_ctx->dest_width, batch->first_row, batch->n_rows); } else if (prep_ctx->dither->mode == CHAFA_DITHER_MODE_DIFFUSION) { fs_dither (prep_ctx->dither, prep_ctx->palette, prep_ctx->color_space, prep_ctx->dest_pixels, prep_ctx->dest_width, batch->first_row, batch->n_rows); } } static gboolean need_pass_2 (PrepareContext *prep_ctx) { if ((prep_ctx->preprocessing_enabled && (prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_16 || prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_8 || prep_ctx->palette_type == CHAFA_PALETTE_TYPE_FIXED_FGBG)) || prep_ctx->have_alpha_int || prep_ctx->color_space == CHAFA_COLOR_SPACE_DIN99D || prep_ctx->dither->mode != CHAFA_DITHER_MODE_NONE) return TRUE; return FALSE; } static void prepare_pixels_pass_2 (PrepareContext *prep_ctx) { gint n_batches; gint batch_unit = 1; /* Second pass * ----------- * * - Normalization (optional) * - Dithering (optional) * - Color space conversion; DIN99d (optional) */ if (!need_pass_2 (prep_ctx)) return; n_batches = chafa_get_n_actual_threads (); /* Floyd-Steinberg diffusion needs the batch size to be a multiple of the * grain height. It also needs to run in a single thread to propagate the * quantization error correctly. */ if (prep_ctx->dither->mode == CHAFA_DITHER_MODE_DIFFUSION) { n_batches = 1; batch_unit = 1 << prep_ctx->dither->grain_height_shift; } chafa_process_batches (prep_ctx, (GFunc) prepare_pixels_2_worker, NULL, /* _post */ prep_ctx->dest_height, n_batches, batch_unit); } void chafa_prepare_pixel_data_for_symbols (const ChafaPalette *palette, const ChafaDither *dither, ChafaColorSpace color_space, gboolean preprocessing_enabled, gint work_factor, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaPixel *dest_pixels, gint dest_width, gint dest_height, gint cell_width, gint cell_height, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck) { PrepareContext prep_ctx = { 0 }; gint placement_x, placement_y; gint placement_width, placement_height; /* Convert the destination dimensions from symbol matrix geometry to real * geometry (just for the calculation) for correct image sizing. */ chafa_tuck_and_align (src_width, src_height, (dest_width / CHAFA_SYMBOL_WIDTH_PIXELS) * cell_width, (dest_height / CHAFA_SYMBOL_HEIGHT_PIXELS) * cell_height, halign, valign, tuck, &placement_x, &placement_y, &placement_width, &placement_height); /* Rounding the placement edges to cell boundaries prevents artifacts * in the first/last row/col containing the actual image, * when tuck == FIT or SHRINK_TO_FIT. */ /* First image row/col rounds *down* to the nearest cell boundary. */ placement_x -= placement_x % cell_width; placement_y -= placement_y % cell_height; /* Last image row/col rounds *up* to the nearest cell boundary. * * Note: If the left/top edge is on a cell boundary (which it already is), * and the width/height is a multiple of the cell width/height, * then the right/bottom edge is also on a cell boundary. */ placement_width = chafa_round_up_to_multiple_of (placement_width, cell_width); placement_height = chafa_round_up_to_multiple_of (placement_height, cell_height); /* Convert the placement dimensions from real geometry to symbol matrix geometry. */ placement_x = (placement_x / cell_width) * CHAFA_SYMBOL_WIDTH_PIXELS, placement_y = (placement_y / cell_height) * CHAFA_SYMBOL_HEIGHT_PIXELS, placement_width = (placement_width / cell_width) * CHAFA_SYMBOL_WIDTH_PIXELS, placement_height = (placement_height / cell_height) * CHAFA_SYMBOL_HEIGHT_PIXELS, prep_ctx.palette = palette; prep_ctx.dither = dither; prep_ctx.color_space = color_space; prep_ctx.preprocessing_enabled = preprocessing_enabled; prep_ctx.work_factor_int = work_factor; prep_ctx.palette_type = chafa_palette_get_type (palette); prep_ctx.bg_color_rgb = *chafa_palette_get_color (palette, CHAFA_COLOR_SPACE_RGB, CHAFA_PALETTE_INDEX_BG); prep_ctx.src_pixel_type = src_pixel_type; prep_ctx.src_pixels = src_pixels; prep_ctx.src_width = src_width; prep_ctx.src_height = src_height; prep_ctx.src_rowstride = src_rowstride; prep_ctx.dest_pixels = dest_pixels; prep_ctx.dest_width = dest_width; prep_ctx.dest_height = dest_height; prep_ctx.scale_ctx = smol_scale_new_full (/* Source */ prep_ctx.src_pixels, (SmolPixelType) prep_ctx.src_pixel_type, prep_ctx.src_width, prep_ctx.src_height, prep_ctx.src_rowstride, /* Fill */ NULL, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* Destination */ NULL, SMOL_PIXEL_RGBA8_UNASSOCIATED, /* FIXME: Premul */ prep_ctx.dest_width, prep_ctx.dest_height, prep_ctx.dest_width * sizeof (guint32), /* Placement */ placement_x * SMOL_SUBPIXEL_MUL, placement_y * SMOL_SUBPIXEL_MUL, placement_width * SMOL_SUBPIXEL_MUL, placement_height * SMOL_SUBPIXEL_MUL, /* Extra args */ SMOL_COMPOSITE_SRC_CLEAR_DEST, SMOL_NO_FLAGS, NULL, &prep_ctx); prepare_pixels_pass_1 (&prep_ctx); prepare_pixels_pass_2 (&prep_ctx); smol_scale_destroy (prep_ctx.scale_ctx); } void chafa_sort_pixel_index_by_channel (guint8 *index, const ChafaPixel *pixels, gint n_pixels, gint ch) { guint8 buckets [256] [64]; guint8 bucket_size [256] = { 0 }; gint i, j, k; g_assert (n_pixels <= 64); for (i = 0; i < n_pixels; i++) { guint8 bucket = pixels [i].col.ch [ch]; buckets [bucket] [bucket_size [bucket]++] = i; } for (i = 0, k = 0; i < 256; i++) { for (j = 0; j < bucket_size [i]; j++) index [k++] = buckets [i] [j]; } } chafa-1.18.2/chafa/internal/chafa-pixops.h000066400000000000000000000045161517447374300203030ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2020-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PIXOPS_H__ #define __CHAFA_PIXOPS_H__ #include #include "internal/chafa-private.h" G_BEGIN_DECLS void chafa_prepare_pixel_data_for_symbols (const ChafaPalette *palette, const ChafaDither *dither, ChafaColorSpace color_space, gboolean preprocessing_enabled, gint work_factor, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaPixel *dest_pixels, gint dest_width, gint dest_height, gint cell_width, gint cell_height, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck); void chafa_sort_pixel_index_by_channel (guint8 *index, const ChafaPixel *pixels, gint n_pixels, gint ch); G_END_DECLS #endif /* __CHAFA_PIXOPS_H__ */ chafa-1.18.2/chafa/internal/chafa-popcnt.c000066400000000000000000000066001517447374300202530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chafa.h" #include "internal/chafa-private.h" gint chafa_pop_count_u64_builtin (guint64 v) { #if defined(HAVE_POPCNT64_INTRINSICS) return (gint) _mm_popcnt_u64 (v); #else /* HAVE_POPCNT32_INTRINSICS */ const guint32 *w = (const guint32 *) &v; return (gint) _mm_popcnt_u32(w[0]) + _mm_popcnt_u32(w[1]); #endif } void chafa_pop_count_vu64_builtin (const guint64 *vv, gint *vc, gint n) { while (n--) { #if defined(HAVE_POPCNT64_INTRINSICS) *(vc++) = _mm_popcnt_u64 (*(vv++)); #else /* HAVE_POPCNT32_INTRINSICS */ const guint32 *w = (const guint32 *)vv; *(vc++) = _mm_popcnt_u32(w[0]) + _mm_popcnt_u32(w[1]); vv++; #endif } } void chafa_hamming_distance_vu64_builtin (guint64 a, const guint64 *vb, gint *vc, gint n) { #if defined(HAVE_POPCNT64_INTRINSICS) while (n >= 4) { n -= 4; *(vc++) = _mm_popcnt_u64 (a ^ *(vb++)); *(vc++) = _mm_popcnt_u64 (a ^ *(vb++)); *(vc++) = _mm_popcnt_u64 (a ^ *(vb++)); *(vc++) = _mm_popcnt_u64 (a ^ *(vb++)); } while (n--) { *(vc++) = _mm_popcnt_u64 (a ^ *(vb++)); } #else /* HAVE_POPCNT32_INTRINSICS */ const guint32 *aa = (const guint32 *) &a; const guint32 *wb = (const guint32 *) vb; while (n--) { *(vc++) = _mm_popcnt_u32 (aa [0] ^ wb [0]) + _mm_popcnt_u32 (aa [1] ^ wb [1]); wb += 2; } #endif } /* Two bitmaps per item (a points to a pair, vb points to array of pairs) */ void chafa_hamming_distance_2_vu64_builtin (const guint64 *a, const guint64 *vb, gint *vc, gint n) { #if defined(HAVE_POPCNT64_INTRINSICS) while (n >= 4) { n -= 4; *vc = _mm_popcnt_u64 (a [0] ^ *(vb++)); *(vc++) += _mm_popcnt_u64 (a [1] ^ *(vb++)); *vc = _mm_popcnt_u64 (a [0] ^ *(vb++)); *(vc++) += _mm_popcnt_u64 (a [1] ^ *(vb++)); *vc = _mm_popcnt_u64 (a [0] ^ *(vb++)); *(vc++) += _mm_popcnt_u64 (a [1] ^ *(vb++)); *vc = _mm_popcnt_u64 (a [0] ^ *(vb++)); *(vc++) += _mm_popcnt_u64 (a [1] ^ *(vb++)); } while (n--) { *vc = _mm_popcnt_u64 (a [0] ^ *(vb++)); *(vc++) += _mm_popcnt_u64 (a [1] ^ *(vb++)); } #else /* HAVE_POPCNT32_INTRINSICS */ const guint32 *aa = (const guint32 *) a; const guint32 *wb = (const guint32 *) vb; while (n--) { *(vc++) = _mm_popcnt_u32 (aa [0] ^ wb [0]) + _mm_popcnt_u32 (aa [1] ^ wb [1]) + _mm_popcnt_u32 (aa [2] ^ wb [2]) + _mm_popcnt_u32 (aa [3] ^ wb [3]); wb += 4; } #endif } chafa-1.18.2/chafa/internal/chafa-private.h000066400000000000000000000225571517447374300204400ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PRIVATE_H__ #define __CHAFA_PRIVATE_H__ #include #include "internal/chafa-bitfield.h" #include "internal/chafa-color-hash.h" #include "internal/chafa-dither.h" #include "internal/chafa-indexed-image.h" #include "internal/chafa-iterm2-canvas.h" #include "internal/chafa-kitty-canvas.h" #include "internal/chafa-math-util.h" #include "internal/chafa-noise.h" #include "internal/chafa-palette.h" #include "internal/chafa-sixel-canvas.h" G_BEGIN_DECLS /* Character symbols and symbol classes */ #define CHAFA_N_SYMBOLS_MAX 2048 /* For static temp arrays */ #define CHAFA_SYMBOL_N_PIXELS (CHAFA_SYMBOL_WIDTH_PIXELS * CHAFA_SYMBOL_HEIGHT_PIXELS) typedef struct { ChafaSymbolTags sc; gunichar c; gchar *coverage; guint32 *mask_u32; gint fg_weight, bg_weight; guint64 bitmap; gint popcount; } ChafaSymbol; /* Double-width symbol */ typedef struct { ChafaSymbol sym [2]; } ChafaSymbol2; struct ChafaSymbolMap { gint refs; guint need_rebuild : 1; guint use_builtin_glyphs : 1; GHashTable *glyphs; GHashTable *glyphs2; /* Wide glyphs with left/right bitmaps */ GArray *selectors; /* Remaining fields are populated by chafa_symbol_map_prepare () */ /* Narrow symbols */ ChafaSymbol *symbols; gint n_symbols; guint64 *packed_bitmaps; /* Wide symbols */ ChafaSymbol2 *symbols2; gint n_symbols2; guint64 *packed_bitmaps2; }; /* Symbol selection candidate */ typedef struct { gint symbol_index; guint8 hamming_distance; guint8 is_inverted; } ChafaCandidate; /* Canvas config */ struct ChafaCanvasConfig { gint refs; gint width, height; gint cell_width, cell_height; ChafaCanvasMode canvas_mode; ChafaColorSpace color_space; ChafaDitherMode dither_mode; ChafaColorExtractor color_extractor; ChafaPixelMode pixel_mode; gint dither_grain_width, dither_grain_height; gfloat dither_intensity; guint32 fg_color_packed_rgb; guint32 bg_color_packed_rgb; gint alpha_threshold; /* 0-255. 255 = no alpha in output */ gfloat work_factor; ChafaSymbolMap symbol_map; ChafaSymbolMap fill_symbol_map; guint preprocessing_enabled : 1; guint fg_only_enabled : 1; ChafaOptimizations optimizations; ChafaPassthrough passthrough; }; /* Frame */ struct ChafaFrame { gint refs; ChafaPixelType pixel_type; gint width, height, rowstride; gpointer data; guint data_is_owned : 1; }; /* Image */ struct ChafaImage { gint refs; ChafaFrame *frame; }; /* Placement */ struct ChafaPlacement { gint refs; ChafaImage *image; gint id; ChafaAlign halign, valign; ChafaTuck tuck; }; /* Canvas */ typedef struct ChafaCanvasCell ChafaCanvasCell; /* Library functions */ extern ChafaSymbol *chafa_symbols; extern ChafaSymbol2 *chafa_symbols2; void chafa_init_palette (void); void chafa_init_symbols (void); ChafaSymbolTags chafa_get_tags_for_char (gunichar c); void chafa_init (void); gboolean chafa_have_mmx (void) G_GNUC_PURE; gboolean chafa_have_sse41 (void) G_GNUC_PURE; gboolean chafa_have_popcnt (void) G_GNUC_PURE; gboolean chafa_have_avx2 (void) G_GNUC_PURE; void chafa_symbol_map_init (ChafaSymbolMap *symbol_map); void chafa_symbol_map_deinit (ChafaSymbolMap *symbol_map); void chafa_symbol_map_copy_contents (ChafaSymbolMap *dest, const ChafaSymbolMap *src); void chafa_symbol_map_prepare (ChafaSymbolMap *symbol_map); gboolean chafa_symbol_map_has_symbol (const ChafaSymbolMap *symbol_map, gunichar symbol); void chafa_symbol_map_find_candidates (const ChafaSymbolMap *symbol_map, guint64 bitmap, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout); void chafa_symbol_map_find_fill_candidates (const ChafaSymbolMap *symbol_map, gint popcount, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout); void chafa_symbol_map_find_wide_candidates (const ChafaSymbolMap *symbol_map, const guint64 *bitmaps, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout); void chafa_symbol_map_find_wide_fill_candidates (const ChafaSymbolMap *symbol_map, gint popcount, gboolean do_inverse, ChafaCandidate *candidates_out, gint *n_candidates_inout); void chafa_canvas_config_init (ChafaCanvasConfig *canvas_config); void chafa_canvas_config_deinit (ChafaCanvasConfig *canvas_config); void chafa_canvas_config_copy_contents (ChafaCanvasConfig *dest, const ChafaCanvasConfig *src); gint *chafa_gen_bayer_matrix (gint matrix_size, gfloat magnitude); /* Math stuff */ #ifdef HAVE_MMX_INTRINSICS void chafa_extract_cell_mean_colors_mmx (const ChafaPixel *pixels, ChafaColorAccum *accums_out, const guint8 *cov); #endif #ifdef HAVE_SSE41_INTRINSICS gint chafa_calc_cell_error_sse41 (const ChafaPixel *pixels, const ChafaColorPair *color_pair, const guint8 *cov); #endif #ifdef HAVE_AVX2_INTRINSICS gint chafa_calc_cell_error_avx2 (const ChafaPixel *pixels, const ChafaColorPair *color_pair, const guint32 *sym_mask_u32); void chafa_extract_cell_mean_colors_avx2 (const ChafaPixel *pixels, ChafaColorAccum *accums_out, const guint32 *sym_mask_u32); void chafa_color_accum_div_scalar_avx2 (ChafaColorAccum *accum, guint16 divisor); #endif #if defined(HAVE_POPCNT64_INTRINSICS) || defined(HAVE_POPCNT32_INTRINSICS) #define HAVE_POPCNT_INTRINSICS #endif #ifdef HAVE_POPCNT_INTRINSICS gint chafa_pop_count_u64_builtin (guint64 v) G_GNUC_PURE; void chafa_pop_count_vu64_builtin (const guint64 *vv, gint *vc, gint n); void chafa_hamming_distance_vu64_builtin (guint64 a, const guint64 *vb, gint *vc, gint n); void chafa_hamming_distance_2_vu64_builtin (const guint64 *a, const guint64 *vb, gint *vc, gint n); #endif /* Inline functions */ static inline guint64 chafa_slow_pop_count (guint64 v) G_GNUC_UNUSED; static inline gint chafa_population_count_u64 (guint64 v) G_GNUC_UNUSED; static inline void chafa_population_count_vu64 (const guint64 *vv, gint *vc, gint n) G_GNUC_UNUSED; __attribute__ ((no_sanitize ("integer"))) static inline guint64 chafa_slow_pop_count (guint64 v) { /* Generic population count from * http://www.graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel * * Peter Kankowski has more hacks, including better SIMD versions, at * https://www.strchr.com/crc32_popcnt */ v = v - ((v >> 1) & (guint64) ~(guint64) 0 / 3); v = (v & (guint64) ~(guint64) 0 / 15 * 3) + ((v >> 2) & (guint64) ~(guint64) 0 / 15 * 3); v = (v + (v >> 4)) & (guint64) ~(guint64) 0 / 255 * 15; return (guint64) (v * ((guint64) ~(guint64) 0 / 255)) >> (sizeof (guint64) - 1) * 8; } static inline gint chafa_population_count_u64 (guint64 v) { #ifdef HAVE_POPCNT_INTRINSICS if (chafa_have_popcnt ()) return chafa_pop_count_u64_builtin (v); #endif return chafa_slow_pop_count (v); } static inline void chafa_population_count_vu64 (const guint64 *vv, gint *vc, gint n) { #ifdef HAVE_POPCNT_INTRINSICS if (chafa_have_popcnt ()) { chafa_pop_count_vu64_builtin (vv, vc, n); return; } #endif while (n--) *(vc++) = chafa_slow_pop_count (*(vv++)); } static inline void chafa_hamming_distance_vu64 (guint64 a, const guint64 *vb, gint *vc, gint n) { #ifdef HAVE_POPCNT_INTRINSICS if (chafa_have_popcnt ()) { chafa_hamming_distance_vu64_builtin (a, vb, vc, n); return; } #endif while (n--) *(vc++) = chafa_slow_pop_count (a ^ *(vb++)); } static inline void chafa_hamming_distance_2_vu64 (const guint64 *a, const guint64 *vb, gint *vc, gint n) { #ifdef HAVE_POPCNT_INTRINSICS if (chafa_have_popcnt ()) { chafa_hamming_distance_2_vu64_builtin (a, vb, vc, n); return; } #endif while (n--) { *(vc++) = chafa_slow_pop_count (a [0] ^ vb [0]) + chafa_slow_pop_count (a [1] ^ vb [1]); vb += 2; } } G_END_DECLS #endif /* __CHAFA_PRIVATE_H__ */ chafa-1.18.2/chafa/internal/chafa-sixel-canvas.c000066400000000000000000000353561517447374300213570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa.h" #include "smolscale/smolscale.h" #include "internal/chafa-batch.h" #include "internal/chafa-bitfield.h" #include "internal/chafa-indexed-image.h" #include "internal/chafa-math-util.h" #include "internal/chafa-passthrough-encoder.h" #include "internal/chafa-sixel-canvas.h" #include "internal/chafa-string-util.h" #define SIXEL_CELL_HEIGHT 6 typedef struct { ChafaSixelCanvas *sixel_canvas; ChafaPassthroughEncoder *ptenc; } BuildSixelsCtx; typedef struct { /* Lower six bytes are vertical pixel strip; LSB is bottom pixel */ guint64 d; } SixelData; typedef struct { SixelData *data; ChafaBitfield filter_bits; } SixelRow; ChafaSixelCanvas * chafa_sixel_canvas_new (gint width, gint height, ChafaColorSpace color_space, const ChafaPalette *palette, const ChafaDither *dither) { ChafaSixelCanvas *sixel_canvas; sixel_canvas = g_new (ChafaSixelCanvas, 1); sixel_canvas->width = width; sixel_canvas->height = height; sixel_canvas->color_space = color_space; sixel_canvas->image = chafa_indexed_image_new (width, chafa_round_up_to_multiple_of (height, SIXEL_CELL_HEIGHT), palette, dither); if (!sixel_canvas->image) { g_free (sixel_canvas); sixel_canvas = NULL; } return sixel_canvas; } void chafa_sixel_canvas_destroy (ChafaSixelCanvas *sixel_canvas) { chafa_indexed_image_destroy (sixel_canvas->image); g_free (sixel_canvas); } void chafa_sixel_canvas_draw_all_pixels (ChafaSixelCanvas *sixel_canvas, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck, gfloat quality) { g_return_if_fail (sixel_canvas != NULL); g_return_if_fail (src_pixel_type < CHAFA_PIXEL_MAX); g_return_if_fail (src_pixels != NULL); g_return_if_fail (src_width >= 0); g_return_if_fail (src_height >= 0); if (src_width == 0 || src_height == 0) return; chafa_indexed_image_draw_pixels (sixel_canvas->image, sixel_canvas->color_space, src_pixel_type, src_pixels, src_width, src_height, src_rowstride, sixel_canvas->width, sixel_canvas->height, halign, valign, tuck, quality); } #define FILTER_BANK_WIDTH 64 static void filter_set (SixelRow *srow, guint8 pen, gint bank) { chafa_bitfield_set_bit (&srow->filter_bits, bank * 256 + (gint) pen, TRUE); } static gboolean filter_get (const SixelRow *srow, guint8 pen, gint bank) { return chafa_bitfield_get_bit (&srow->filter_bits, bank * 256 + (gint) pen); } static void fetch_sixel_row (SixelRow *srow, const guint8 *pixels, gint width) { const guint8 *pixels_end, *p; SixelData *sdata = srow->data; gint x; /* The ordering of output bytes is 351240; this is the inverse of * 140325. see sixel_data_do_schar(). */ for (pixels_end = pixels + width, x = 0; pixels < pixels_end; pixels++, x++) { guint64 d; gint bank = x / FILTER_BANK_WIDTH; p = pixels; filter_set (srow, *p, bank); d = (guint64) *p; p += width; filter_set (srow, *p, bank); d |= (guint64) *p << (3 * 8); p += width; filter_set (srow, *p, bank); d |= (guint64) *p << (2 * 8); p += width; filter_set (srow, *p, bank); d |= (guint64) *p << (5 * 8); p += width; filter_set (srow, *p, bank); d |= (guint64) *p << (1 * 8); p += width; filter_set (srow, *p, bank); d |= (guint64) *p << (4 * 8); (sdata++)->d = d; } } static gchar sixel_data_to_schar (const SixelData *sdata, guint64 expanded_pen) { guint64 a; gchar c; a = ~(sdata->d ^ expanded_pen); /* Matching bytes will now contain 0xff. Any other value is a mismatch. */ a &= (a & 0x0000f0f0f0f0f0f0) >> 4; a &= (a & 0x00000c0c0c0c0c0c) >> 2; a &= (a & 0x0000020202020202) >> 1; /* Matching bytes will now contain 0x01. Misses contain 0x00. */ a |= a >> (24 - 1); a |= a >> (16 - 2); a |= a >> (8 - 4); /* Set bits are now packed in the lower 6 bits, reordered like this: * * 012345 -> 03/14/25 -> 14/0325 -> 140325 */ c = a & 0x3f; return '?' + c; } static gchar * format_schar_reps (gchar rep_schar, gint n_reps, gchar *p) { g_assert (n_reps > 0); for (;;) { if (n_reps < 4) { do *(p++) = rep_schar; while (--n_reps); goto out; } else if (n_reps < 255) { *(p++) = '!'; p = chafa_format_dec_u8 (p, n_reps); *(p++) = rep_schar; goto out; } else { strcpy (p, "!255"); p += 4; *(p++) = rep_schar; n_reps -= 255; if (n_reps == 0) goto out; } } out: return p; } static gchar * format_pen (guint8 pen, gchar *p) { *(p++) = '#'; return chafa_format_dec_u8 (p, pen); } /* force_full_width is a workaround for a bug in mlterm; we need to * draw the entire first row even if the rightmost pixels are transparent, * otherwise the first row with non-transparent pixels will have * garbage rendered in it */ static gchar * build_sixel_row_ansi (const ChafaSixelCanvas *scanvas, const SixelRow *srow, gchar *p, gboolean force_full_width) { gint pen = 0; gboolean need_cr = FALSE; gboolean need_cr_next = FALSE; const SixelData *sdata = srow->data; gint width = scanvas->width; do { guint64 expanded_pen; gboolean need_pen = TRUE; gchar rep_schar; gint n_reps; gint i; if (pen == chafa_palette_get_transparent_index (&scanvas->image->palette)) continue; /* Assign pen value to each of lower six bytes */ expanded_pen = pen; expanded_pen |= expanded_pen << 8; expanded_pen |= expanded_pen << 16; expanded_pen |= expanded_pen << 16; rep_schar = 0; n_reps = 0; for (i = 0; i < width; ) { gint step = MIN (FILTER_BANK_WIDTH, width - i); gchar schar; /* Skip over FILTER_BANK_WIDTH sixels at once if possible */ if (!filter_get (srow, pen, i / FILTER_BANK_WIDTH)) { if (rep_schar != '?' && rep_schar != 0) { if (need_cr) { *(p++) = '$'; need_cr = FALSE; } if (need_pen) { p = format_pen (pen, p); need_pen = FALSE; } p = format_schar_reps (rep_schar, n_reps, p); need_cr_next = TRUE; n_reps = 0; } rep_schar = '?'; n_reps += step; i += step; continue; } /* The pen appears in this bank; iterate over sixels */ for ( ; step > 0; step--, i++) { schar = sixel_data_to_schar (&sdata [i], expanded_pen); if (schar == rep_schar) { n_reps++; } else if (rep_schar == 0) { rep_schar = schar; n_reps = 1; } else { if (need_cr) { *(p++) = '$'; need_cr = FALSE; } if (need_pen) { p = format_pen (pen, p); need_pen = FALSE; } p = format_schar_reps (rep_schar, n_reps, p); need_cr_next = TRUE; rep_schar = schar; n_reps = 1; } } } if (rep_schar != '?' || force_full_width) { if (need_cr) { *(p++) = '$'; need_cr = FALSE; } if (need_pen) { p = format_pen (pen, p); need_pen = FALSE; } p = format_schar_reps (rep_schar, n_reps, p); need_cr_next = TRUE; /* Only need to do this for a single pen */ force_full_width = FALSE; } need_cr = need_cr_next; } while (++pen < chafa_palette_get_n_colors (&scanvas->image->palette)); return p; } static void build_sixel_row_worker (ChafaBatchInfo *batch, const BuildSixelsCtx *ctx) { SixelRow srow; gchar *sixel_ansi, *p; gint n_sixel_rows; gint i; n_sixel_rows = (batch->n_rows + SIXEL_CELL_HEIGHT - 1) / SIXEL_CELL_HEIGHT; srow.data = g_malloc (sizeof (SixelData) * (gsize) ctx->sixel_canvas->width); chafa_bitfield_init (&srow.filter_bits, ((ctx->sixel_canvas->width + FILTER_BANK_WIDTH - 1) / FILTER_BANK_WIDTH) * 256); sixel_ansi = p = g_malloc (256 * ((gsize) ctx->sixel_canvas->width + 5) * n_sixel_rows + 1); for (i = 0; i < n_sixel_rows; i++) { gboolean is_global_first_row = batch->first_row + i == 0; gboolean is_global_last_row = batch->first_row + (i + 1) * SIXEL_CELL_HEIGHT >= ctx->sixel_canvas->height; fetch_sixel_row (&srow, ctx->sixel_canvas->image->pixels + (gsize) ctx->sixel_canvas->image->width * (batch->first_row + i * SIXEL_CELL_HEIGHT), ctx->sixel_canvas->image->width); p = build_sixel_row_ansi (ctx->sixel_canvas, &srow, p, (is_global_first_row) || (is_global_last_row) ? TRUE : FALSE); chafa_bitfield_clear (&srow.filter_bits); /* GNL after every row except final */ if (!is_global_last_row) *(p++) = '-'; } batch->ret_p = sixel_ansi; batch->ret_n = p - sixel_ansi; chafa_bitfield_deinit (&srow.filter_bits); g_free (srow.data); } static void build_sixel_row_post (ChafaBatchInfo *batch, BuildSixelsCtx *ctx) { chafa_passthrough_encoder_append_len (ctx->ptenc, batch->ret_p, batch->ret_n); g_free (batch->ret_p); } static void build_sixel_palette (ChafaSixelCanvas *sixel_canvas, ChafaPassthroughEncoder *ptenc) { gchar str [256 * 20 + 1]; gchar *p = str; gint first_color; gint pen; first_color = chafa_palette_get_first_color (&sixel_canvas->image->palette); for (pen = 0; pen < chafa_palette_get_n_colors (&sixel_canvas->image->palette); pen++) { const ChafaColor *col; if (pen == chafa_palette_get_transparent_index (&sixel_canvas->image->palette)) continue; col = chafa_palette_get_color (&sixel_canvas->image->palette, CHAFA_COLOR_SPACE_RGB, first_color + pen); *(p++) = '#'; p = chafa_format_dec_u8 (p, pen); *(p++) = ';'; *(p++) = '2'; /* Color space: RGB */ *(p++) = ';'; /* Sixel color channel range is 0..100 */ p = chafa_format_dec_u8 (p, (col->ch [0] * 100) / 255); *(p++) = ';'; p = chafa_format_dec_u8 (p, (col->ch [1] * 100) / 255); *(p++) = ';'; p = chafa_format_dec_u8 (p, (col->ch [2] * 100) / 255); } chafa_passthrough_encoder_append_len (ptenc, str, p - str); } static void end_sixels (ChafaPassthroughEncoder *ptenc, ChafaTermInfo *term_info) { gchar buf [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; gint i; *chafa_term_info_emit_end_sixels (term_info, buf) = '\0'; if (ptenc->mode == CHAFA_PASSTHROUGH_SCREEN) { /* In GNU Screen, the end of an emitted sixel passthrough sequence should * look something like this: \e P \e \e \\ \e P \\ \e \\ */ for (i = 0; buf [i]; i++) { chafa_passthrough_encoder_flush (ptenc); chafa_passthrough_encoder_append_len (ptenc, buf + i, 1); } } else { chafa_passthrough_encoder_append (ptenc, buf); } chafa_passthrough_encoder_flush (ptenc); } void chafa_sixel_canvas_build_ansi (ChafaSixelCanvas *sixel_canvas, ChafaTermInfo *term_info, GString *str, ChafaPassthrough passthrough) { ChafaPassthroughEncoder ptenc; BuildSixelsCtx ctx; gchar buf [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; g_assert (sixel_canvas->image->height % SIXEL_CELL_HEIGHT == 0); chafa_passthrough_encoder_begin (&ptenc, passthrough, term_info, str); *chafa_term_info_emit_begin_sixels (term_info, buf, 0, 1, 0) = '\0'; chafa_passthrough_encoder_append (&ptenc, buf); g_snprintf (buf, CHAFA_TERM_SEQ_LENGTH_MAX, "\"1;1;%d;%d", sixel_canvas->width, sixel_canvas->height); chafa_passthrough_encoder_append (&ptenc, buf); ctx.sixel_canvas = sixel_canvas; ctx.ptenc = &ptenc; build_sixel_palette (sixel_canvas, &ptenc); chafa_process_batches (&ctx, (GFunc) build_sixel_row_worker, (GFunc) build_sixel_row_post, sixel_canvas->image->height, chafa_get_n_actual_threads (), SIXEL_CELL_HEIGHT); end_sixels (&ptenc, term_info); chafa_passthrough_encoder_end (&ptenc); } chafa-1.18.2/chafa/internal/chafa-sixel-canvas.h000066400000000000000000000041061517447374300213510ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_SIXEL_CANVAS_H__ #define __CHAFA_SIXEL_CANVAS_H__ #include "chafa.h" G_BEGIN_DECLS typedef struct { gint width, height; ChafaColorSpace color_space; ChafaIndexedImage *image; } ChafaSixelCanvas; ChafaSixelCanvas *chafa_sixel_canvas_new (gint width, gint height, ChafaColorSpace color_space, const ChafaPalette *palette, const ChafaDither *dither); void chafa_sixel_canvas_destroy (ChafaSixelCanvas *sixel_canvas); void chafa_sixel_canvas_draw_all_pixels (ChafaSixelCanvas *sixel_canvas, ChafaPixelType src_pixel_type, gconstpointer src_pixels, gint src_width, gint src_height, gint src_rowstride, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck, gfloat quality); void chafa_sixel_canvas_build_ansi (ChafaSixelCanvas *sixel_canvas, ChafaTermInfo *term_info, GString *out_str, ChafaPassthrough passthrough); G_END_DECLS #endif /* __CHAFA_SIXEL_CANVAS_H__ */ chafa-1.18.2/chafa/internal/chafa-sse41.c000066400000000000000000000033511517447374300177070ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chafa.h" #include "internal/chafa-private.h" gint chafa_calc_cell_error_sse41 (const ChafaPixel *pixels, const ChafaColorPair *color_pair, const guint8 *cov) { guint32 cpair_u32 [2]; __m128i err = { 0 }; gint i; cpair_u32 [0] = chafa_color8_to_u32 (color_pair->colors [0]); cpair_u32 [1] = chafa_color8_to_u32 (color_pair->colors [1]); for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { __m128i t0, t1, t; t0 = _mm_cvtepu8_epi32 (_mm_cvtsi32_si128 (chafa_color8_to_u32 (pixels [i].col))); t1 = _mm_cvtepu8_epi32 (_mm_cvtsi32_si128 (cpair_u32 [cov [i]])); t = t0 - t1; t = _mm_mullo_epi32 (t, t); err += t; } /* FIXME: Perhaps not ideal */ return _mm_extract_epi32 (err, 0) + _mm_extract_epi32 (err, 1) + _mm_extract_epi32 (err, 2) + _mm_extract_epi32 (err, 3); } chafa-1.18.2/chafa/internal/chafa-string-util.c000066400000000000000000000121711517447374300212310ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "internal/chafa-string-util.h" /* Generate a const table of the ASCII decimal numbers 0..255, avoiding leading * zeroes. Each entry is exactly 4 bytes. The strings are not zero-terminated; * instead their lengths are stored in the 4th byte, potentially leaving a gap * between the string and the length. * * This allows us to fetch a string using fixed-length memcpy() followed by * incrementing the target pointer. We copy all four bytes (32 bits) in the * hope that the compiler will generate register-wide loads and stores where * alignment is not an issue. * * The idea is to speed up printing for decimal numbers in this range (common * with palette indexes and color channels) at the cost of exactly 1kiB in the * executable. * * We require C99 due to __VA_ARGS__ and designated init but use no extensions. */ #define GEN_1(len, ...) { __VA_ARGS__, [3] = len } #define GEN_10(len, ...) \ GEN_1 (len, __VA_ARGS__, '0'), GEN_1 (len, __VA_ARGS__, '1'), \ GEN_1 (len, __VA_ARGS__, '2'), GEN_1 (len, __VA_ARGS__, '3'), \ GEN_1 (len, __VA_ARGS__, '4'), GEN_1 (len, __VA_ARGS__, '5'), \ GEN_1 (len, __VA_ARGS__, '6'), GEN_1 (len, __VA_ARGS__, '7'), \ GEN_1 (len, __VA_ARGS__, '8'), GEN_1 (len, __VA_ARGS__, '9') #define GEN_100(len, ...) \ GEN_10 (len, __VA_ARGS__, '0'), GEN_10 (len, __VA_ARGS__, '1'), \ GEN_10 (len, __VA_ARGS__, '2'), GEN_10 (len, __VA_ARGS__, '3'), \ GEN_10 (len, __VA_ARGS__, '4'), GEN_10 (len, __VA_ARGS__, '5'), \ GEN_10 (len, __VA_ARGS__, '6'), GEN_10 (len, __VA_ARGS__, '7'), \ GEN_10 (len, __VA_ARGS__, '8'), GEN_10 (len, __VA_ARGS__, '9') const char chafa_ascii_dec_u8 [256] [4] = { /* 0-9 */ GEN_1 (1, '0'), GEN_1 (1, '1'), GEN_1 (1, '2'), GEN_1 (1, '3'), GEN_1 (1, '4'), GEN_1 (1, '5'), GEN_1 (1, '6'), GEN_1 (1, '7'), GEN_1 (1, '8'), GEN_1 (1, '9'), /* 10-99 */ GEN_10 (2, '1'), GEN_10 (2, '2'), GEN_10 (2, '3'), GEN_10 (2, '4'), GEN_10 (2, '5'), GEN_10 (2, '6'), GEN_10 (2, '7'), GEN_10 (2, '8'), GEN_10 (2, '9'), /* 100-199 */ GEN_100 (3, '1'), /* 200-249 */ GEN_10 (3, '2', '0'), GEN_10 (3, '2', '1'), GEN_10 (3, '2', '2'), GEN_10 (3, '2', '3'), GEN_10 (3, '2', '4'), /* 250-255 */ GEN_1 (3, '2', '5', '0'), GEN_1 (3, '2', '5', '1'), GEN_1 (3, '2', '5', '2'), GEN_1 (3, '2', '5', '3'), GEN_1 (3, '2', '5', '4'), GEN_1 (3, '2', '5', '5') }; /* We need this because reg may contain garbage that will end up being * harmlessly dumped past end-of-output. Avoiding initialization saves * us approx. 3%, enough to matter. */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-warning-option" #pragma GCC diagnostic ignored "-Wuninitialized" #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #pragma clang diagnostic ignored "-Wuninitialized" gchar * chafa_format_dec_uint_0_to_9999 (char *dest, guint arg) { guint n, m; guint32 reg; gint i = 0; m = arg < 9999 ? arg : 9999; /* Reduce argument one decimal digit at a time and shift their * ASCII equivalents into a register. The register can usually be * written to memory all at once. memcpy() will do that if possible * while keeping us safe from potential alignment issues. * * We take advantage of the fact that registers are backwards on * x86 to reverse the result. GUINT32_TO_LE() will be a no-op there. * On BE archs, it will manually reverse using a bswap. * * With -O2 -fno-inline, this is approx. 15 times faster than sprintf() * in my tests. */ do { n = (m * (((1 << 15) + 9) / 10)) >> 15; reg <<= 8; reg |= '0' + (m - n * 10); m = n; i++; } while (m != 0); reg = GUINT32_TO_LE (reg); memcpy (dest, ®, 4); return dest + i; } #pragma clang diagnostic pop #pragma GCC diagnostic pop static gchar format_hex_digit (guchar n) { g_assert (n < 16); return (n < 10) ? '0' + n : 'a' - 10 + n; } gchar * chafa_format_dec_u16_hex (char *dest, guint16 arg) { *(dest++) = format_hex_digit ((arg >> 12) & 0xf); *(dest++) = format_hex_digit ((arg >> 8) & 0xf); *(dest++) = format_hex_digit ((arg >> 4) & 0xf); *(dest++) = format_hex_digit (arg & 0xf); return dest; } chafa-1.18.2/chafa/internal/chafa-string-util.h000066400000000000000000000034011517447374300212320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2021-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_STRING_UTIL_H__ #define __CHAFA_STRING_UTIL_H__ #include #include G_BEGIN_DECLS extern const char chafa_ascii_dec_u8 [256] [4]; /* Will overwrite 4 bytes starting at dest. Returns a pointer to the first * byte after the formatted ASCII decimal number (dest + 1..3). */ static inline gchar * chafa_format_dec_u8 (gchar *dest, guint8 n) { memcpy (dest, &chafa_ascii_dec_u8 [n] [0], 4); return dest + chafa_ascii_dec_u8 [n] [3]; } /* Will overwrite 4 bytes starting at dest. Returns a pointer to the first * byte after the formatted ASCII decimal number (dest + 1..4). */ gchar *chafa_format_dec_uint_0_to_9999 (char *dest, guint arg); /* Will overwrite 4 bytes starting at dest. Returns a pointer to the first * byte after the formatted ASCII hexadecimal number (dest + 4). */ gchar *chafa_format_dec_u16_hex (char *dest, guint16 arg); G_END_DECLS #endif /* __CHAFA_STRING_UTIL_H__ */ chafa-1.18.2/chafa/internal/chafa-symbols-ascii-ibm.h000066400000000000000000000722141517447374300223040ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* This is meant to be #included in the symbol definition table of * chafa-symbols.c. It's kept in a separate file due to its size. * * The symbol bitmaps are derived from https://github.com/dhepper/font8x8 by * Daniel Hepper . Excerpt from the accompanying README: * * 8x8 monochrome bitmap font for rendering * ======================================== * * A collection of header files containing a 8x8 bitmap font. * * [...] * * Author: Daniel Hepper * License: Public Domain * * Credits * ======= * * These header files are directly derived from an assembler file fetched from: * http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm * * Original header: * * ; Summary: font8_8.asm * ; 8x8 monochrome bitmap fonts for rendering * ; * ; Author: * ; Marcel Sondaar * ; International Business Machines (public domain VGA fonts) * ; * ; License: * ; Public Domain */ { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_SPACE, ' ', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '!', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXX " " XXXX " " XX " " XX " " " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '"', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX XX " " XX XX " " " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '#', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX XX " " XX XX " "XXXXXXX " " XX XX " "XXXXXXX " " XX XX " " XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '$', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXXX " "XX " " XXXX " " XX " "XXXXX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '%', CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XX XX " "XX XX " " XX " " XX " " XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '&', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX XX " " XXX " " XXX XX " "XX XXX " "XX XX " " XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, 0x27, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " "XX " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '(', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XX " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, ')', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XX " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '*', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX XX " " XXXX " "XXXXXXXX" " XXXX " " XX XX " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '+', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XX " "XXXXXX " " XX " " XX " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, ',', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_ASCII, '-', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXX " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '.', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '/', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XX " "XX " "X " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '0', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXX " "XX XX " "XX XXX " "XX XXXX " "XXXX XX " "XXX XX " " XXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '1', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXX " " XX " " XX " " XX " " XX " "XXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '2', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " " XX " " XXX " " XX " "XX XX " "XXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '3', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " " XX " " XXX " " XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '4', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXX " " XX XX " "XX XX " "XXXXXXX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '5', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " "XX " "XXXXX " " XX " " XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '6', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX " "XX " "XXXXX " "XX XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '7', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " "XX XX " " XX " " XX " " XX " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '8', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " "XX XX " " XXXX " "XX XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_DIGIT, '9', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " "XX XX " " XXXXX " " XX " " XX " " XXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, ':', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XX " " " " " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, ';', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XX " " " " " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_ASCII, '<', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XX " " XX " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '=', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXX " " " " " "XXXXXX " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '>', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XX " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '?', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " " XX " " XX " " XX " " " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '@', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXX " "XX XX " "XX XXXX " "XX XXXX " "XX XXXX " "XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'A', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXX " "XX XX " "XX XX " "XXXXXX " "XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'B', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " " XX XX " " XX XX " " XXXXX " " XX XX " " XX XX " "XXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'C', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX XX " "XX " "XX " "XX " " XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'D', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXX " " XX XX " " XX XX " " XX XX " " XX XX " " XX XX " "XXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'E', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXX " " XX X " " XX X " " XXXX " " XX X " " XX X " "XXXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'F', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXX " " XX X " " XX X " " XXXX " " XX X " " XX " "XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'G', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX XX " "XX " "XX " "XX XXX " " XX XX " " XXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'H', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " "XX XX " "XXXXXX " "XX XX " "XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'I', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX " " XX " " XX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'J', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX " " XX " " XX " "XX XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'K', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXX XX " " XX XX " " XX XX " " XXXX " " XX XX " " XX XX " "XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'L', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " " XX " " XX " " XX " " XX X " " XX XX " "XXXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'M', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XXX XXX " "XXXXXXX " "XXXXXXX " "XX X XX " "XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'N', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XXX XX " "XXXX XX " "XX XXXX " "XX XXX " "XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'O', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX XX " "XX XX " "XX XX " "XX XX " " XX XX " " XXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'P', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " " XX XX " " XX XX " " XXXXX " " XX " " XX " "XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'Q', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " "XX XX " "XX XX " "XX XXX " " XXXX " " XXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'R', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " " XX XX " " XX XX " " XXXXX " " XX XX " " XX XX " "XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'S', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " "XX XX " "XXX " " XXX " " XXX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'T', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " "X XX X " " XX " " XX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'U', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " "XX XX " "XX XX " "XX XX " "XX XX " "XXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'V', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " "XX XX " "XX XX " "XX XX " " XXXX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'W', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " "XX XX " "XX X XX " "XXXXXXX " "XXX XXX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'X', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " " XX XX " " XXX " " XXX " " XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'Y', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " "XX XX " " XXXX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'Z', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXX " "XX XX " "X XX " " XX " " XX X " " XX XX " "XXXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '[', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX " " XX " " XX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '\\', CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " XX " " XX " " XX " " XX " " XX " " X " " ") }, { CHAFA_SYMBOL_TAG_ASCII, ']', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX " " XX " " XX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '^', CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXX " " XX XX " "XX XX " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '_', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " "XXXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '`', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'a', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " " XX " " XXXXX " "XX XX " " XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'b', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXX " " XX " " XX " " XXXXX " " XX XX " " XX XX " "XX XXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'c', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " "XX XX " "XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'd', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX " " XX " " XXXXX " "XX XX " "XX XX " " XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'e', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " "XX XX " "XXXXXX " "XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'f', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX XX " " XX " "XXXX " " XX " " XX " "XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'g', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXX XX " "XX XX " "XX XX " " XXXXX " " XX " "XXXXX ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'h', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXX " " XX " " XX XX " " XXX XX " " XX XX " " XX XX " "XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'i', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " " " XXX " " XX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'j', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " " " XX " " XX " " XX " "XX XX " "XX XX " " XXXX ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'k', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXX " " XX " " XX XX " " XX XX " " XXXX " " XX XX " "XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'l', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX " " XX " " XX " " XX " " XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'm', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XX " "XXXXXXX " "XXXXXXX " "XX X XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'n', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXX " "XX XX " "XX XX " "XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'o', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " "XX XX " "XX XX " "XX XX " " XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'p', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XXX " " XX XX " " XX XX " " XXXXX " " XX " "XXXX ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'q', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXX XX " "XX XX " "XX XX " " XXXXX " " XX " " XXXX ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'r', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XXX " " XXX XX " " XX XX " " XX " "XXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 's', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXXX " "XX " " XXXX " " XX " "XXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 't', CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XX " " XXXXX " " XX " " XX " " XX X " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'u', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XX " "XX XX " "XX XX " "XX XX " " XXX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'v', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XX " "XX XX " "XX XX " " XXXX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'w', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XX " "XX X XX " "XXXXXXX " "XXXXXXX " " XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'x', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XX " " XX XX " " XXX " " XX XX " "XX XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'y', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XX XX " "XX XX " "XX XX " " XXXXX " " XX " "XXXXX ") }, { CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_ALPHA, 'z', CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXX " "X XX " " XX " " XX X " "XXXXXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '{', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX " " XX " "XXX " " XX " " XX " " XXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '|', CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " " " XX " " XX " " XX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '}', CHAFA_SYMBOL_OUTLINE_8X8 ( "XXX " " XX " " XX " " XXX " " XX " " XX " "XXX " " ") }, { CHAFA_SYMBOL_TAG_ASCII, '~', CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX XX " "XX XXX " " " " " " " " " " " " ") }, chafa-1.18.2/chafa/internal/chafa-symbols-ascii.h000066400000000000000000000763661517447374300215530ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* This is meant to be #included in the symbol definition table of * chafa-symbols.c. It's kept in a separate file due to its size. * * These are 7-bit ASCII symbols. The bitmaps are a close match to the * Terminus font (specifically ter-x14n.pcf). * * ASCII symbols are also "Latin" symbols, loosely corresponding to the * symbols you'd find in the European ISO/IEC 8859 charsets. */ { /* [ ] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN | CHAFA_SYMBOL_TAG_SPACE | CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_SEXTANT | CHAFA_SYMBOL_TAG_OCTANT, 0x20, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " " " ") }, { /* [!] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x21, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X " " X " " " " X " " ") }, { /* ["] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x22, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " X X " " " " " " " " " " " " ") }, { /* [#] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x23, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXX XX " " XX XXX " " X X " " X X " " ") }, { /* [$] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x24, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " XXXXX " "X X " " XXXXXX " " X X " " XXXXX " " X ") }, { /* [%] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x25, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX X " " XX X " " XX " " XX " " X XX " " X XX " " ") }, { /* [&] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x26, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XXX " " X X X " " X X " " XXX X " " ") }, { /* ['] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x27, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " " " " " " " " " ") }, { /* [(] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x28, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X " " X " " X " " XX " " ") }, { /* [)] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x29, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X " " X " " X " " XX " " ") }, { /* [*] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x2a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXX " " XXXXXX " " X X " " " " ") }, { /* [+] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x2b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X " " XXXXX " " X " " " " ") }, { /* [,] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x2c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " X " " X ") }, { /* [-] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x2d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XXXXXX " " " " " " ") }, { /* [.] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x2e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " X " " ") }, { /* [/] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x2f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " XX " " X " " X " " ") }, { /* [0] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x30, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X XXX " " XXX X " " X X " " XXXX " " ") }, { /* [1] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x31, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " X " " X " " X " " XXXXX " " ") }, { /* [2] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x32, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [3] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x33, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXX " " X " " X X " " XXXX " " ") }, { /* [4] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x34, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XX X " " X X " " XXXXXX " " X " " X " " ") }, { /* [5] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x35, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXXX " " X " " X X " " XXXX " " ") }, { /* [6] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x36, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X " " XXXXX " " X X " " X X " " XXXX " " ") }, { /* [7] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x37, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " X " " X " " X " " X " " ") }, { /* [8] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x38, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXXX " " X X " " X X " " XXXX " " ") }, { /* [9] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x39, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " XXXXX " " X " " XXXX " " ") }, { /* [:] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x3a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X " " " " " " X " " ") }, { /* [;] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x3b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X " " " " " " X " " X ") }, { /* [<] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x3c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " XX " " XX " " X " " ") }, { /* [=] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x3d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXXXX " " " " " " ") }, { /* [>] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x3e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " XX " " XX " " X " " ") }, { /* [?] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x3f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X XX " " X " " " " X " " ") }, { /* [@] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x40, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " "X X " "X XXX X " "X X XX " "X XX " " XXXXXX " " ") }, { /* [A] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x41, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [B] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x42, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " XXXXX " " X X " " X X " " XXXXX " " ") }, { /* [C] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x43, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X " " X " " X X " " XXXX " " ") }, { /* [D] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x44, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " X X " " X X " " X X " " XXXXX " " ") }, { /* [E] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x45, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [F] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x46, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXX " " X " " X " " X " " ") }, { /* [G] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x47, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " ") }, { /* [H] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x48, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [I] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x49, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [J] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x4a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X X " " XXX " " ") }, { /* [K] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x4b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X XX " " XXX " " XXX " " X XX " " X X " " ") }, { /* [L] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x4c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X " " X " " X " " XXXXXX " " ") }, { /* [M] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x4d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XX XX " "X X X X " "X X X " "X X " "X X " "X X " " ") }, { /* [N] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x4e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX X " " X X X " " X X X " " X XX " " X X " " ") }, { /* [O] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x4f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [P] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x50, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " X X " " XXXXX " " X " " X " " ") }, { /* [Q] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x51, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " X ") }, { /* [R] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x52, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " X X " " XXXXX " " X XX " " X X " " ") }, { /* [S] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x53, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXXXX " " X " " X X " " XXXX " " ") }, { /* [T] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x54, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXX " " X " " X " " X " " X " " X " " ") }, { /* [U] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x55, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [V] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x56, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " X X " " X X " " X X " " XX " " ") }, { /* [W] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x57, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X X " "X X " "X X " "X X X " "X X X X " "XX XX " " ") }, { /* [X] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x58, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XX " " XX " " X X " " X X " " ") }, { /* [Y] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x59, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X X " " X X " " XX XX " " X " " X " " X " " ") }, { /* [Z] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x5a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [[] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x5b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [\] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x5c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " XX " " X " " X " " ") }, { /* []] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x5d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [^] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x5e, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X X " " X X " " " " " " " " " " ") }, { /* [_] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x5f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " " " XXXXXX ") }, { /* [`] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x60, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " " " " " " " " " " " " " ") }, { /* [a] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x61, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [b] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x62, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXXXX " " ") }, { /* [c] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x63, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [d] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x64, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXXXX " " ") }, { /* [e] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x65, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [f] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x66, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " XXXXX " " X " " X " " X " " ") }, { /* [g] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x67, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [h] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x68, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [i] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x69, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XX " " X " " X " " XXX " " ") }, { /* [j] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x6a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XX " " X " " X " " X X " " XXX ") }, { /* [k] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x6b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X XX " " XXXX " " X X " " X XX " " ") }, { /* [l] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x6c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X " " X " " X " " XXX " " ") }, { /* [m] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x6d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXX " "X X X " "X X X " "X X X " " ") }, { /* [n] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x6e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [o] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x6f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [p] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x70, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXXX " " X ") }, { /* [q] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x71, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXXX " " X ") }, { /* [r] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x72, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X " " X " " ") }, { /* [s] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x73, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXXX " " X " " XXXXX " " ") }, { /* [t] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x74, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXX " " X " " X " " XXX " " ") }, { /* [u] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x75, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " X X " " XXXXX " " ") }, { /* [v] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x76, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " XX XX " " X X " " XX " " ") }, { /* [w] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x77, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "X X " "X X X " "X X X " " XXXXX " " ") }, { /* [x] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x78, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " XXXX " " X X " " X X " " ") }, { /* [y] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x79, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " X X " " XXXXX " " XXXX ") }, { /* [z] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x7a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XX " " XX " " XXXXXX " " ") }, { /* [{] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x7b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X " " X " " X " " XX " " ") }, { /* [|] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x7c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X " " X " " X " " X " " ") }, { /* [}] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x7d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X " " X " " X " " XX " " ") }, { /* [~] */ CHAFA_SYMBOL_TAG_ASCII | CHAFA_SYMBOL_TAG_LATIN, 0x7e, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX X " "X XXX " " " " " " " " " " " " ") }, chafa-1.18.2/chafa/internal/chafa-symbols-block.h000066400000000000000000002074071517447374300215450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* Block and border characters * --------------------------- * * This is meant to be #included in the symbol definition table of * chafa-symbols.c. It's kept in a separate file due to its size. */ /* Begin box drawing characters */ { CHAFA_SYMBOL_TAG_BORDER, 0x2500, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2501, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2502, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2503, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2504, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XX XX XX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2505, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XX XX XX" "XX XX XX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2506, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " X " " X " " " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2507, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " " " XX " " XX " " " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2508, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "X X X X " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2509, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "X X X X " "X X X X " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x250a, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " " " X " " " " X " " " " X " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x250b, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " " " XX " " " " XX " " " " XX " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x250c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x250d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXX" " XXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x250e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x250f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX" " XXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2510, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXX " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2511, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXX " "XXXXX " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2512, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2513, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXX " "XXXXX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2514, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " XXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2515, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " XXXX" " XXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2516, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2517, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XXXXX" " XXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2518, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " "XXXXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2519, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXX " "XXXXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x251a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " "XXXXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x251b, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXX " "XXXXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x251c, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " XXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x251d, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " XXXX" " XXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x251e, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x251f, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " XXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2520, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " XXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2521, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XXXXX" " XXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2522, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " XXXXX" " XXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2523, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XXXXX" " XXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2524, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " "XXXXX " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2525, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXX " "XXXXX " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2526, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " "XXXXX " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2527, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " "XXXXX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2528, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " "XXXXX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2529, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXX " "XXXXX " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x252a, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXX " "XXXXX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x252b, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXX " "XXXXX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x252c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x252d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXX " "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x252e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXX" "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x252f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXXX" "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2530, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2531, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXX " "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2532, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX" "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2533, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXXX" "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2534, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2535, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXX " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2536, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " XXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2537, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXXXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2538, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2539, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXX " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x253a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XXXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x253b, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXXXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x253c, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x253d, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXX " "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x253e, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " XXXX" "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x253f, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXXXXX" "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2540, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2541, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2542, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2543, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXX " "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2544, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XXXXX" "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2545, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXX " "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2546, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " XXXXX" "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2547, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXXXXX" "XXXXXXXX" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2548, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "XXXXXXXX" "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x2549, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXX " "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x254a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XXXXX" "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x254b, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " "XXXXXXXX" "XXXXXXXX" " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x254c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXX XXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x254d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXX XXX" "XXX XXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x254e, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " " " " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x254f, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " " " " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DIAGONAL, 0x2571, CHAFA_SYMBOL_OUTLINE_8X8 ( " X" " X " " X " " X " " X " " X " " X " "X ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DIAGONAL, 0x2572, CHAFA_SYMBOL_OUTLINE_8X8 ( "X " " X " " X " " X " " X " " X " " X " " X") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DIAGONAL, 0x2573, CHAFA_SYMBOL_OUTLINE_8X8 ( "X X" " X X " " X X " " XX " " XX " " X X " " X X " "X X") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2574, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2575, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2576, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2577, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2578, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXX " "XXXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x2579, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x257a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXX" " XXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER | CHAFA_SYMBOL_TAG_DOT, 0x257b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x257c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x257d, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " XX " " XX " " XX " " XX ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x257e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXX " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_BORDER, 0x257f, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " XX " " XX " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_VHALF | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x2580, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " " " " " " " ") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x2581, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_OCTANT, 0x2582, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x2583, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_VHALF | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT, 0x2584, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x2585, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_OCTANT, 0x2586, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x2587, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { /* Full block */ CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_SOLID | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_SEXTANT | CHAFA_SYMBOL_TAG_OCTANT, 0x2588, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x2589, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXX " "XXXXXXX " "XXXXXXX " "XXXXXXX " "XXXXXXX " "XXXXXXX " "XXXXXXX " "XXXXXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x258a, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXX " "XXXXXX " "XXXXXX " "XXXXXX " "XXXXXX " "XXXXXX " "XXXXXX " "XXXXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x258b, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXX " "XXXXX " "XXXXX " "XXXXX " "XXXXX " "XXXXX " "XXXXX " "XXXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_HHALF | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_SEXTANT | CHAFA_SYMBOL_TAG_OCTANT, 0x258c, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXX " "XXXX " "XXXX " "XXXX " "XXXX " "XXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x258d, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXX " "XXX " "XXX " "XXX " "XXX " "XXX " "XXX " "XXX ") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x258e, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " "XX " "XX " "XX " "XX " "XX " "XX " "XX ") }, { CHAFA_SYMBOL_TAG_BLOCK, 0x258f, CHAFA_SYMBOL_OUTLINE_8X8 ( "X " "X " "X " "X " "X " "X " "X " "X ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_HHALF | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_SEXTANT | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x2590, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXX" " XXXX" " XXXX" " XXXX" " XXXX" " XXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_STIPPLE, 0x2591, CHAFA_SYMBOL_OUTLINE_8X8 ( "X X " " X X " "X X " " X X " "X X " " X X " "X X " " X X ") }, { CHAFA_SYMBOL_TAG_STIPPLE, 0x2592, CHAFA_SYMBOL_OUTLINE_8X8 ( "X X X X " " X X X X" "X X X X " " X X X X" "X X X X " " X X X X" "X X X X " " X X X X") }, { CHAFA_SYMBOL_TAG_STIPPLE, 0x2593, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX XXX" "XX XXX X" " XXX XXX" "XX XXX X" " XXX XXX" "XX XXX X" " XXX XXX" "XX XXX X") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_INVERTED, 0x2594, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " " " " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_INVERTED, 0x2595, CHAFA_SYMBOL_OUTLINE_8X8 ( " X" " X" " X" " X" " X" " X" " X" " X") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT, 0x2596, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXX " "XXXX " "XXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT, 0x2597, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XXXX" " XXXX" " XXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT, 0x2598, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXX " "XXXX " "XXXX " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x2599, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXX " "XXXX " "XXXX " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT, 0x259a, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXX " "XXXX " "XXXX " " XXXX" " XXXX" " XXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x259b, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXX " "XXXX " "XXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x259c, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " XXXX" " XXXX" " XXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT, 0x259d, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXX" " XXXX" " XXXX" " " " " " " " ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x259e, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXX" " XXXX" " XXXX" "XXXX " "XXXX " "XXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_BLOCK | CHAFA_SYMBOL_TAG_QUAD | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x259f, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXX" " XXXX" " XXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb3c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " "X " "XXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb3d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " "XX " "XXXXX " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb3e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "X " "XX " "XX " "XXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb3f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XX " "XXX " "XXXXX " "XXXXXXX " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb40, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X " "X " "XX " "XX " "XXX " "XXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb41, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXXX" " XXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb42, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX" " XXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb43, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXXX" " XXXXX" " XXXXXX" " XXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb44, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X" " XX" " XXXX" " XXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb45, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXX" " XXXXX" " XXXXX" " XXXXXX" " XXXXXX" " XXXXXXX" " XXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb46, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXX" " XXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb47, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " X" " XXX" " XXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb48, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " XX" " XXXXX" " XXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb49, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X" " XX" " XX" " XXX" " XXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb4a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X" " XXX" " XXXXX" " XXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb4b, CHAFA_SYMBOL_OUTLINE_8X8 ( " X" " X" " XX" " XX" " XXX" " XXX" " XXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb4c, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXXXX " "XXXXXXX " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb4d, CHAFA_SYMBOL_OUTLINE_8X8 ( "X " "XXX " "XXXXXX " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb4e, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXXX " "XXXXXX " "XXXXXX " "XXXXXXX " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb4f, CHAFA_SYMBOL_OUTLINE_8X8 ( "X " "XX " "XXXX " "XXXXXX " "XXXXXXX " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb50, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXX " "XXXXX " "XXXXX " "XXXXXX " "XXXXXX " "XXXXXXX " "XXXXXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb51, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXX " "XXXXX " "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb52, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " XXXXXXX" " XXXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb53, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " XXXXXX" " XXX" " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb54, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " XXXXXXX" " XXXXXX" " XXXXXX" " XXXXX" " XXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb55, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " XXXXXXX" " XXXXXX" " XXXX" " XXX" " X") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb56, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXXX" " XXXXXXX" " XXXXXX" " XXXXXX" " XXXXX" " XXXXX" " XXXX" " XXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb57, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXX " "X " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb58, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXX " "XXX " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb59, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXX " "XXX " "X " "X " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb5a, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXX " "XXXXX " "XXX " "XX " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb5b, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " "XXXX " "XXX " "XXX " "XX " "X " "X " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb5c, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXX " "XXX " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb5d, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXX " "XXXXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb5e, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXX " "XXX " "X ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb5f, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXX " "XXXXXXX " "XXXXXX " "XXXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb60, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXX " "XXXXXX " "XXXX " "XXX " "X ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb61, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXX " "XXXXXXX " "XXXXXX " "XXXXXX " "XXXXX " "XXXXX " "XXXX " "XXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb62, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XX" " X" " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb63, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " XXXXX" " XX" " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb64, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXX" " XX" " XX" " X" " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb65, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXXX" " XXXXXX" " XXXX" " XXX" " X" " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb66, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX" " XXXX" " XXX" " XXX" " XX" " XX" " X" " X") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb67, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " XXXXX" " XXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb68, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " XXXXXXX" " XXXXXX" " XXXXX" " XXXX" " XXXXX" " XXXXXX" " XXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb69, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X X" "XX XX" "XXX XXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb6a, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXX " "XXXXXX " "XXXXX " "XXXX " "XXXXX " "XXXXXX " "XXXXXXX ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb6b, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXX XXX" "XX XX" "X X" " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb6c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X " "XX " "XXX " "XXXX " "XXX " "XX " "X ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb6d, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " XXXXXX " " XXXX " " XX " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb6e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X" " XX" " XXX" " XXXX" " XXX" " XX" " X") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb6f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " XX " " XXXX " " XXXXXX " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb7c, CHAFA_SYMBOL_OUTLINE_8X8 ( "X " "X " "X " "X " "X " "X " "X " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb7d, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "X " "X " "X " "X " "X " "X " "X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb7e, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " X" " X" " X" " X" " X" " X" " X") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb7f, CHAFA_SYMBOL_OUTLINE_8X8 ( " X" " X" " X" " X" " X" " X" " X" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb70, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb71, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb72, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb73, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb74, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb75, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X " " X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb76, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXXX" " " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb77, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXXXX" " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb78, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXXX" " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb79, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb7a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " "XXXXXXXX" " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb7b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " "XXXXXXXX" " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb80, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " " " " " " " " " " " " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb81, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" " " "XXXXXXXX" " " "XXXXXXXX" " " " " "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb82, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" " " " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb83, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb84, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_OCTANT | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb85, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb86, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" "XXXXXXXX" " ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb87, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX" " XX" " XX" " XX" " XX" " XX" " XX" " XX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb88, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX" " XXX" " XXX" " XXX" " XXX" " XXX" " XXX" " XXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb89, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXX" " XXXXX" " XXXXX" " XXXXX" " XXXXX" " XXXXX" " XXXXX" " XXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb8a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXX" " XXXXXX" " XXXXXX" " XXXXXX" " XXXXXX" " XXXXXX" " XXXXXX" " XXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_INVERTED, 0x1fb8b, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXXX" " XXXXXXX" " XXXXXXX" " XXXXXXX" " XXXXXXX" " XXXXXXX" " XXXXXXX" " XXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb95, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX XX " "XX XX " " XX XX" " XX XX" "XX XX " "XX XX " " XX XX" " XX XX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb96, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX XX" " XX XX" "XX XX " "XX XX " " XX XX" " XX XX" "XX XX " "XX XX ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb97, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXXXX" "XXXXXXXX" " " " " "XXXXXXXX" "XXXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb98, CHAFA_SYMBOL_OUTLINE_8X8 ( "X X X " " X X X" " X X " "X X X " " X X X" " X X " "X X X " " X X X") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fb99, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X X" "X X X " " X X " " X X X" "X X X " " X X " " X X X" "X X X ") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb9a, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXXXXX " " XXXXX " " XXX " " X " " X " " XXX " " XXXXX " " XXXXXXX") }, { CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_WEDGE, 0x1fb9b, CHAFA_SYMBOL_OUTLINE_8X8 ( " X" "X XX" "XX XXX" "XXX XXXX" "XXXX XXX" "XXX XX" "XX X" "X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba0, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "X " " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba1, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X" " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " X" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba4, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "X " "X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba5, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X" " X" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "X X" " X X " " X X " " XX ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba7, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X X " "X X" " " " " " " " ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba8, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "X " " X" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fba9, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X" "X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fbaa, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " " X" "X X" " X X " " X X " " XX ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fbab, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " X " "X " "X X" " X X " " X X " " XX ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fbac, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X X " "X X" " X" " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fbad, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X X " "X X" "X " " X " " X " " X ") }, { CHAFA_SYMBOL_TAG_LEGACY, 0x1fbae, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X X " "X X" "X X" " X X " " X X " " XX ") }, chafa-1.18.2/chafa/internal/chafa-symbols-kana.h000066400000000000000000002055451517447374300213660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* Japanese hiragana and katakana * ------------------------------ * * This is meant to be #included in the symbol definition table of * chafa-symbols.c. It's kept in a separate file due to its size. */ /* Hiragana */ { /* [ã��] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3041, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXXXXXXXX " " X X " " XXXXX XX " " XX X X XX " " X XX X " " XX XXX ") }, { /* [ã�‚] freq=374 */ CHAFA_SYMBOL_TAG_NONE, 0x3042, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XXXXXXXXXXX " " X XX " " XXXXXXXX " " XX X X X " " X X X X " " X XX X " " XXX XXXX ") }, { /* [ã�ƒ] freq=73 */ CHAFA_SYMBOL_TAG_NONE, 0x3043, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " X X " " X X " " X X " " X X X " " XX ") }, { /* [ã�„] freq=12 */ CHAFA_SYMBOL_TAG_NONE, 0x3044, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " X XX " " X XX " " XX X " " X X XX " " XX X " " XXX ") }, { /* [ã�…] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3045, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXX " " " " XXXX " " XX XX " " X " " XX " " XXXX ") }, { /* [ã�†] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3046, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXX " " XXX " " XXXX XXX " " X " " X " " XX " " XXXX ") }, { /* [ã�‡] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3047, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXXXX " " " " XXXXXXX " " XX " " XX XX " " XX XXXX ") }, { /* [ã�ˆ] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3048, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXX " " " " XXXXXXXX " " XX " " XXXXX " " XX X " " X XXXX ") }, { /* [ã�‰] freq=11 */ CHAFA_SYMBOL_TAG_NONE, 0x3049, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XXXXXX XXX " " X " " XXXXXXXXX " " X X X " " XXXX XXXX ") }, { /* [ã�Š] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x304a, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " X X " " XXXXXXX XXX " " X XX " " XXXXX XXX " " XX X X " " X X X " " XXX XXXX ") }, { /* [ã�‹] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x304b, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XX X " " XXXXXXXXX XX " " X X XX " " X X X " " XX XX " " XX X " " X XXX ") }, { /* [ã�Œ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x304c, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X X " " X X " " XXXXXXXXX X " " XX XX X " " X XX X " " X X " " XX X " " X XXXX ") }, { /* [ã��] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x304d, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XX XXXXX " " XXX X " " XXXXXXXXXX " " XX " " X XXX " " X " " XXXXXXXX ") }, { /* [ã�Ž] freq=48 */ CHAFA_SYMBOL_TAG_NONE, 0x304e, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X XX " " XX XXXXXX " " XXX X " " XXX XXXXXXX " " X X " " X XXXX " " XX " " XXXXXXXX ") }, { /* [ã��] freq=20 */ CHAFA_SYMBOL_TAG_NONE, 0x304f, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XX " " XX " " XX " " XX " " XXX " " X ") }, { /* [ã��] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3050, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XX " " XXX X X " " XX " " XX " " XX " " XX ") }, { /* [ã�‘] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3051, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XX X " " X XXXXXXXXX " " X X " " X X " " XX X " " XX X " " XX ") }, { /* [ã�’] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3052, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " XX X X " " X XXXXXXXXX " " X X " " X X " " XX XX " " XX X " " X XXX ") }, { /* [ã�“] freq=6 */ CHAFA_SYMBOL_TAG_NONE, 0x3053, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXX " " " " " " " " X " " XX " " XXXXXXXX ") }, { /* [ã�”] freq=7 */ CHAFA_SYMBOL_TAG_NONE, 0x3054, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " XXXXXXXXX X " " " " " " " " X " " X " " XXXXXXXXX ") }, { /* [ã�•] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3055, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X " " XXXXXXXXXX " " X " " XX " " X XX " " XX " " XXXXXXX ") }, { /* [ã�–] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3056, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X X " " XX " " XXXXXXXXXXX " " X " " X X " " X XX " " X " " XXXXXXXX ") }, { /* [ã�—] freq=21 */ CHAFA_SYMBOL_TAG_NONE, 0x3057, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " X " " X " " X " " X X " " X XX " " XXXXXXX ") }, { /* [ã�˜] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3058, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X XX " " X X " " X " " X " " X " " X XX " " XXXXXXXX ") }, { /* [ã�™] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3059, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXXXXXX " " XX X " " XXXX " " X X " " XXXXX " " XX " " XXX ") }, { /* [ã�š] freq=10 */ CHAFA_SYMBOL_TAG_NONE, 0x305a, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X X " " XXXXXXXXXX " " XX X " " XXXX " " XX X " " XXXXX " " XX " " XXX ") }, { /* [ã�›] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x305b, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X " " X XXXXX " " XXXXXXXXX X " " X XX " " X XX " " XX " " XXXXXXX ") }, { /* [ã�œ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x305c, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X X " " X XXXX " " XXXXXXXXXX " " X X " " X XXX " " X " " XXXXXXXX ") }, { /* [ã��] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x305d, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXXX " " XXX XX " " XX " " XX XXX " " XXX XXXX " " X " " X " " XXXXX ") }, { /* [ã�ž] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x305e, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXX " " XXXXXX X " " X XX " " XX XXXX " " XXXX XXXX " " X " " XX " " XXXX ") }, { /* [ã�Ÿ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x305f, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXXX " " X " " X XXXXX " " X " " XX X " " X X " " XX XXXXX ") }, { /* [ã� ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3060, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X " " X X X " " XXXXXXXX " " XX XXXXXX " " X " " X X " " XX X " " XX XXXXXX ") }, { /* [ã�¡] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3061, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XXXXXXXXXXX " " X " " X X " " XXXX XXX " " X XX " " XX " " XXXXXX ") }, { /* [ã�¢] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3062, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X " " X X " " XXXXXXXXXX " " X " " XXXXXXXXX " " X X " " XX " " XXXXXX ") }, { /* [ã�£] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x3063, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " XXXXXXX " " XX XX " " X " " XX " " XXXX ") }, { /* [ã�¤] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x3064, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXX " " XXXXXXX XXX " " XX " " X " " XX " " XXXXXX " " ") }, { /* [ã�¥] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3065, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X " " XXXXXXXX " " XXXX X " " X " " XX " " XX " " XXXXX ") }, { /* [ã�¦] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3066, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " X " " XX " " X " " XX " " XX " " XXX ") }, { /* [ã�§] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x3067, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " XX X " " XX XX X " " X " " XX " " XX " " XXX ") }, { /* [ã�¨] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3068, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " X XXXX " " XXX " " XX " " XX " " XX " " XXXXXXXX ") }, { /* [ã�©] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3069, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X XX " " X XXX " " XXXX " " X " " X " " XX " " XXXXXXXX ") }, { /* [ã�ª] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x306a, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XX " " XXXX XX XXX " " XX X " " XX X " " XX X " " XXXXXXXXX " " XXXXX ") }, { /* [ã�«] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x306b, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X XXXXXXX " " XX " " X " " X " " X X X " " XX X " " XX XXXXXX ") }, { /* [ã�¬] freq=26 */ CHAFA_SYMBOL_TAG_NONE, 0x306c, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X XX " " XXXXXX XXX " " XXX X X " " X XX X X " " X XX XXXXXX " " XXX X XXX " " XXX ") }, { /* [ã�­] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x306d, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X " " XXXXXXXXX XX " " XX X " " XX X " " X X XXXXXX " " X X X X X " " XX XXX ") }, { /* [ã�®] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x306e, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXX " " XX XX XX " " X X X " " XX XX XX " " X X X " " XXXX XX " " XXX ") }, { /* [ã�¯] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x306f, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X " " X XXXXXXXX " " X X " " X X " " XX XXXXXX " " XX X X XX " " XX XXXX ") }, { /* [ã�°] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3070, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X X " " X XXXXXXXX " " X X " " XX XX " " XXX XXXXXXX " " X X XX XX " " X XXX ") }, { /* [ã�±] freq=51 */ CHAFA_SYMBOL_TAG_NONE, 0x3071, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXXX" " X X XX " " X XXXXXXXX " " X X " " XX XX " " XXX XXXXXXX " " X X XX XX " " X XXX ") }, { /* [ã�²] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3072, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXX X " " XX XX " " XX XX " " X X XX " " XX X " " X X " " XXXXXX ") }, { /* [ã�³] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3073, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " XXXXXXX XX X " " X X " " X XX " " XX X X " " X XX " " XX X " " XXXXXX ") }, { /* [ã�´] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3074, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXX " " XXXXXXX XXX X " " X X X " " X XX " " XX X X " " X X " " XX X " " XXXXXX ") }, { /* [ã�µ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3075, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXX " " XX " " X " " XX X " " X X X " " XXX XX X " " XXXX ") }, { /* [ã�¶] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3076, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXX XX " " XX X X " " X " " XX XX " " XX XX X " " XX X XX " " XXXX ") }, { /* [ã�·] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x3077, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXX XXX " " XX X X " " X X " " XX XX " " XX XX X " " XX X XX " " XXXX ") }, { /* [ã�¸] freq=25 */ CHAFA_SYMBOL_TAG_NONE, 0x3078, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXX " " X XX " " XX XX " " X XX " " XX " " ") }, { /* [ã�¹] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3079, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X " " XXX X " " XX XX " " XX X " " X XX " " XX " " ") }, { /* [ã�º] freq=6 */ CHAFA_SYMBOL_TAG_NONE, 0x307a, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXX " " XXX X X " " XX XX XX " " XX X " " X XX " " XX " " ") }, { /* [ã�»] freq=9 */ CHAFA_SYMBOL_TAG_NONE, 0x307b, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX XXXXXXX " " X XX " " X XXXXXXX " " X X " " XX XXXXXX " " XX X X XX " " XX XXXX ") }, { /* [ã�¼] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x307c, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X XXXXXX X " " X X " " X XXXXXXXX " " XX X " " XXX X " " X XXXXXXXX " " X XXX ") }, { /* [ã�½] freq=181 */ CHAFA_SYMBOL_TAG_NONE, 0x307d, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXXX" " X XXXXXX XX " " X X " " X XXXXXXXX " " XX X " " XXX X " " X XXXXXXXX " " X XXX ") }, { /* [ã�¾] freq=7 */ CHAFA_SYMBOL_TAG_NONE, 0x307e, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXXXXX " " X " " XXXXXXXXXXX " " X " " XXXXXXX " " X X XX " " XXXXXX ") }, { /* [ã�¿] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x307f, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXX " " XX " " XX X " " XXXXX XXXXX " " X X XXXX " " XXXX XX " " XX ") }, { /* [ã‚€] freq=8 */ CHAFA_SYMBOL_TAG_NONE, 0x3080, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXXX XX " " X X " " XXXX " " X X " " XXXX X " " X X " " XXXXXXX ") }, { /* [ã‚�] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3081, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X " " XXXXXXXX " " XX X XX " " X X XX X " " XX XX X " " XXXX XX " " XX ") }, { /* [ã‚‚] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3082, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " XXXXXXXX " " X " " XXXXXXXX XX " " X X " " X X " " XXXXXX ") }, { /* [ゃ] freq=6 */ CHAFA_SYMBOL_TAG_NONE, 0x3083, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XX " " X XXXXXX " " XXXX X " " X X XXXXX " " XX " " X ") }, { /* [ã‚„] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x3084, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X XX " " XXXXXX XX " " XXX X XX " " X XXXXX " " XX " " X " " XX ") }, { /* [ã‚…] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x3085, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X XX " " X XX XXXX " " X X X XX " " XX X X XX " " XX XXXXX " " XX ") }, { /* [ゆ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3086, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XX X " " X XXXXX XXX " " X X X X " " XX X X " " XX X XX XX " " XXXXX " " XX ") }, { /* [ょ] freq=14 */ CHAFA_SYMBOL_TAG_NONE, 0x3087, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XXXXX " " XX " " XX " " XXXXXXXXX " " XXXXX ") }, { /* [よ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3088, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XX " " XXXXXX " " XX " " XX " " XXXXXXX " " X XX XXXX " " XXXX ") }, { /* [ら] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3089, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXX " " X " " XX XXX " " XXXXX XX " " X XX " " XX " " XXXXXX ") }, { /* [り] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x308a, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X XXXX " " XXX X " " XX XX " " XX XX " " X " " XX " " XXXX ") }, { /* [ã‚‹] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x308b, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXX " " XX " " XX " " XXX XXXXXX " " X XX " " XXXXX X " " XXXXXX ") }, { /* [れ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x308c, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X " " XXXXXXXXX XX " " XX XX " " XX X " " X X X " " X X X " " X XXXX ") }, { /* [ã‚�] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x308d, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXX " " XX " " XX X " " XXX XX XXX " " X XX " " XX " " XXXXXX ") }, { /* [ゎ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x308e, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XX " " XXX XXXXXX " " XX X " " XXX X " " X X XX " " X XX ") }, { /* [ã‚�] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x308f, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " XXXXX XXXXXX " " XXX XX " " XX X " " X X X " " X X XXX " " XX X ") }, { /* [ã‚�] freq=14 */ CHAFA_SYMBOL_TAG_NONE, 0x3090, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XXX X " " XXX " " XXXX XXX " " XX X X " " X XX X " " XX XX XXXXXXX " " XXX XXX ") }, { /* [ã‚‘] freq=17 */ CHAFA_SYMBOL_TAG_NONE, 0x3091, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXXXXXX " " XX " " XXX XXX " " X X XX X " " XXXXXXX " " XX " " XX X XXXX " " XX XX XX ") }, { /* [ã‚’] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x3092, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXXXXX " " X " " XXXXXX XXXX " " X XXX " " XX X " " X " " XXXXXXX ") }, { /* [ã‚“] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x3093, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XX " " XX " " XX X " " X X X " " X XX X " " X XX X " " X XXXX ") }, { /* [ã‚”] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3094, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXX XX " " XXXX X " " XXXX XX " " X " " XX " " XXX " " XXX ") }, { /* [ã‚•] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x3095, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " X XXXX XX " " XXX XX X " " X XX X " " X X " " XX XXXX ") }, { /* [ã‚–] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x3096, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X XX " " X XXXXXXX " " X XX " " X X XX " " XX X " " X XX ") }, /* Katakana */ { /* [ã‚ ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30a0, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " XXXX " " XXXX " " " " " " ") }, { /* [ã‚¡] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30a1, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXXXXXXXXX " " XX " " X X " " X " " XX " " XX ") }, { /* [ã‚¢] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30a2, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXXX " " X X " " X XX " " X " " XX " " XX " " XX ") }, { /* [ã‚£] freq=7 */ CHAFA_SYMBOL_TAG_NONE, 0x30a3, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XX " " XXX " " XXXX X " " X " " X ") }, { /* [イ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30a4, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XXX " " XXX " " XXXX X " " X " " X " " XX ") }, { /* [ã‚¥] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30a5, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XX " " XXXXXXXXXX " " X XX " " X " " XX " " XXXX ") }, { /* [ウ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30a6, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XX " " XXXXXXXXXXXX " " XX XX " " XX X " " XX " " XXX " " XX ") }, { /* [ã‚§] freq=20 */ CHAFA_SYMBOL_TAG_NONE, 0x30a7, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " XXXXXXXXXX " " XX " " XX " " XX " " XXXXXXXXXXXX ") }, { /* [エ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30a8, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " XX " " XX " " XX " " XX " " XXXXXXXXXXXXXX " " ") }, { /* [ã‚©] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30a9, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XXXXXXXXXXX " " XX " " XX X " " XX X " " X XXX ") }, { /* [オ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30aa, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " X " " XXXXXXXXXXXX " " XXX " " XX XX " " XXX XX " " X XX " " XXX ") }, { /* [ã‚«] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30ab, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " XXXXXXXXXXXX " " XX XX " " X X " " X X " " X X " " XX XXXX ") }, { /* [ガ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30ac, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X X " " XX X X " " XXXXXXXXXXX " " X X " " XX X " " X X " " XX XX " " X XXXX ") }, { /* [ã‚­] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30ad, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XXXXXX " " XXXXXX " " XX XXXX " " XXXXX XX " " XX " " X ") }, { /* [ã‚®] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30ae, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X X " " XXXXXXXXXXX " " X " " XXXXXXXXX " " XXX X " " X " " ") }, { /* [ク] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30af, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXX " " XX X " " XX XX " " XX " " X " " XXX " " XX ") }, { /* [ã‚°] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30b0, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X X " " XXXXXXXX " " XX X " " XX XX " " X " " XXX " " XXX ") }, { /* [ケ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30b1, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " X " " XXXXXXXXXXX " " XX X " " XX " " X " " XX " " X ") }, { /* [ゲ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30b2, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XX X X " " XXXXXXXXXX " " X X " " XX XX " " X " " XX " " XXX ") }, { /* [コ] freq=6 */ CHAFA_SYMBOL_TAG_NONE, 0x30b3, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXX " " XX " " XX " " XX " " XX " " XXXXXXXXXXX " " XX ") }, { /* [ã‚´] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30b4, CHAFA_SYMBOL_OUTLINE_16X8 ( " X XX " " XXXXXXXXXXX " " X " " X " " X " " X " " XXXXXXXXXXX " " X ") }, { /* [サ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30b5, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XX XX " " XXXXXXXXXXXXXX " " XX XX " " XX X " " X " " XX " " XX ") }, { /* [ã‚¶] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30b6, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X X XXX " " XXXXXXXXXXXXX " " X X " " X X " " XX " " XX " " XX ") }, { /* [ã‚·] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30b7, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XX " " XXX XX " " XX " " XX " " XXXXXX " " ") }, { /* [ジ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30b8, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X X " " XXX X X " " XX X " " X X " " XXX " " XXX " " XXX ") }, { /* [ス] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30b9, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX " " XX " " XX " " XX " " XX XX " " XXX X " " X X ") }, { /* [ズ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30ba, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X " " XXXXXXXXXX " " XX " " XX " " XX " " XX XX " " XX XX " " XX XX ") }, { /* [ã‚»] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30bb, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " X XXXXXX " " XXXXXXX XX " " X XX " " X " " X " " XXXXXXX ") }, { /* [ゼ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30bc, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X " " X XXXXX " " XXXXXXXX XX " " X XX " " X " " X " " XXXXXXX ") }, { /* [ソ] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x30bd, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX X " " XX XX " " X X " " X " " XX " " XXX " " ") }, { /* [ゾ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30be, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X X " " X XX " " XX X " " X " " XX " " XXX " " ") }, { /* [ã‚¿] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30bf, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " XXXXXXX " " X X " " XX X XX " " X XXXXX " " XXXX " " XX " " XXX ") }, { /* [ダ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30c0, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X X " " XXXXXXXX " " XX XX " " XX X X " " XX X " " XXXX " " XX " " XXX ") }, { /* [ãƒ�] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30c1, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXX " " X " " XXXXXXXXXXXXXX " " XX " " X " " X " " XX ") }, { /* [ヂ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30c2, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX X " " X X X " " XXXXXXXXXXXXX " " X " " X " " XX " " XX ") }, { /* [ッ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30c3, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " X X X " " X X XX " " XX " " XX " " XXX ") }, { /* [ツ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30c4, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX X " " XX X XX " " X X " " X " " XX " " XXXX " " ") }, { /* [ヅ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30c5, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X " " X X XX " " X XX " " XX " " XX " " XXX " " ") }, { /* [テ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30c6, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX " " " " XXXXXXXXXXXXX " " X " " XX " " XX " " XX ") }, { /* [デ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30c7, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " XXXXXXXXX " " " " XXXXXXXXXXXXX " " XX " " X " " XX " " XX ") }, { /* [ト] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30c8, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XX " " XXXX " " XX XXXXX " " XX " " XX " " ") }, { /* [ド] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30c9, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X X " " X X " " XXX " " X XXXXX " " X " " X " " X ") }, { /* [ナ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30ca, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " XXXXXXXXXXXXX " " X " " XX " " X " " XX " " X ") }, { /* [ニ] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30cb, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX " " " " " " " " " " XXXXXXXXXXXXX " " ") }, { /* [ヌ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30cc, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX " " X " " XXX X " " XXX " " XXXX " " XX XX " " XX ") }, { /* [ãƒ�] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x30cd, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX " " XXXXXXXXXXX " " XX " " XX " " XXXX XX " " XXXX XX XXX " " XX " " XX ") }, { /* [ノ] freq=6 */ CHAFA_SYMBOL_TAG_NONE, 0x30ce, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XX " " XX " " XX " " XX " " XXXX " " ") }, { /* [ãƒ�] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30cf, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X " " X XX " " XX X " " X X " " X XX " " X XX " " ") }, { /* [ãƒ�] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30d0, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X " " X X " " XX X " " X X " " X XX " " XX X " " ") }, { /* [パ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30d1, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXX " " X XX X X " " X XX X " " XX X " " X X " " X XX " " X X " " ") }, { /* [ヒ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30d2, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X " " X XXX " " XXXXXX " " X " " X " " X " " XXXXXXXX ") }, { /* [ビ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30d3, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X " " X XX " " XXXXXXX " " X " " X " " X " " XXXXXXXXX ") }, { /* [ピ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30d4, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXX " " X X X " " X XXX X " " XXXXXX " " X " " X " " X " " XXXXXXXXX ") }, { /* [フ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30d5, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " X " " XX " " XX " " XX " " XXX " " XX ") }, { /* [ブ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30d6, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " XXXXXXXXXXX " " X " " XX " " XX " " XX " " XXX " " XX ") }, { /* [プ] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30d7, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXXX" " XXXXXXXXXXX X" " XXX " " XX " " XX " " XX " " XXX " " XX ") }, { /* [ヘ] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30d8, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXX " " X XX " " XX XX " " X XX " " XX " " ") }, { /* [ベ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30d9, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X " " XXX X " " XX XX " " XX XX " " X XX " " XX " " ") }, { /* [ペ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30da, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXX " " XXX X X " " XX XX X " " XX XX " " X XX " " XX " " ") }, { /* [ホ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30db, CHAFA_SYMBOL_OUTLINE_16X8 ( " X " " X " " XXXXXXXXXXXX " " X " " X X X " " XX X X " " X " " XXX ") }, { /* [ボ] freq=14 */ CHAFA_SYMBOL_TAG_NONE, 0x30dc, CHAFA_SYMBOL_OUTLINE_16X8 ( " XX X X " " XX X X " " XXXXXXXXXXXXX " " XX " " XX XX XX " " X XX X " " X XX " " XXX ") }, { /* [ãƒ�] freq=32 */ CHAFA_SYMBOL_TAG_NONE, 0x30dd, CHAFA_SYMBOL_OUTLINE_16X8 ( " XXXX " " XX XX " " XXXXXXXXXXXXX " " XX " " XX XX XX " " XX XX XX " " XX " " XXX ") }, { /* [マ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30de, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " XX " " XX " " XX XX " " XXX " " XX " " X ") }, { /* [ミ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30df, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXX " " XXX " " XXXX " " XXXX " " X " " XXXXXXXX " " ") }, { /* [ム] freq=8 */ CHAFA_SYMBOL_TAG_NONE, 0x30e0, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " X " " XX " " X X " " X X " " XXXXXXXXXXX X " " ") }, { /* [メ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30e1, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " X XX " " XXX XX " " XXX " " XX XX " " XXX " " ") }, { /* [モ] freq=9 */ CHAFA_SYMBOL_TAG_NONE, 0x30e2, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX " " XX " " XXXXXXXXXXXXX " " XX " " XX " " XX " " XXXXXX ") }, { /* [ャ] freq=10 */ CHAFA_SYMBOL_TAG_NONE, 0x30e3, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XX XXX " " XXXXXXXXXX " " X XX " " X " " X ") }, { /* [ヤ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30e4, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " X XXXXX " " XXXXXXXX X " " X XX " " XX " " X " " XX ") }, { /* [ュ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30e5, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " XXXXXXXX " " X " " X " " XXXXXXXXXXXX " " ") }, { /* [ユ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30e6, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXX " " X " " X " " XX " " XX " " XXXXXXXXXXXXXX " " ") }, { /* [ョ] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30e7, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXXXXXXX " " X " " XXXXXXXX " " X " " X " " XXXXXXXXX ") }, { /* [ヨ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30e8, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXX " " X " " X " " XXXXXXXXXX " " X " " XXXXXXXXXXX " " X ") }, { /* [ラ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30e9, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXX " " " " XXXXXXXXXXXX " " X " " X " " XXX " " XXX ") }, { /* [リ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30ea, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X " " X X " " X X " " X X " " XX " " XXX " " ") }, { /* [ル] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30eb, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX XX " " XX XX " " X XX " " X XX X " " XX XX XX " " XX XXXX " " ") }, { /* [レ] freq=6 */ CHAFA_SYMBOL_TAG_NONE, 0x30ec, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X " " X " " X " " X XX " " X XXX " " XXXXX " " ") }, { /* [ロ] freq=653 */ CHAFA_SYMBOL_TAG_NONE, 0x30ed, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " XX XX " " XX XX " " XX XX " " XX XX " " XXXXXXXXXXXX " " XX XX ") }, { /* [ヮ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30ee, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XXXXXXXXXX " " X X " " X X " " XX " " XX " " XXXX ") }, { /* [ワ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30ef, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " XX XX " " XX X " " XX " " XX " " XXX " " X ") }, { /* [ヰ] freq=2 */ CHAFA_SYMBOL_TAG_NONE, 0x30f0, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X " " XXXXXXXXXXXX " " X X " " X X " " XXXXXXXXXXXXXX " " X " " X ") }, { /* [ヱ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30f1, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXXX " " X " " X XX " " X " " X " " XXXXXXXXXXXXXX " " ") }, { /* [ヲ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30f2, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XXXXXXXXXXX " " XX " " XXXXXXXXXX " " X " " X " " XXX " " XX ") }, { /* [ン] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30f3, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " XX " " XX " " XX " " X " " XXX " " XXXXXX " " ") }, { /* [ヴ] freq=0 */ CHAFA_SYMBOL_TAG_NONE, 0x30f4, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X XX " " X X " " XXXXXXXXXXXX " " X X " " X XX " " XX " " XX " " XXX ") }, { /* [ヵ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30f5, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XXXXXXXXX " " XX XX " " X XX " " XX X " " XX XXXX ") }, { /* [ヶ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30f6, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " XX " " XXXXXXXXX " " XX X " " XX " " XX " " XXX ") }, { /* [ヷ] freq=3 */ CHAFA_SYMBOL_TAG_NONE, 0x30f7, CHAFA_SYMBOL_OUTLINE_16X8 ( " X XX " " XXXXXXXXXXX " " X X " " X X " " X " " XX " " XX " " XXX ") }, { /* [ヸ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30f8, CHAFA_SYMBOL_OUTLINE_16X8 ( " X X " " X X " " XXXXXXXXXXXX " " X X " " X X " " XXXXXXXXXXXXXX " " X " " X ") }, { /* [ヹ] freq=1 */ CHAFA_SYMBOL_TAG_NONE, 0x30f9, CHAFA_SYMBOL_OUTLINE_16X8 ( " X XX " " XXXXXXXXXXXX " " X " " X XX " " X " " X " " XXXXXXXXXXXXXX " " ") }, { /* [ヺ] freq=4 */ CHAFA_SYMBOL_TAG_NONE, 0x30fa, CHAFA_SYMBOL_OUTLINE_16X8 ( " X XX " " XXXXXXXXXXX " " X " " XXXXXXXXXXX " " XX " " XX " " XX " " XXX ") }, { /* [・] freq=99 */ CHAFA_SYMBOL_TAG_NONE, 0x30fb, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " XXXX " " XX " " " " " " ") }, { /* [ー] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x30fc, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " " " XXXXXXXXXXXX " " " " " " " " ") }, { /* [ヽ] freq=19 */ CHAFA_SYMBOL_TAG_NONE, 0x30fd, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " " " X " " XX " " XX " " XX " " " " ") }, { /* [ヾ] freq=5 */ CHAFA_SYMBOL_TAG_NONE, 0x30fe, CHAFA_SYMBOL_OUTLINE_16X8 ( " " " X X " " X X " " XX " " XX " " X " " " " ") }, chafa-1.18.2/chafa/internal/chafa-symbols-latin.h000066400000000000000000003271721517447374300215640ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* This is meant to be #included in the symbol definition table of * chafa-symbols.c. It's kept in a separate file due to its size. * * These are Latin symbols not in the ASCII 7-bit range. The bitmaps are a * close match to the Terminus font (specifically ter-x14n.pcf). */ { /* [¡] */ CHAFA_SYMBOL_TAG_LATIN, 0xa1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " X " " X " " X " " X " " ") }, { /* [¢] */ CHAFA_SYMBOL_TAG_LATIN, 0xa2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " X " "XXXXXXX " "X X " "X X X " " XXXXX " " X ") }, { /* [£] */ CHAFA_SYMBOL_TAG_LATIN, 0xa3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [¤] */ CHAFA_SYMBOL_TAG_LATIN, 0xa4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " X X " " XXXXX " " X X " " XXX " " X X " " ") }, { /* [Â¥] */ CHAFA_SYMBOL_TAG_LATIN, 0xa5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X X " " X X " " XXX " " XXXXX " " XXXXX " " X " " ") }, { /* [¦] */ CHAFA_SYMBOL_TAG_LATIN, 0xa6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X " " " " X " " X " " ") }, { /* [§] */ CHAFA_SYMBOL_TAG_LATIN, 0xa7, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " X X " " XX " " X XX " " XX X " " XX " " X X " " XXX ") }, { /* [¨] */ CHAFA_SYMBOL_TAG_LATIN, 0xa8, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " " " " " " " " " " " " " ") }, { /* [©] */ CHAFA_SYMBOL_TAG_LATIN, 0xa9, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXXXX" "X XXXX X" "X X X" "X XXX X" " XXXXXX " " ") }, { /* [ª] */ CHAFA_SYMBOL_TAG_LATIN, 0xaa, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " X " " XX X " " XXX " " XXXXX " " " " " " ") }, { /* [«] */ CHAFA_SYMBOL_TAG_LATIN, 0xab, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XX XX " "XX XX " " XX XX " " X X " " ") }, { /* [¬] */ CHAFA_SYMBOL_TAG_LATIN, 0xac, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " " " " " ") }, { /* [®] */ CHAFA_SYMBOL_TAG_LATIN, 0xae, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " "XXXXXXXX" "X X X X" "X XXX X" "X X X X" " XXXXXX " " ") }, { /* [¯] */ CHAFA_SYMBOL_TAG_LATIN, 0xaf, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " " " " " " " " " " " " " ") }, { /* [°] */ CHAFA_SYMBOL_TAG_LATIN, 0xb0, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " XX " " " " " " " " " " ") }, { /* [±] */ CHAFA_SYMBOL_TAG_LATIN, 0xb1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X " " XXXXX " " X " " XXXXX " " ") }, { /* [²] */ CHAFA_SYMBOL_TAG_LATIN, 0xb2, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X " " XXXX " " " " " " " " ") }, { /* [³] */ CHAFA_SYMBOL_TAG_LATIN, 0xb3, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XX " " X " " XXXX " " " " " " " " ") }, { /* [´] */ CHAFA_SYMBOL_TAG_LATIN, 0xb4, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " " " " " " " " " " " " " ") }, { /* [µ] */ CHAFA_SYMBOL_TAG_LATIN, 0xb5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " X XX " " XXXX X " " X ") }, { /* [¶] */ CHAFA_SYMBOL_TAG_LATIN, 0xb6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " "X X X " "X X X " " XXX X " " X X " " X X " " ") }, { /* [·] */ CHAFA_SYMBOL_TAG_LATIN, 0xb7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X " " X " " " " " " ") }, { /* [¸] */ CHAFA_SYMBOL_TAG_LATIN, 0xb8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " X " " X ") }, { /* [¹] */ CHAFA_SYMBOL_TAG_LATIN, 0xb9, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XX " " X " " XXX " " " " " " " " ") }, { /* [º] */ CHAFA_SYMBOL_TAG_LATIN, 0xba, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " X X " " X X " " XXX " " XXXXX " " " " " " ") }, { /* [»] */ CHAFA_SYMBOL_TAG_LATIN, 0xbb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XX XX " " XX XX " " XX XX " "X X " " ") }, { /* [¼] */ CHAFA_SYMBOL_TAG_LATIN, 0xbc, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X X " " XX " " XX XX " "X X X " " XXX " " X ") }, { /* [½] */ CHAFA_SYMBOL_TAG_LATIN, 0xbd, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X X " " XX " " XX XX " "X X X " " X " " XXXX ") }, { /* [¾] */ CHAFA_SYMBOL_TAG_LATIN, 0xbe, CHAFA_SYMBOL_OUTLINE_8X8 ( "XXXX " " XX X " "XXX X " " XX " " XX XX " "X X X " " XXX " " X ") }, { /* [¿] */ CHAFA_SYMBOL_TAG_LATIN, 0xbf, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " X " " XX X " " X X " " XXXX " " ") }, { /* [À] */ CHAFA_SYMBOL_TAG_LATIN, 0xc0, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Ã�] */ CHAFA_SYMBOL_TAG_LATIN, 0xc1, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Â] */ CHAFA_SYMBOL_TAG_LATIN, 0xc2, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Ã] */ CHAFA_SYMBOL_TAG_LATIN, 0xc3, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Ä] */ CHAFA_SYMBOL_TAG_LATIN, 0xc4, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Ã…] */ CHAFA_SYMBOL_TAG_LATIN, 0xc5, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Æ] */ CHAFA_SYMBOL_TAG_LATIN, 0xc6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " "X X " "XXXXXX " "X X " "X X " "X XXXX " " ") }, { /* [Ç] */ CHAFA_SYMBOL_TAG_LATIN, 0xc7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X " " X " " X X " " XXXX " " X ") }, { /* [È] */ CHAFA_SYMBOL_TAG_LATIN, 0xc8, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXXXX " " X " " X " " XXXX " " X " " XXXXXX " " ") }, { /* [É] */ CHAFA_SYMBOL_TAG_LATIN, 0xc9, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXXXX " " X " " X " " XXXX " " X " " XXXXXX " " ") }, { /* [Ê] */ CHAFA_SYMBOL_TAG_LATIN, 0xca, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXXXX " " X " " X " " XXXX " " X " " XXXXXX " " ") }, { /* [Ë] */ CHAFA_SYMBOL_TAG_LATIN, 0xcb, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XXXXXX " " X " " X " " XXXX " " X " " XXXXXX " " ") }, { /* [ÃŒ] */ CHAFA_SYMBOL_TAG_LATIN, 0xcc, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ã�] */ CHAFA_SYMBOL_TAG_LATIN, 0xcd, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [ÃŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0xce, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ã�] */ CHAFA_SYMBOL_TAG_LATIN, 0xcf, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ã�] */ CHAFA_SYMBOL_TAG_LATIN, 0xd0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " "XXXX X " " X X " " X X " " XXXXX " " ") }, { /* [Ñ] */ CHAFA_SYMBOL_TAG_LATIN, 0xd1, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXX " " X X " " X X " " XXX X " " X XXX " " X X " " X X " " ") }, { /* [Ã’] */ CHAFA_SYMBOL_TAG_LATIN, 0xd2, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ó] */ CHAFA_SYMBOL_TAG_LATIN, 0xd3, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ô] */ CHAFA_SYMBOL_TAG_LATIN, 0xd4, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Õ] */ CHAFA_SYMBOL_TAG_LATIN, 0xd5, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ö] */ CHAFA_SYMBOL_TAG_LATIN, 0xd6, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [×] */ CHAFA_SYMBOL_TAG_LATIN, 0xd7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XX XX " " XX " " X X " " X X " " ") }, { /* [Ø] */ CHAFA_SYMBOL_TAG_LATIN, 0xd8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X XX" " X XXX " " XXX X " "XX X " " XXXX " " ") }, { /* [Ù] */ CHAFA_SYMBOL_TAG_LATIN, 0xd9, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ú] */ CHAFA_SYMBOL_TAG_LATIN, 0xda, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Û] */ CHAFA_SYMBOL_TAG_LATIN, 0xdb, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ü] */ CHAFA_SYMBOL_TAG_LATIN, 0xdc, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ã�] */ CHAFA_SYMBOL_TAG_LATIN, 0xdd, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " "X X " " X X " " XX XX " " X " " X " " X " " ") }, { /* [Þ] */ CHAFA_SYMBOL_TAG_LATIN, 0xde, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " XXXXX " " X X " " X X " " XXXXX " " X " " ") }, { /* [ß] */ CHAFA_SYMBOL_TAG_LATIN, 0xdf, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X X " " XXXXX " " X X " " XX X " " X XXX " " ") }, { /* [à] */ CHAFA_SYMBOL_TAG_LATIN, 0xe0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [á] */ CHAFA_SYMBOL_TAG_LATIN, 0xe1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [â] */ CHAFA_SYMBOL_TAG_LATIN, 0xe2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [ã] */ CHAFA_SYMBOL_TAG_LATIN, 0xe3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX X " " X XX " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [ä] */ CHAFA_SYMBOL_TAG_LATIN, 0xe4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [Ã¥] */ CHAFA_SYMBOL_TAG_LATIN, 0xe5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XX " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [æ] */ CHAFA_SYMBOL_TAG_LATIN, 0xe6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXX X " "X XXXX " " XX XX " " ") }, { /* [ç] */ CHAFA_SYMBOL_TAG_LATIN, 0xe7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X X " " XXXX " " X ") }, { /* [è] */ CHAFA_SYMBOL_TAG_LATIN, 0xe8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [é] */ CHAFA_SYMBOL_TAG_LATIN, 0xe9, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [ê] */ CHAFA_SYMBOL_TAG_LATIN, 0xea, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [ë] */ CHAFA_SYMBOL_TAG_LATIN, 0xeb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [ì] */ CHAFA_SYMBOL_TAG_LATIN, 0xec, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " X " " X " " XXX " " ") }, { /* [í] */ CHAFA_SYMBOL_TAG_LATIN, 0xed, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " X " " X " " XXX " " ") }, { /* [î] */ CHAFA_SYMBOL_TAG_LATIN, 0xee, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XX " " X " " X " " XXX " " ") }, { /* [ï] */ CHAFA_SYMBOL_TAG_LATIN, 0xef, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XX " " X " " X " " XXX " " ") }, { /* [ð] */ CHAFA_SYMBOL_TAG_LATIN, 0xf0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X XX " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ñ] */ CHAFA_SYMBOL_TAG_LATIN, 0xf1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX X " " X XX " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [ò] */ CHAFA_SYMBOL_TAG_LATIN, 0xf2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ó] */ CHAFA_SYMBOL_TAG_LATIN, 0xf3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ô] */ CHAFA_SYMBOL_TAG_LATIN, 0xf4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [õ] */ CHAFA_SYMBOL_TAG_LATIN, 0xf5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX X " " X XX " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ö] */ CHAFA_SYMBOL_TAG_LATIN, 0xf6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [÷] */ CHAFA_SYMBOL_TAG_LATIN, 0xf7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " X " " X " " XXXXX " " X " " " " ") }, { /* [ø] */ CHAFA_SYMBOL_TAG_LATIN, 0xf8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " X " " XXXXXX " " X XX X " " XX X " "X XXXX " " ") }, { /* [ù] */ CHAFA_SYMBOL_TAG_LATIN, 0xf9, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X X " " X X " " X X " " XXXXX " " ") }, { /* [ú] */ CHAFA_SYMBOL_TAG_LATIN, 0xfa, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X X " " X X " " X X " " XXXXX " " ") }, { /* [û] */ CHAFA_SYMBOL_TAG_LATIN, 0xfb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " X X " " X X " " X X " " XXXXX " " ") }, { /* [ü] */ CHAFA_SYMBOL_TAG_LATIN, 0xfc, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " X X " " X X " " X X " " XXXXX " " ") }, { /* [ý] */ CHAFA_SYMBOL_TAG_LATIN, 0xfd, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X X " " X X " " X X " " XXXXX " " XXXX ") }, { /* [þ] */ CHAFA_SYMBOL_TAG_LATIN, 0xfe, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXXXX " " X ") }, { /* [ÿ] */ CHAFA_SYMBOL_TAG_LATIN, 0xff, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " X X " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ä€] */ CHAFA_SYMBOL_TAG_LATIN, 0x100, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Ä�] */ CHAFA_SYMBOL_TAG_LATIN, 0x101, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XX " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [Ä‚] */ CHAFA_SYMBOL_TAG_LATIN, 0x102, CHAFA_SYMBOL_OUTLINE_8X8 ( " X XX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [ă] */ CHAFA_SYMBOL_TAG_LATIN, 0x103, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [Ä„] */ CHAFA_SYMBOL_TAG_LATIN, 0x104, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " XXX") }, { /* [Ä…] */ CHAFA_SYMBOL_TAG_LATIN, 0x105, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX " " XXXXXX " " X X " " XXXXX " " XX") }, { /* [Ć] */ CHAFA_SYMBOL_TAG_LATIN, 0x106, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXX " " X X " " X " " X " " X X " " XXXX " " ") }, { /* [ć] */ CHAFA_SYMBOL_TAG_LATIN, 0x107, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [Ĉ] */ CHAFA_SYMBOL_TAG_LATIN, 0x108, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " X " " X X " " XXXX " " ") }, { /* [ĉ] */ CHAFA_SYMBOL_TAG_LATIN, 0x109, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [ÄŠ] */ CHAFA_SYMBOL_TAG_LATIN, 0x10a, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXXX " " X X " " X " " X " " X X " " XXXX " " ") }, { /* [Ä‹] */ CHAFA_SYMBOL_TAG_LATIN, 0x10b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [ÄŒ] */ CHAFA_SYMBOL_TAG_LATIN, 0x10c, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " X " " X X " " XXXX " " ") }, { /* [Ä�] */ CHAFA_SYMBOL_TAG_LATIN, 0x10d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [ÄŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x10e, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XXXXX " " X X " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Ä�] */ CHAFA_SYMBOL_TAG_LATIN, 0x10f, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XX X " " X " " XXXXXX " " X X " " X X " " XXXXX " " ") }, { /* [Ä�] */ CHAFA_SYMBOL_TAG_LATIN, 0x110, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " "XXXX X " " X X " " X X " " XXXXX " " ") }, { /* [Ä‘] */ CHAFA_SYMBOL_TAG_LATIN, 0x111, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " XXX " " XXXXXX " " X X " " X X " " XXXXX " " ") }, { /* [Ä’] */ CHAFA_SYMBOL_TAG_LATIN, 0x112, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Ä“] */ CHAFA_SYMBOL_TAG_LATIN, 0x113, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXX " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [Ä”] */ CHAFA_SYMBOL_TAG_LATIN, 0x114, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Ä•] */ CHAFA_SYMBOL_TAG_LATIN, 0x115, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [Ä–] */ CHAFA_SYMBOL_TAG_LATIN, 0x116, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Ä—] */ CHAFA_SYMBOL_TAG_LATIN, 0x117, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [Ę] */ CHAFA_SYMBOL_TAG_LATIN, 0x118, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " XX") }, { /* [Ä™] */ CHAFA_SYMBOL_TAG_LATIN, 0x119, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X XX X " " X " " XXXX " " XX ") }, { /* [Äš] */ CHAFA_SYMBOL_TAG_LATIN, 0x11a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Ä›] */ CHAFA_SYMBOL_TAG_LATIN, 0x11b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [Äœ] */ CHAFA_SYMBOL_TAG_LATIN, 0x11c, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " ") }, { /* [Ä�] */ CHAFA_SYMBOL_TAG_LATIN, 0x11d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Äž] */ CHAFA_SYMBOL_TAG_LATIN, 0x11e, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " ") }, { /* [ÄŸ] */ CHAFA_SYMBOL_TAG_LATIN, 0x11f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ä ] */ CHAFA_SYMBOL_TAG_LATIN, 0x120, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " ") }, { /* [Ä¡] */ CHAFA_SYMBOL_TAG_LATIN, 0x121, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ä¢] */ CHAFA_SYMBOL_TAG_LATIN, 0x122, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " X ") }, { /* [Ä£] */ CHAFA_SYMBOL_TAG_LATIN, 0x123, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ĥ] */ CHAFA_SYMBOL_TAG_LATIN, 0x124, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Ä¥] */ CHAFA_SYMBOL_TAG_LATIN, 0x125, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " X " " X " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [Ħ] */ CHAFA_SYMBOL_TAG_LATIN, 0x126, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " "XXX XXX" " XXXXXX " " X X " " X X " " X X " " ") }, { /* [ħ] */ CHAFA_SYMBOL_TAG_LATIN, 0x127, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " XXX " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [Ĩ] */ CHAFA_SYMBOL_TAG_LATIN, 0x128, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXXX " " " " X " " X " " X " " X " " XXX " " ") }, { /* [Ä©] */ CHAFA_SYMBOL_TAG_LATIN, 0x129, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX XX " " X X " " XX " " X " " X " " XXX " " ") }, { /* [Ī] */ CHAFA_SYMBOL_TAG_LATIN, 0x12a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ä«] */ CHAFA_SYMBOL_TAG_LATIN, 0x12b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXX " " XX " " X " " X " " XXX " " ") }, { /* [Ĭ] */ CHAFA_SYMBOL_TAG_LATIN, 0x12c, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ä­] */ CHAFA_SYMBOL_TAG_LATIN, 0x12d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XX " " X " " X " " XXX " " ") }, { /* [Ä®] */ CHAFA_SYMBOL_TAG_LATIN, 0x12e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X " " XXX " " XX ") }, { /* [į] */ CHAFA_SYMBOL_TAG_LATIN, 0x12f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XX " " X " " X " " XXX " " XX ") }, { /* [İ] */ CHAFA_SYMBOL_TAG_LATIN, 0x130, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [ı] */ CHAFA_SYMBOL_TAG_LATIN, 0x131, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XX " " X " " X " " XXX " " ") }, { /* [IJ] */ CHAFA_SYMBOL_TAG_LATIN, 0x132, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXX XXX" " X X " " X X " " X X " " X X X " "XXX XX " " ") }, { /* [ij] */ CHAFA_SYMBOL_TAG_LATIN, 0x133, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " "XX XX " " X X " " X X " "XXXX X " " XX ") }, { /* [Ä´] */ CHAFA_SYMBOL_TAG_LATIN, 0x134, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " X " " X " " X " " X X " " XXX " " ") }, { /* [ĵ] */ CHAFA_SYMBOL_TAG_LATIN, 0x135, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XX " " X " " X " " X X " " XXX ") }, { /* [Ķ] */ CHAFA_SYMBOL_TAG_LATIN, 0x136, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X XX " " XXX " " XXX " " X XX " " X X X " " X ") }, { /* [Ä·] */ CHAFA_SYMBOL_TAG_LATIN, 0x137, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X XX " " XXXX " " X XX " " X X X " " X ") }, { /* [ĸ] */ CHAFA_SYMBOL_TAG_LATIN, 0x138, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X XX " " XXXX " " X XX " " X X " " ") }, { /* [Ĺ] */ CHAFA_SYMBOL_TAG_LATIN, 0x139, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " " " X " " X " " X " " X " " XXXXXX " " ") }, { /* [ĺ] */ CHAFA_SYMBOL_TAG_LATIN, 0x13a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ä»] */ CHAFA_SYMBOL_TAG_LATIN, 0x13b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X " " X " " X " " XXXXXX " " X ") }, { /* [ļ] */ CHAFA_SYMBOL_TAG_LATIN, 0x13c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X " " X " " X " " XXX " " X ") }, { /* [Ľ] */ CHAFA_SYMBOL_TAG_LATIN, 0x13d, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " X XX " " X " " X " " X " " X " " XXXXXX " " ") }, { /* [ľ] */ CHAFA_SYMBOL_TAG_LATIN, 0x13e, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ä¿] */ CHAFA_SYMBOL_TAG_LATIN, 0x13f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X X " " X X " " X " " XXXXXX " " ") }, { /* [Å€] */ CHAFA_SYMBOL_TAG_LATIN, 0x140, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " X X" " X X" " X " " XXX " " ") }, { /* [Å�] */ CHAFA_SYMBOL_TAG_LATIN, 0x141, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " "XX " " X " " XXXXXX " " ") }, { /* [Å‚] */ CHAFA_SYMBOL_TAG_LATIN, 0x142, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X " " XX " " XX " " X " " XXX " " ") }, { /* [Ń] */ CHAFA_SYMBOL_TAG_LATIN, 0x143, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " X X " " X X " " XXX X " " X XXX " " X X " " X X " " ") }, { /* [Å„] */ CHAFA_SYMBOL_TAG_LATIN, 0x144, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [Å…] */ CHAFA_SYMBOL_TAG_LATIN, 0x145, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXX X " " X XXX " " X X " " X X X " " X ") }, { /* [ņ] */ CHAFA_SYMBOL_TAG_LATIN, 0x146, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X X " " X ") }, { /* [Ň] */ CHAFA_SYMBOL_TAG_LATIN, 0x147, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " X XX X " " X X " " XXX X " " X XXX " " X X " " X X " " ") }, { /* [ň] */ CHAFA_SYMBOL_TAG_LATIN, 0x148, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [ʼn] */ CHAFA_SYMBOL_TAG_LATIN, 0x149, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [ÅŠ] */ CHAFA_SYMBOL_TAG_LATIN, 0x14a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXX X " " X XXX " " X X " " X X " " XX ") }, { /* [Å‹] */ CHAFA_SYMBOL_TAG_LATIN, 0x14b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X " " XX ") }, { /* [ÅŒ] */ CHAFA_SYMBOL_TAG_LATIN, 0x14c, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Å�] */ CHAFA_SYMBOL_TAG_LATIN, 0x14d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XX " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ÅŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x14e, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Å�] */ CHAFA_SYMBOL_TAG_LATIN, 0x14f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [Å�] */ CHAFA_SYMBOL_TAG_LATIN, 0x150, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX XX " " " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Å‘] */ CHAFA_SYMBOL_TAG_LATIN, 0x151, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [Å’] */ CHAFA_SYMBOL_TAG_LATIN, 0x152, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " "X X " "X XXX " "X X " "X X " " XXXXXX " " ") }, { /* [Å“] */ CHAFA_SYMBOL_TAG_LATIN, 0x153, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXX " "X XXXX " "X X " " XXXXXX " " ") }, { /* [Å”] */ CHAFA_SYMBOL_TAG_LATIN, 0x154, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXXX " " X X " " X X " " XXXXX " " X X " " X XX " " ") }, { /* [Å•] */ CHAFA_SYMBOL_TAG_LATIN, 0x155, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X " " X " " X " " ") }, { /* [Å–] */ CHAFA_SYMBOL_TAG_LATIN, 0x156, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " X X " " XXXXX " " X X " " X X XX " " X ") }, { /* [Å—] */ CHAFA_SYMBOL_TAG_LATIN, 0x157, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X " " XX " " X ") }, { /* [Ř] */ CHAFA_SYMBOL_TAG_LATIN, 0x158, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXXX " " X X " " X X " " XXXXX " " X X " " X XX " " ") }, { /* [Å™] */ CHAFA_SYMBOL_TAG_LATIN, 0x159, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X " " X " " X " " ") }, { /* [Åš] */ CHAFA_SYMBOL_TAG_LATIN, 0x15a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXX " " X X " " X " " XXXXX " " X X " " XXXX " " ") }, { /* [Å›] */ CHAFA_SYMBOL_TAG_LATIN, 0x15b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " XXXXX " " X " " XXXXX " " ") }, { /* [Åœ] */ CHAFA_SYMBOL_TAG_LATIN, 0x15c, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " XXXXX " " X X " " XXXX " " ") }, { /* [Å�] */ CHAFA_SYMBOL_TAG_LATIN, 0x15d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XXXXXX " " XXXXX " " X " " XXXXX " " ") }, { /* [Åž] */ CHAFA_SYMBOL_TAG_LATIN, 0x15e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXXXX " " X " " X X " " XXXX " " X ") }, { /* [ÅŸ] */ CHAFA_SYMBOL_TAG_LATIN, 0x15f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXXX " " X " " XXXXX " " X ") }, { /* [Å ] */ CHAFA_SYMBOL_TAG_LATIN, 0x160, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " XXXXX " " X X " " XXXX " " ") }, { /* [Å¡] */ CHAFA_SYMBOL_TAG_LATIN, 0x161, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " XXXXX " " X " " XXXXX " " ") }, { /* [Å¢] */ CHAFA_SYMBOL_TAG_LATIN, 0x162, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXX " " X " " X " " X " " X " " XX " " X ") }, { /* [Å£] */ CHAFA_SYMBOL_TAG_LATIN, 0x163, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXX " " X " " X " " XXX " " X ") }, { /* [Ť] */ CHAFA_SYMBOL_TAG_LATIN, 0x164, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " " " X " " X " " X " " X " " X " " ") }, { /* [Å¥] */ CHAFA_SYMBOL_TAG_LATIN, 0x165, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " " " X " " XXXXX " " X " " X " " XXX " " ") }, { /* [Ŧ] */ CHAFA_SYMBOL_TAG_LATIN, 0x166, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXX " " X " " XXXXX " " X " " X " " X " " ") }, { /* [ŧ] */ CHAFA_SYMBOL_TAG_LATIN, 0x167, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXX " " XXX " " X " " XXX " " ") }, { /* [Ũ] */ CHAFA_SYMBOL_TAG_LATIN, 0x168, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX X " " X XX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Å©] */ CHAFA_SYMBOL_TAG_LATIN, 0x169, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX X " " XX " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Ū] */ CHAFA_SYMBOL_TAG_LATIN, 0x16a, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Å«] */ CHAFA_SYMBOL_TAG_LATIN, 0x16b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Ŭ] */ CHAFA_SYMBOL_TAG_LATIN, 0x16c, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " X XX X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Å­] */ CHAFA_SYMBOL_TAG_LATIN, 0x16d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Å®] */ CHAFA_SYMBOL_TAG_LATIN, 0x16e, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [ů] */ CHAFA_SYMBOL_TAG_LATIN, 0x16f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XX " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Ű] */ CHAFA_SYMBOL_TAG_LATIN, 0x170, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX XX " " " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [ű] */ CHAFA_SYMBOL_TAG_LATIN, 0x171, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Ų] */ CHAFA_SYMBOL_TAG_LATIN, 0x172, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " X X " " X X " " X X " " XXXX " " XX ") }, { /* [ų] */ CHAFA_SYMBOL_TAG_LATIN, 0x173, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " X X " " XXXXX " " XX") }, { /* [Å´] */ CHAFA_SYMBOL_TAG_LATIN, 0x174, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " " "X X " "X X " "X X X " "X X X X " "XX XX " " ") }, { /* [ŵ] */ CHAFA_SYMBOL_TAG_LATIN, 0x175, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " "X X " "X X X " "X X X " " XXXXX " " ") }, { /* [Ŷ] */ CHAFA_SYMBOL_TAG_LATIN, 0x176, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " " "X X " " X X " " X X " " X " " X " " ") }, { /* [Å·] */ CHAFA_SYMBOL_TAG_LATIN, 0x177, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " X X " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ÿ] */ CHAFA_SYMBOL_TAG_LATIN, 0x178, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " " "X X " " X X " " X X " " X " " X " " ") }, { /* [Ź] */ CHAFA_SYMBOL_TAG_LATIN, 0x179, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXXXX " " X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [ź] */ CHAFA_SYMBOL_TAG_LATIN, 0x17a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " XX " " X " " XXXXXX " " ") }, { /* [Å»] */ CHAFA_SYMBOL_TAG_LATIN, 0x17b, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXXXXX " " X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [ż] */ CHAFA_SYMBOL_TAG_LATIN, 0x17c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " XX " " X " " XXXXXX " " ") }, { /* [Ž] */ CHAFA_SYMBOL_TAG_LATIN, 0x17d, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXXXX " " X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [ž] */ CHAFA_SYMBOL_TAG_LATIN, 0x17e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " XX " " X " " XXXXXX " " ") }, { /* [Å¿] */ CHAFA_SYMBOL_TAG_LATIN, 0x17f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X " " X " " ") }, { /* [Ɔ] */ CHAFA_SYMBOL_TAG_LATIN, 0x186, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X " " X " " X X " " XXXX " " ") }, { /* [ÆŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x18e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Æ�] */ CHAFA_SYMBOL_TAG_LATIN, 0x18f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [Æ�] */ CHAFA_SYMBOL_TAG_LATIN, 0x190, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXX " " X " " X X " " XXXX " " ") }, { /* [Æ’] */ CHAFA_SYMBOL_TAG_LATIN, 0x192, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " X X " " XXXXX " " X " " X " " X " "XXX ") }, { /* [Æ�] */ CHAFA_SYMBOL_TAG_LATIN, 0x19d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXX X " " X XXX " " X X " " X X " "X ") }, { /* [Æž] */ CHAFA_SYMBOL_TAG_LATIN, 0x19e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X " " X ") }, { /* [Ƶ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1b5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXXXX " " XX " " X " " XXXXXX " " ") }, { /* [ƶ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1b6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXX " " X " " XXXXXX " " ") }, { /* [Æ·] */ CHAFA_SYMBOL_TAG_LATIN, 0x1b7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXX " " X " " X X " " XXXX " " ") }, { /* [Ç�] */ CHAFA_SYMBOL_TAG_LATIN, 0x1cd, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [ÇŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ce, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXX " " XXXXXX " " X X " " XXXXX " " ") }, { /* [Ç�] */ CHAFA_SYMBOL_TAG_LATIN, 0x1cf, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ç�] */ CHAFA_SYMBOL_TAG_LATIN, 0x1d0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XX " " X " " X " " XXX " " ") }, { /* [Ç‘] */ CHAFA_SYMBOL_TAG_LATIN, 0x1d1, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ç’] */ CHAFA_SYMBOL_TAG_LATIN, 0x1d2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [Ç“] */ CHAFA_SYMBOL_TAG_LATIN, 0x1d3, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " X X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Ç”] */ CHAFA_SYMBOL_TAG_LATIN, 0x1d4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " X X " " X X " " X X " " XXXXX " " ") }, { /* [Ç¢] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e2, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXX " " XXXXXX " "X X " "XXXXXX " "X X " "X X " "X XXXX " " ") }, { /* [Ç£] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XX " " XXXXXX " " XXXXXX " "X X " " XX XX " " ") }, { /* [Ǥ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X " " X XXX " " X XXXX" " XXXX " " ") }, { /* [Ç¥] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X XXXX" " X X " " XXXXX " " XXXX ") }, { /* [Ǧ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e6, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " ") }, { /* [ǧ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ǩ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e8, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " X X " " X XX " " XXX " " XXX " " X XX " " X X " " ") }, { /* [Ç©] */ CHAFA_SYMBOL_TAG_LATIN, 0x1e9, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " X " " X " " X XX " " XXXX " " X XX " " X X " " ") }, { /* [Ǫ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ea, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " XX ") }, { /* [Ç«] */ CHAFA_SYMBOL_TAG_LATIN, 0x1eb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXX " " XX ") }, { /* [Ǭ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ec, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " XX ") }, { /* [Ç­] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ed, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXX " " XXXXXX " " X X " " X X " " XXXX " " XX ") }, { /* [Ç®] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ee, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXX " " XXXXX " " X " " XXX " " X " " X X " " XXXX " " ") }, { /* [ǯ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ef, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " XX " " XXXXXX " " X " " XXX " " X " " XXXXX ") }, { /* [ǰ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1f0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XX " " X " " X " " X X " " XXX ") }, { /* [Ç´] */ CHAFA_SYMBOL_TAG_LATIN, 0x1f4, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXX " " X X " " X " " X XXX " " X X " " XXXX " " ") }, { /* [ǵ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1f5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [Ǽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1fc, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXXXX " "X X " "X X " "XXXXXX " "X X " "X XXXX " " ") }, { /* [ǽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1fd, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " XXXXXX " "X X " " XX XX " " ") }, { /* [Ǿ] */ CHAFA_SYMBOL_TAG_LATIN, 0x1fe, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " XXXX " " X XXX" " X X X " " XXX X " "XX X " " XXXX " " ") }, { /* [Ç¿] */ CHAFA_SYMBOL_TAG_LATIN, 0x1ff, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X X " " XXXXXX " " X XX X " " XX X " "X XXXX " " ") }, { /* [Ș] */ CHAFA_SYMBOL_TAG_LATIN, 0x218, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXXXX " " X " " X X " " XXXX " " X ") }, { /* [È™] */ CHAFA_SYMBOL_TAG_LATIN, 0x219, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXXX " " X " " XXXXX " " X ") }, { /* [Èš] */ CHAFA_SYMBOL_TAG_LATIN, 0x21a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXX " " X " " X " " X " " X " " XX " " X ") }, { /* [È›] */ CHAFA_SYMBOL_TAG_LATIN, 0x21b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXX " " X " " X " " XXX " " X ") }, { /* [Ȳ] */ CHAFA_SYMBOL_TAG_LATIN, 0x232, CHAFA_SYMBOL_OUTLINE_8X8 ( " XXXXX " "X X " " X X " " XX XX " " X " " X " " X " " ") }, { /* [ȳ] */ CHAFA_SYMBOL_TAG_LATIN, 0x233, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " " X X " " X X " " X X " " XXXXX " " XXXX ") }, { /* [È·] */ CHAFA_SYMBOL_TAG_LATIN, 0x237, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XX " " X " " X " " X X " " XXX ") }, { /* [É”] */ CHAFA_SYMBOL_TAG_LATIN, 0x254, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [ɘ] */ CHAFA_SYMBOL_TAG_LATIN, 0x258, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X XX X " " X " " XXXX " " ") }, { /* [É™] */ CHAFA_SYMBOL_TAG_LATIN, 0x259, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX " " XXXX X " " X X " " XXXX " " ") }, { /* [É›] */ CHAFA_SYMBOL_TAG_LATIN, 0x25b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXX " " X X " " XXXX " " ") }, { /* [ɲ] */ CHAFA_SYMBOL_TAG_LATIN, 0x272, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X " "X ") }, { /* [Ê’] */ CHAFA_SYMBOL_TAG_LATIN, 0x292, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " XXX " " X " " XXXXX ") }, { /* [Ê»] */ CHAFA_SYMBOL_TAG_LATIN, 0x2bb, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " " " " " " " " " ") }, { /* [ʼ] */ CHAFA_SYMBOL_TAG_LATIN, 0x2bc, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " " " " " " " " " ") }, { /* [ʽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x2bd, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " X " " " " " " " " " " " " ") }, { /* [ˆ] */ CHAFA_SYMBOL_TAG_LATIN, 0x2c6, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX " " X X " " " " " " " " " " " " ") }, { /* [ˇ] */ CHAFA_SYMBOL_TAG_LATIN, 0x2c7, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XX " " " " " " " " " " " " ") }, { /* [˘] */ CHAFA_SYMBOL_TAG_LATIN, 0x2d8, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XX " " " " " " " " " " " " ") }, { /* [Ë™] */ CHAFA_SYMBOL_TAG_LATIN, 0x2d9, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " " " " " " " " " " " " " ") }, { /* [Ë›] */ CHAFA_SYMBOL_TAG_LATIN, 0x2db, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " " X " " XXX ") }, { /* [Ëœ] */ CHAFA_SYMBOL_TAG_LATIN, 0x2dc, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX X " " X XX " " " " " " " " " " " " ") }, { /* [Ë�] */ CHAFA_SYMBOL_TAG_LATIN, 0x2dd, CHAFA_SYMBOL_OUTLINE_8X8 ( " XX XX " " " " " " " " " " " " " " ") }, { /* [΄] */ CHAFA_SYMBOL_TAG_LATIN, 0x384, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " " " " " " " " " " " " " ") }, { /* [Î…] */ CHAFA_SYMBOL_TAG_LATIN, 0x385, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XX X " " X X " " " " " " " " " " ") }, { /* [Ά] */ CHAFA_SYMBOL_TAG_LATIN, 0x386, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [·] */ CHAFA_SYMBOL_TAG_LATIN, 0x387, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X " " " " " " " " ") }, { /* [Έ] */ CHAFA_SYMBOL_TAG_LATIN, 0x388, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Ή] */ CHAFA_SYMBOL_TAG_LATIN, 0x389, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " X X " " X X " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [Ί] */ CHAFA_SYMBOL_TAG_LATIN, 0x38a, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [ÎŒ] */ CHAFA_SYMBOL_TAG_LATIN, 0x38c, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [ÎŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x38e, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " " "X X " " X X " " X X " " X " " X " " ") }, { /* [Î�] */ CHAFA_SYMBOL_TAG_LATIN, 0x38f, CHAFA_SYMBOL_OUTLINE_8X8 ( "XX " " XXXX " " X X " " X X " " X X " " X X " " XX XX " " ") }, { /* [Î�] */ CHAFA_SYMBOL_TAG_LATIN, 0x390, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XX X " " " " XX " " X " " X " " XX " " ") }, { /* [Α] */ CHAFA_SYMBOL_TAG_LATIN, 0x391, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " XXXXXX " " X X " " X X " " ") }, { /* [Î’] */ CHAFA_SYMBOL_TAG_LATIN, 0x392, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " XXXXX " " X X " " X X " " XXXXX " " ") }, { /* [Γ] */ CHAFA_SYMBOL_TAG_LATIN, 0x393, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " X " " X " " X " " X " " ") }, { /* [Δ] */ CHAFA_SYMBOL_TAG_LATIN, 0x394, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X X " " XX XX " " X X " "X X " "XXXXXXX " " ") }, { /* [Ε] */ CHAFA_SYMBOL_TAG_LATIN, 0x395, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XXXX " " X " " X " " XXXXXX " " ") }, { /* [Ζ] */ CHAFA_SYMBOL_TAG_LATIN, 0x396, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [Η] */ CHAFA_SYMBOL_TAG_LATIN, 0x397, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [Θ] */ CHAFA_SYMBOL_TAG_LATIN, 0x398, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X XX X " " X X " " X X " " XXXX " " ") }, { /* [Ι] */ CHAFA_SYMBOL_TAG_LATIN, 0x399, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Κ] */ CHAFA_SYMBOL_TAG_LATIN, 0x39a, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X XX " " XXX " " XXX " " X XX " " X X " " ") }, { /* [Λ] */ CHAFA_SYMBOL_TAG_LATIN, 0x39b, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X X " " XX XX " " X X " "X X " "X X " " ") }, { /* [Μ] */ CHAFA_SYMBOL_TAG_LATIN, 0x39c, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XX XX " "X X X X " "X X X " "X X " "X X " "X X " " ") }, { /* [Î�] */ CHAFA_SYMBOL_TAG_LATIN, 0x39d, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XXX X " " X XXX " " X X " " X X " " ") }, { /* [Ξ] */ CHAFA_SYMBOL_TAG_LATIN | CHAFA_SYMBOL_TAG_EXTRA, 0x39e, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " " " XXXX " " " " " " XXXXXX " " ") }, { /* [Ο] */ CHAFA_SYMBOL_TAG_LATIN, 0x39f, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [Π] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X X " " X X " " X X " " X X " " X X " " ") }, { /* [Ρ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X X " " X X " " XXXXX " " X " " X " " ") }, { /* [Σ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XX " " XX " " X " " XXXXXX " " ") }, { /* [Τ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXX " " X " " X " " X " " X " " X " " ") }, { /* [Î¥] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X X " " X X " " XX XX " " X " " X " " X " " ") }, { /* [Φ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " "X X X " "X X X " "X X X " "X X X " " XXXXX " " ") }, { /* [Χ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " X X " " XX " " XX " " X X " " X X " " ") }, { /* [Ψ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "X X X " "X X X " "X X X " "X X X " " XXXXX " " X " " ") }, { /* [Ω] */ CHAFA_SYMBOL_TAG_LATIN, 0x3a9, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " X X " " X X " " X X " " XX XX " " ") }, { /* [Ϊ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3aa, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " XXX " " X " " X " " X " " X " " XXX " " ") }, { /* [Ϋ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ab, CHAFA_SYMBOL_OUTLINE_8X8 ( " X X " " " "X X " " X X " " X X " " X " " X " " ") }, { /* [ά] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ac, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " XXX X " " ") }, { /* [έ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ad, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " XXXX " " X X " " XXXX " " ") }, { /* [ή] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ae, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XXXXXX " " X X " " X X " " X X " " X ") }, { /* [ί] */ CHAFA_SYMBOL_TAG_LATIN, 0x3af, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " XX " " X " " X " " XX " " ") }, { /* [ΰ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b0, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XX X " " X X " " X X " " X X " " X X " " XXXX " " ") }, { /* [α] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXX X " " ") }, { /* [β] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X X " " XXXXX " " X X " " X X " " XXXXX " " X ") }, { /* [γ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "X X " " X X " " X X " " X " " X ") }, { /* [δ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ε] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " XXXX " " X X " " XXXX " " ") }, { /* [ζ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " X " " XX " " X " " X " " XXXX " " XX ") }, { /* [η] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X " " X ") }, { /* [θ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X X " " XXXXX " " X X " " X X " " XXX " " ") }, { /* [ι] */ CHAFA_SYMBOL_TAG_LATIN, 0x3b9, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XX " " X " " X " " XX " " ") }, { /* [κ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ba, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X XX " " XXXX " " X X " " X X " " ") }, { /* [λ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3bb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X X " " XX XX " " X X " "X X " " ") }, { /* [μ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3bc, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " X XX " " XXXX X " " X ") }, { /* [ν] */ CHAFA_SYMBOL_TAG_LATIN, 0x3bd, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " XX XX " " X X " " XX " " ") }, { /* [ξ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3be, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXX " " X " " XXXX " " X " " X " " XXXX " " XX ") }, { /* [ο] */ CHAFA_SYMBOL_TAG_LATIN, 0x3bf, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [Ï€] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " X X " " ") }, { /* [Ï�] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXXX " " X ") }, { /* [Ï‚] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X " " XXXX " " XX ") }, { /* [σ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXX " " ") }, { /* [Ï„] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXX " " X " " X " " XX " " ") }, { /* [Ï…] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " X X " " XXXX " " ") }, { /* [φ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XX XXXX " "X X X " "X X X " " XXXXX " " X ") }, { /* [χ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c7, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " X X " " X X " " XX " " X X " " X X ") }, { /* [ψ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c8, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "X X X " "X X X " "X X X " " XXXXX " " X ") }, { /* [ω] */ CHAFA_SYMBOL_TAG_LATIN, 0x3c9, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XX XX " "X X X " "X X X " " XX XX " " ") }, { /* [ÏŠ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ca, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " XX " " X " " X " " XX " " ") }, { /* [Ï‹] */ CHAFA_SYMBOL_TAG_LATIN, 0x3cb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X X " " " " X X " " X X " " X X " " XXXX " " ") }, { /* [ÏŒ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3cc, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [Ï�] */ CHAFA_SYMBOL_TAG_LATIN, 0x3cd, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X X " " X X " " X X " " XXXX " " ") }, { /* [ÏŽ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3ce, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " "XX XX " "X X X " "X X X " " XX XX " " ") }, { /* [Ï‘] */ CHAFA_SYMBOL_TAG_LATIN, 0x3d1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXX " " X X " " XXXXX " "X X " " X X " " XXX " " ") }, { /* [Ï•] */ CHAFA_SYMBOL_TAG_LATIN, 0x3d5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " X " "XXXXXXX " "X X X " "X X X " " XXXXX " " X ") }, { /* [ϰ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f0, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXX XX " " XX " " XX " "X XX " " ") }, { /* [ϱ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f1, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X X " " X X " " XXXXX " " XXXX ") }, { /* [ϲ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXXX " " X " " X X " " XXXX " " ") }, { /* [ϳ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " " " XX " " X " " X " " X X " " XXX ") }, { /* [Ï´] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " X X " " XXXXXX " " X X " " X X " " XXXX " " ") }, { /* [ϵ] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX " " XXXXX " " X " " XXXXX " " ") }, { /* [϶] */ CHAFA_SYMBOL_TAG_LATIN, 0x3f6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XXXXX " " XXXXX " " X " " XXXXX " " ") }, chafa-1.18.2/chafa/internal/chafa-symbols-misc-narrow.h000066400000000000000000000215261517447374300227100ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ /* Miscellaneous single-cell symbols * --------------------------------- * * This is meant to be #included in the symbol definition table of * chafa-symbols.c. It's kept in a separate file due to its size. */ { /* Leftwards arrow */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x2190, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " XX " " XXXXXX " " XX " " X " " " " ") }, { /* Upwards arrow */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x2191, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " XXX " " XXXXX " " X " " X " " X " " ") }, { /* Rightwards arrow */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x2192, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " XX " " XXXXXX " " XX " " X " " " " ") }, { /* Downwards arrow */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x2193, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " X " " X " " X " " XXXXX " " XXX " " X " " ") }, { /* Horizontal Scan Line 1 */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x23ba, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXXX" " " " " " " " " " " " ") }, { /* Horizontal Scan Line 3 */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x23bb, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " "XXXXXXXX" " " " " " " " ") }, { /* Horizontal Scan Line 7 */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x23bc, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " "XXXXXXXX" " " " " " ") }, { /* Horizontal Scan Line 9 */ CHAFA_SYMBOL_TAG_TECHNICAL, 0x23bd, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " " " " " " "XXXXXXXX" " ") }, /* Begin dot characters */ { CHAFA_SYMBOL_TAG_DOT, 0x25ae, /* Black vertical rectangle */ CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXXXX " " XXXXXX " " XXXXXX " " XXXXXX " " XXXXXX " " XXXXXX " " ") }, { CHAFA_SYMBOL_TAG_DOT, 0x25a0, /* Black square */ CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXXXX " " XXXXXX " " XXXXXX " " XXXXXX " " " " ") }, { /* Has an emoji variant that may show up unbidden */ CHAFA_SYMBOL_TAG_DOT | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25aa, /* Black small square */ CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " " XXXX " " XXXX " " XXXX " " " " ") }, { /* Black up-pointing triangle */ CHAFA_SYMBOL_TAG_GEOMETRIC, 0x25b2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XXXX " " XXXXXX " " XXXXXX " "XXXXXXXX" " " " ") }, { /* Black right-pointing triangle */ /* Has an emoji variant that may show up unbidden */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25b6, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXX " " XXXX " " XXXXXX " " XXXX " " XXX " " X " " ") }, { /* Black down-pointing triangle */ CHAFA_SYMBOL_TAG_GEOMETRIC, 0x25bc, CHAFA_SYMBOL_OUTLINE_8X8 ( " " "XXXXXXXX" " XXXXXX " " XXXXXX " " XXXX " " XX " " " " ") }, { /* Black left-pointing triangle */ /* Has an emoji variant that may show up unbidden */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25c0, CHAFA_SYMBOL_OUTLINE_8X8 ( " X " " XXX " " XXXX " " XXXXXX " " XXXX " " XXX " " X " " ") }, { /* Black diamond */ /* Depending on font, may exceed cell boundaries on VTE */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25c6, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XX " " XXXX " " XXXXXX " " XXXX " " XX " " " " ") }, { /* Black Circle */ CHAFA_SYMBOL_TAG_GEOMETRIC, 0x25cf, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " XXXX " " XXXXXX " " XXXXXX " " XXXXXX " " XXXX " " " " ") }, { /* Black Lower Right Triangle */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25e2, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XX " " XXX " " XXXX " " XXXXXX " " " " ") }, { /* Black Lower Left Triangle */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25e3, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XX " " XXX " " XXXX " " XXXXXX " " " " ") }, { /* Black Upper Left Triangle */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25e4, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXXXX " " XXXX " " XXX " " XX " " " " ") }, { /* Black Upper Right Triangle */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25e5, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXXXX " " XXXX " " XXX " " XX " " " " ") }, { /* Black Medium Square */ /* Has en emoji variant that may show up unbidden. See: * https://github.com/hpjansson/chafa/issues/52 */ CHAFA_SYMBOL_TAG_GEOMETRIC | CHAFA_SYMBOL_TAG_AMBIGUOUS, 0x25fc, CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " XXXX " " XXXX " " XXXX " " XXXX " " " " ") }, { CHAFA_SYMBOL_TAG_DOT, 0x00b7, /* Middle dot */ CHAFA_SYMBOL_OUTLINE_8X8 ( " " " " " " " XX " " XX " " " " " " ") }, chafa-1.18.2/chafa/internal/chafa-symbols.c000066400000000000000000000442731517447374300204500ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* memset */ #include "chafa.h" #include "internal/chafa-private.h" /* Standard C doesn't require that "s"[0] be considered a compile-time constant. * Modern compilers support it as an extension, but gcc < 8.1 does not. That's a * bit too recent, enough to make our tests fail. Therefore we disable it for now. * * See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69960 * * Another option is to use binary literals, but that is itself an extension, * and the symbol outlines would be less legible that way. */ #undef CHAFA_USE_CONSTANT_STRING_EXPR #ifdef CHAFA_USE_CONSTANT_STRING_EXPR /* Fancy macros that turn our ASCII symbol outlines into compact bitmaps */ #define CHAFA_FOLD_BYTE_TO_BIT(x) ((((x) >> 0) | ((x) >> 1) | ((x) >> 2) | ((x) >> 3) | \ ((x) >> 4) | ((x) >> 5) | ((x) >> 6) | ((x) >> 7)) & 1) #define CHAFA_OUTLINE_CHAR_TO_BIT(c) ((guint64) CHAFA_FOLD_BYTE_TO_BIT ((c) ^ 0x20)) #define CHAFA_OUTLINE_8_CHARS_TO_BITS(s, i) \ ((CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 0]) << 7) | (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 1]) << 6) | \ (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 2]) << 5) | (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 3]) << 4) | \ (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 4]) << 3) | (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 5]) << 2) | \ (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 6]) << 1) | (CHAFA_OUTLINE_CHAR_TO_BIT (s [i + 7]) << 0)) #define CHAFA_OUTLINE_TO_BITMAP_8X8(s) { \ ((CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 0) << 56) | (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 8) << 48) | \ (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 16) << 40) | (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 24) << 32) | \ (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 32) << 24) | (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 40) << 16) | \ (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 48) << 8) | (CHAFA_OUTLINE_8_CHARS_TO_BITS (s, 56) << 0)), 0 } #define CHAFA_SYMBOL_OUTLINE_8X8(x) CHAFA_OUTLINE_TO_BITMAP_8X8(x) #else #define CHAFA_SYMBOL_OUTLINE_8X8(x) x #define CHAFA_SYMBOL_OUTLINE_16X8(x) x #endif typedef struct { gunichar first, last; } UnicharRange; typedef struct { ChafaSymbolTags sc; gunichar c; #ifdef CHAFA_USE_CONSTANT_STRING_EXPR /* Each 64-bit integer represents an 8x8 bitmap, scanning left-to-right * and top-to-bottom, stored in host byte order. * * Narrow symbols use bitmap [0], with bitmap [1] set to zero. Wide * symbols are implemented as two narrow symbols side-by-side, with * the leftmost in [0] and rightmost in [1]. */ guint64 bitmap [2]; #else const gchar *outline; #endif } ChafaSymbolDef; ChafaSymbol *chafa_symbols; ChafaSymbol2 *chafa_symbols2; static gboolean symbols_initialized; /* Ranges we treat as ambiguous-width in addition to the ones defined by * GLib. For instance: VTE, although spacing correctly, has many glyphs * extending well outside their cells resulting in ugly overlapping. */ static const UnicharRange ambiguous_ranges [] = { { 0x00ad, 0x00ad }, /* Soft hyphen */ { 0x2196, 0x21ff }, /* Arrows (most) */ { 0x222c, 0x2237 }, /* Mathematical ops (some) */ { 0x2245, 0x2269 }, /* Mathematical ops (some) */ { 0x226d, 0x2279 }, /* Mathematical ops (some) */ { 0x2295, 0x22af }, /* Mathematical ops (some) */ { 0x22bf, 0x22bf }, /* Mathematical ops (some) */ { 0x22c8, 0x22ff }, /* Mathematical ops (some) */ { 0x2300, 0x23ff }, /* Technical */ { 0x2460, 0x24ff }, /* Enclosed alphanumerics */ { 0x25a0, 0x25ff }, /* Geometric */ { 0x2700, 0x27bf }, /* Dingbats */ { 0x27c0, 0x27e5 }, /* Miscellaneous mathematical symbols A (most) */ { 0x27f0, 0x27ff }, /* Supplemental arrows A */ { 0x2900, 0x297f }, /* Supplemental arrows B */ { 0x2980, 0x29ff }, /* Miscellaneous mathematical symbols B */ { 0x2b00, 0x2bff }, /* Miscellaneous symbols and arrows */ { 0x1f100, 0x1f1ff }, /* Enclosed alphanumeric supplement */ { 0, 0 } }; /* Emojis of various kinds; usually multicolored. We have no control over * the foreground colors of these, and they may render poorly for other * reasons (e.g. too wide). */ static const UnicharRange emoji_ranges [] = { { 0x2600, 0x26ff }, /* Miscellaneous symbols */ { 0x1f000, 0x1fb3b }, /* Emojis first part */ { 0x1fbcb, 0x1ffff }, /* Emojis second part, the gap is legacy computing */ /* This symbol usually prints fine, but we don't want it randomly * popping up in our output anyway. So we add it to the "ugly" category, * which is excluded from "all". */ { 0x534d, 0x534d }, { 0, 0 } }; static const UnicharRange meta_ranges [] = { /* Arabic tatweel -- RTL but it's a modifier and not formally part * of a script, so can't simply be excluded on that basis in * ChafaSymbolMap::char_is_selected() */ { 0x0640, 0x0640 }, /* Ideographic description characters. These convert poorly to our * internal format. */ { 0x2ff0, 0x2fff }, { 0, 0 } }; static const ChafaSymbolDef symbol_defs [] = { #include "chafa-symbols-ascii.h" #include "chafa-symbols-latin.h" #include "chafa-symbols-block.h" #include "chafa-symbols-kana.h" #include "chafa-symbols-misc-narrow.h" { #ifdef CHAFA_USE_CONSTANT_STRING_EXPR 0, 0, { 0, 0 } #else 0, 0, NULL #endif } }; /* ranges must be terminated by zero first, last */ static gboolean unichar_is_in_ranges (gunichar c, const UnicharRange *ranges) { for ( ; ranges->first != 0 || ranges->last != 0; ranges++) { g_assert (ranges->first <= ranges->last); if (c >= ranges->first && c <= ranges->last) return TRUE; } return FALSE; } static void calc_weights (ChafaSymbol *sym) { gint i; sym->fg_weight = 0; sym->bg_weight = 0; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { guchar p = sym->coverage [i]; sym->fg_weight += p; sym->bg_weight += 1 - p; } } static void outline_to_coverage (const gchar *outline, gchar *coverage_out, gint rowstride) { gchar xlate [256]; gint x, y; xlate [' '] = 0; xlate ['X'] = 1; for (y = 0; y < CHAFA_SYMBOL_HEIGHT_PIXELS; y++) { for (x = 0; x < CHAFA_SYMBOL_WIDTH_PIXELS; x++) { guchar p = (guchar) outline [y * rowstride + x]; coverage_out [y * CHAFA_SYMBOL_WIDTH_PIXELS + x] = xlate [p]; } } } static guint64 coverage_to_bitmap (const gchar *cov, gint rowstride) { guint64 bitmap = 0; gint x, y; for (y = 0; y < CHAFA_SYMBOL_HEIGHT_PIXELS; y++) { for (x = 0; x < CHAFA_SYMBOL_WIDTH_PIXELS; x++) { bitmap <<= 1; if (cov [y * rowstride + x]) bitmap |= 1; } } return bitmap; } static void bitmap_to_coverage (guint64 bitmap, gchar *cov_out) { gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { cov_out [i] = (bitmap >> (63 - i)) & 1; } } static void gen_braille_sym (gchar *cov, guint8 val) { memset (cov, 0, CHAFA_SYMBOL_N_PIXELS); cov [1] = cov [2] = (val & 1); cov [5] = cov [6] = ((val >> 3) & 1); cov += CHAFA_SYMBOL_WIDTH_PIXELS * 2; cov [1] = cov [2] = ((val >> 1) & 1); cov [5] = cov [6] = ((val >> 4) & 1); cov += CHAFA_SYMBOL_WIDTH_PIXELS * 2; cov [1] = cov [2] = ((val >> 2) & 1); cov [5] = cov [6] = ((val >> 5) & 1); cov += CHAFA_SYMBOL_WIDTH_PIXELS * 2; cov [1] = cov [2] = ((val >> 6) & 1); cov [5] = cov [6] = ((val >> 7) & 1); } static int generate_braille_syms (ChafaSymbol *syms, gint first_ofs) { gunichar c; gint i = first_ofs; /* Braille 2x4 range */ c = 0x2800; for (i = first_ofs; c < 0x2900; c++, i++) { ChafaSymbol *sym = &syms [i]; sym->sc = CHAFA_SYMBOL_TAG_BRAILLE; sym->c = c; sym->coverage = g_malloc (CHAFA_SYMBOL_N_PIXELS); gen_braille_sym (sym->coverage, c - 0x2800); calc_weights (&syms [i]); syms [i].bitmap = coverage_to_bitmap (syms [i].coverage, CHAFA_SYMBOL_WIDTH_PIXELS); syms [i].popcount = chafa_population_count_u64 (syms [i].bitmap); } return i; } static void gen_sextant_sym (gchar *cov, guint8 val) { gint x, y; memset (cov, 0, CHAFA_SYMBOL_N_PIXELS); for (y = 0; y < 3; y++) { for (x = 0; x < 2; x++) { gint bit = y * 2 + x; if (val & (1 << bit)) { gint u, v; for (v = 0; v < 3; v++) { for (u = 0; u < 4; u++) { gint row = y * 3 + v; if (row > 3) row--; cov [(row * 8) + x * 4 + u] = 1; } } } } } } static int generate_sextant_syms (ChafaSymbol *syms, gint first_ofs) { gunichar c; gint i; /* Teletext sextant/2x3 mosaic range */ c = 0x1fb00; for (i = first_ofs; c < 0x1fb3b; c++, i++) { ChafaSymbol *sym = &syms [i]; gint bitmap; sym->sc = CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_SEXTANT; sym->c = c; sym->coverage = g_malloc (CHAFA_SYMBOL_N_PIXELS); bitmap = c - 0x1fb00 + 1; if (bitmap > 20) bitmap++; if (bitmap > 41) bitmap++; gen_sextant_sym (sym->coverage, bitmap); calc_weights (&syms [i]); syms [i].bitmap = coverage_to_bitmap (syms [i].coverage, CHAFA_SYMBOL_WIDTH_PIXELS); syms [i].popcount = chafa_population_count_u64 (syms [i].bitmap); } return i; } /* Based on code by Kang-Che Sung. The original is MIT licensed. * See https://gitlab.com/-/snippets/3710003 */ struct OctantEntry { guint8 octant_bits; guint8 data; }; static const struct OctantEntry octant_map [26] = { { 0x00, 0x00 /* u+00a0 */ }, { 0x01, 0xa8 /* u+1cea8 */ }, { 0x02, 0xab /* u+1ceab */ }, { 0x03, 0xc2 /* u+1fb82 */ }, { 0x05, 0x98 /* u+2598 */ }, { 0x0a, 0x9d /* u+259d */ }, { 0x0f, 0x80 /* u+2580 */ }, { 0x14, 0xe6 /* u+1fbe6 */ }, { 0x28, 0xe7 /* u+1fbe7 */ }, { 0x3f, 0xc5 /* u+1fb85 */ }, { 0x40, 0xa3 /* u+1cea3 */ }, { 0x50, 0x96 /* u+2596 */ }, { 0x55, 0x8c /* u+258c */ }, { 0x5a, 0x9e /* u+259e */ }, { 0x5f, 0x9b /* u+259b */ }, { 0x80, 0xa0 /* u+1cea0 */ }, { 0xa0, 0x97 /* u+2597 */ }, { 0xa5, 0x9a /* u+259a */ }, { 0xaa, 0x90 /* u+2590 */ }, { 0xaf, 0x9c /* u+259c */ }, { 0xc0, 0x82 /* u+2582 */ }, { 0xf0, 0x84 /* u+2584 */ }, { 0xf5, 0x99 /* u+2599 */ }, { 0xfa, 0x9f /* u+259f */ }, { 0xfc, 0x86 /* u+2586 */ }, { 0xff, 0x88 /* u+2588 */ } }; static int find_unicode_octant_map_data (guint8 octant_bits) { unsigned int first = 0; unsigned int last = sizeof (octant_map) / sizeof (octant_map [0]); while (first < last) { unsigned int i = (first + last) / 2; if (octant_bits == octant_map [i].octant_bits) return octant_map [i].data; if (octant_bits > octant_map [i].octant_bits) first = i + 1; else last = i; } return -(int) first; } static gunichar octant_bits_to_unichar (guint8 octant_bits) { int data = find_unicode_octant_map_data (octant_bits); if (data < 0) return (gunichar) (((guint32) (octant_bits + data)) | 0x1cd00); if (data == 0x00) return 0x00a0; switch ((data >> 5) & 0x3) { case 0: /* "Block Elements" block */ return ((guint32) data & 0x1f) | 0x2580; case 1: /* Part of "Symbols for Legacy Computing Supplement" block */ return ((guint32) data & 0x1f) | 0x1cea0; case 2: /* Part of "Symbols for Legacy Computing" block */ return ((guint32) data & 0x1f) | 0x1fb80; case 3: default: /* Part of "Symbols for Legacy Computing" block */ return ((guint32) data & 0x1f) | 0x1fbe6; } } static void octant_bits_to_coverage (guint8 octant_bits, gchar *coverage_dest) { gint y; for (y = 0; y < CHAFA_SYMBOL_HEIGHT_PIXELS; y++) { gint x; for (x = 0; x < CHAFA_SYMBOL_WIDTH_PIXELS; x++) { guint bit = (y & ~1) + ((x >> 2) & 1); guint8 cov; cov = ((octant_bits >> bit) & 1); coverage_dest [y * CHAFA_SYMBOL_WIDTH_PIXELS + x] = cov; #if 0 g_printerr ("%d, ", cov); #endif } #if 0 g_printerr ("\n"); #endif } #if 0 g_printerr ("\n"); #endif } static int generate_octant_syms (ChafaSymbol *syms, gint first_ofs) { guint oct; gint i; for (i = first_ofs, oct = 0; oct < 256; oct++) { ChafaSymbol *sym = &syms [i]; gunichar c; c = octant_bits_to_unichar (oct); /* Skip block symbols; we already have those */ if (c < 0x1cd00 || c > 0x1d000) continue; sym->sc = CHAFA_SYMBOL_TAG_LEGACY | CHAFA_SYMBOL_TAG_OCTANT; sym->c = c; sym->coverage = g_malloc (CHAFA_SYMBOL_N_PIXELS); octant_bits_to_coverage (oct, sym->coverage); calc_weights (sym); sym->bitmap = coverage_to_bitmap (sym->coverage, CHAFA_SYMBOL_WIDTH_PIXELS); sym->popcount = chafa_population_count_u64 (sym->bitmap); i++; } return i; } static gboolean is_private_use (gunichar c) { return !!((c >= 0xe000 && c <= 0xf8ff) || (c >= 0xf0000 && c <= 0xfffff) || (c >= 0x100000 && c <= 0x10ffff)); } static ChafaSymbolTags get_default_tags_for_char (gunichar c) { ChafaSymbolTags tags = CHAFA_SYMBOL_TAG_NONE; if (g_unichar_iswide (c)) tags |= CHAFA_SYMBOL_TAG_WIDE; else if (g_unichar_iswide_cjk (c) && !is_private_use (c)) tags |= CHAFA_SYMBOL_TAG_AMBIGUOUS; if (g_unichar_ismark (c) || g_unichar_iszerowidth (c) || unichar_is_in_ranges (c, ambiguous_ranges)) tags |= CHAFA_SYMBOL_TAG_AMBIGUOUS; if (unichar_is_in_ranges (c, emoji_ranges) || unichar_is_in_ranges (c, meta_ranges)) tags |= CHAFA_SYMBOL_TAG_UGLY; if (c <= 0x7f) tags |= CHAFA_SYMBOL_TAG_ASCII; else if (c >= 0x2300 && c <= 0x23ff) tags |= CHAFA_SYMBOL_TAG_TECHNICAL; else if (c >= 0x25a0 && c <= 0x25ff) tags |= CHAFA_SYMBOL_TAG_GEOMETRIC; else if (c >= 0x2800 && c <= 0x28ff) tags |= CHAFA_SYMBOL_TAG_BRAILLE; else if (c >= 0x1fb00 && c <= 0x1fb3b) tags |= CHAFA_SYMBOL_TAG_SEXTANT; if (g_unichar_isalpha (c)) tags |= CHAFA_SYMBOL_TAG_ALPHA; if (g_unichar_isdigit (c)) tags |= CHAFA_SYMBOL_TAG_DIGIT; if (!(tags & CHAFA_SYMBOL_TAG_WIDE)) tags |= CHAFA_SYMBOL_TAG_NARROW; return tags; } static void def_to_symbol (const ChafaSymbolDef *def, ChafaSymbol *sym, gint x_ofs, gint rowstride) { sym->c = def->c; /* FIXME: g_unichar_iswide_cjk() will erroneously mark many of our * builtin symbols as ambiguous. Find a better way to deal with it. */ sym->sc = def->sc | (get_default_tags_for_char (def->c) & ~CHAFA_SYMBOL_TAG_AMBIGUOUS); sym->coverage = g_malloc (CHAFA_SYMBOL_N_PIXELS); outline_to_coverage (def->outline + x_ofs, sym->coverage, rowstride); sym->bitmap = coverage_to_bitmap (sym->coverage, CHAFA_SYMBOL_WIDTH_PIXELS); sym->popcount = chafa_population_count_u64 (sym->bitmap); calc_weights (sym); } static ChafaSymbol * init_symbol_array (const ChafaSymbolDef *defs) { ChafaSymbol *syms; gint i, j; syms = g_new0 (ChafaSymbol, CHAFA_N_SYMBOLS_MAX); for (i = 0, j = 0; defs [i].c; i++) { gint outline_len; outline_len = strlen (defs [i].outline); g_assert (outline_len == CHAFA_SYMBOL_N_PIXELS || outline_len == CHAFA_SYMBOL_N_PIXELS * 2); if (outline_len != CHAFA_SYMBOL_N_PIXELS || g_unichar_iswide (defs [i].c)) continue; def_to_symbol (&defs [i], &syms [j], 0, CHAFA_SYMBOL_WIDTH_PIXELS); j++; } j = generate_braille_syms (syms, j); j = generate_sextant_syms (syms, j); j = generate_octant_syms (syms, j); return syms; } static ChafaSymbol2 * init_symbol_array_wide (const ChafaSymbolDef *defs) { ChafaSymbol2 *syms; gint i, j; syms = g_new0 (ChafaSymbol2, CHAFA_N_SYMBOLS_MAX); for (i = 0, j = 0; defs [i].c; i++) { gint outline_len; outline_len = strlen (defs [i].outline); g_assert (outline_len == CHAFA_SYMBOL_N_PIXELS || outline_len == CHAFA_SYMBOL_N_PIXELS * 2); if (outline_len != CHAFA_SYMBOL_N_PIXELS * 2 || !g_unichar_iswide (defs [i].c)) continue; def_to_symbol (&defs [i], &syms [j].sym [0], 0, CHAFA_SYMBOL_WIDTH_PIXELS * 2); def_to_symbol (&defs [i], &syms [j].sym [1], CHAFA_SYMBOL_WIDTH_PIXELS, CHAFA_SYMBOL_WIDTH_PIXELS * 2); j++; } return syms; } void chafa_init_symbols (void) { if (symbols_initialized) return; chafa_symbols = init_symbol_array (symbol_defs); chafa_symbols2 = init_symbol_array_wide (symbol_defs); symbols_initialized = TRUE; } ChafaSymbolTags chafa_get_tags_for_char (gunichar c) { gint i; for (i = 0; symbol_defs [i].c; i++) { const ChafaSymbolDef *def = &symbol_defs [i]; if (def->c == c) return def->sc | (get_default_tags_for_char (def->c) & ~CHAFA_SYMBOL_TAG_AMBIGUOUS); } return get_default_tags_for_char (c); } chafa-1.18.2/chafa/internal/chafa-vector.h000066400000000000000000000126551517447374300202660ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_VECTOR_H__ #define __CHAFA_VECTOR_H__ #include #include G_BEGIN_DECLS #define CHAFA_VEC3F32_INIT(x, y, z) { { (x), (y), (z) } } #define CHAFA_VEC3F32_INIT_ZERO CHAFA_VEC3F32_INIT (0.0, 0.0, 0.0) typedef struct { gfloat v [3]; } ChafaVec3f32; typedef struct { gint32 v [3]; } ChafaVec3i32; static inline void chafa_vec3i32_set (ChafaVec3i32 *out, gint32 x, gint32 y, gint32 z) { out->v [0] = x; out->v [1] = y; out->v [2] = z; } static inline void chafa_vec3i32_sub (ChafaVec3i32 *out, const ChafaVec3i32 *a, const ChafaVec3i32 *b) { out->v [0] = a->v [0] - b->v [0]; out->v [1] = a->v [1] - b->v [1]; out->v [2] = a->v [2] - b->v [2]; } static inline void chafa_vec3i32_from_vec3f32 (ChafaVec3i32 *out, const ChafaVec3f32 *in) { /* lrintf() rounding can be extremely slow, so use this function * sparingly. We use tricks to make GCC emit cvtss2si instructions * ("-fno-math-errno -fno-trapping-math", or simply "-ffast-math"), * but Clang apparently cannot be likewise persuaded. * * Clang _does_ like rounding with SSE 4.1, but that's not something * we can enable by default. */ out->v [0] = lrintf (in->v [0]); out->v [1] = lrintf (in->v [1]); out->v [2] = lrintf (in->v [2]); } static inline gint32 chafa_vec3i32_dot_32 (const ChafaVec3i32 *v, const ChafaVec3i32 *u) { return v->v [0] * u->v [0] + v->v [1] * u->v [1] + v->v [2] * u->v [2]; } static inline gint64 chafa_vec3i32_dot_64 (const ChafaVec3i32 *v, const ChafaVec3i32 *u) { return (gint64) v->v [0] * u->v [0] + (gint64) v->v [1] * u->v [1] + (gint64) v->v [2] * u->v [2]; } static inline void chafa_vec3f32_set (ChafaVec3f32 *v, gfloat x, gfloat y, gfloat z) { v->v [0] = x; v->v [1] = y; v->v [2] = z; } static inline void chafa_vec3f32_set_zero (ChafaVec3f32 *v) { chafa_vec3f32_set (v, 0.0f, 0.0f, 0.0f); } static inline void chafa_vec3f32_copy (ChafaVec3f32 *dest, const ChafaVec3f32 *src) { *dest = *src; } static inline void chafa_vec3f32_add (ChafaVec3f32 *out, const ChafaVec3f32 *a, const ChafaVec3f32 *b) { out->v [0] = a->v [0] + b->v [0]; out->v [1] = a->v [1] + b->v [1]; out->v [2] = a->v [2] + b->v [2]; } static inline void chafa_vec3f32_sub (ChafaVec3f32 *out, const ChafaVec3f32 *a, const ChafaVec3f32 *b) { out->v [0] = a->v [0] - b->v [0]; out->v [1] = a->v [1] - b->v [1]; out->v [2] = a->v [2] - b->v [2]; } static inline void chafa_vec3f32_add_from_array (ChafaVec3f32 *accum, const ChafaVec3f32 *v, gint n) { gint i; for (i = 0; i < n; i++) { chafa_vec3f32_add (accum, accum, &v [i]); } } static inline void chafa_vec3f32_add_to_array (ChafaVec3f32 *v, const ChafaVec3f32 *in, gint n) { gint i; for (i = 0; i < n; i++) { chafa_vec3f32_add (&v [i], &v [i], in); } } static inline gfloat chafa_vec3f32_sum_to_scalar (const ChafaVec3f32 *v) { return v->v [0] + v->v [1] + v->v [2]; } static inline void chafa_vec3f32_mul_scalar (ChafaVec3f32 *out, const ChafaVec3f32 *in, gfloat s) { out->v [0] = in->v [0] * s; out->v [1] = in->v [1] * s; out->v [2] = in->v [2] * s; } static inline gfloat chafa_vec3f32_dot (const ChafaVec3f32 *v, const ChafaVec3f32 *u) { return v->v [0] * u->v [0] + v->v [1] * u->v [1] + v->v [2] * u->v [2]; } static inline void chafa_vec3f32_hadamard (ChafaVec3f32 *out, const ChafaVec3f32 *v, const ChafaVec3f32 *u) { out->v [0] = v->v [0] * u->v [0]; out->v [1] = v->v [1] * u->v [1]; out->v [2] = v->v [2] * u->v [2]; } static inline gfloat chafa_vec3f32_get_magnitude (const ChafaVec3f32 *v) { return sqrtf (v->v [0] * v->v [0] + v->v [1] * v->v [1] + v->v [2] * v->v [2]); } static inline void chafa_vec3f32_normalize (ChafaVec3f32 *out, const ChafaVec3f32 *in) { gfloat mag; gfloat m; mag = chafa_vec3f32_get_magnitude (in); if (mag == .0f) { /* Normalize zero-length to (0,0,0) */ out->v [0] = out->v [1] = out->v [2] = .0f; return; } m = 1.0f / mag; out->v [0] = in->v [0] * m; out->v [1] = in->v [1] * m; out->v [2] = in->v [2] * m; } static inline void chafa_vec3f32_round (ChafaVec3f32 *out, const ChafaVec3f32 *in) { out->v [0] = rintf (in->v [0]); out->v [1] = rintf (in->v [1]); out->v [2] = rintf (in->v [2]); } static inline void chafa_vec3f32_average_array (ChafaVec3f32 *out, const ChafaVec3f32 *v, gint n) { chafa_vec3f32_set_zero (out); chafa_vec3f32_add_from_array (out, v, n); chafa_vec3f32_mul_scalar (out, out, 1.0f / (gfloat) n); } G_END_DECLS #endif /* __CHAFA_VECTOR_H__ */ chafa-1.18.2/chafa/internal/chafa-work-cell.c000066400000000000000000000250661517447374300206560ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include "chafa.h" #include "internal/chafa-private.h" #include "internal/chafa-pixops.h" #include "internal/chafa-work-cell.h" static void accum_to_color (const ChafaColorAccum *accum, ChafaColor *color) { gint i; for (i = 0; i < 4; i++) color->ch [i] = accum->ch [i]; } /* pixels_out must point to CHAFA_SYMBOL_N_PIXELS-element array */ static void fetch_canvas_pixel_block (const ChafaPixel *src_image, gint src_width, ChafaPixel *pixels_out, gint cx, gint cy) { const ChafaPixel *row_p; const ChafaPixel *end_p; gint i = 0; row_p = src_image + cy * CHAFA_SYMBOL_HEIGHT_PIXELS * src_width + cx * CHAFA_SYMBOL_WIDTH_PIXELS; end_p = row_p + (src_width * CHAFA_SYMBOL_HEIGHT_PIXELS); for ( ; row_p < end_p; row_p += src_width) { memcpy (&pixels_out [i], row_p, CHAFA_SYMBOL_WIDTH_PIXELS * sizeof (ChafaPixel)); i += CHAFA_SYMBOL_WIDTH_PIXELS; } } static void extract_cell_mean_colors_plain (const ChafaPixel *block, ChafaColorAccum *accums, const guint8 *cov) { const guint8 *in_u8 = (const guint8 *) block; gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { gint16 *out_s16 = accums [*cov++].ch; *out_s16++ += *in_u8++; *out_s16++ += *in_u8++; *out_s16++ += *in_u8++; *out_s16++ += *in_u8++; } } void chafa_work_cell_get_mean_colors_for_symbol (const ChafaWorkCell *wcell, const ChafaSymbol *sym, ChafaColorPair *color_pair_out) { const guint8 *covp = (guint8 *) &sym->coverage [0]; ChafaColorAccum accums [2] = { 0 }; #ifdef HAVE_AVX2_INTRINSICS if (chafa_have_avx2 ()) chafa_extract_cell_mean_colors_avx2 (wcell->pixels, accums, sym->mask_u32); else #elif defined(HAVE_MMX_INTRINSICS) if (chafa_have_mmx ()) chafa_extract_cell_mean_colors_mmx (wcell->pixels, accums, covp); else #endif extract_cell_mean_colors_plain (wcell->pixels, accums, covp); if (sym->fg_weight > 1) chafa_color_accum_div_scalar (&accums [1], sym->fg_weight); if (sym->bg_weight > 1) chafa_color_accum_div_scalar (&accums [0], sym->bg_weight); accum_to_color (&accums [0], &color_pair_out->colors [CHAFA_COLOR_PAIR_BG]); accum_to_color (&accums [1], &color_pair_out->colors [CHAFA_COLOR_PAIR_FG]); } void chafa_work_cell_calc_mean_color (const ChafaWorkCell *wcell, ChafaColor *color_out) { ChafaColorAccum accum = { 0 }; const ChafaPixel *block = wcell->pixels; gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { chafa_color_accum_add (&accum, &block->col); block++; } chafa_color_accum_div_scalar (&accum, CHAFA_SYMBOL_N_PIXELS); accum_to_color (&accum, color_out); } guint64 chafa_work_cell_to_bitmap (const ChafaWorkCell *wcell, const ChafaColorPair *color_pair) { guint64 bitmap = 0; const ChafaPixel *block = wcell->pixels; gint i; for (i = 0; i < CHAFA_SYMBOL_N_PIXELS; i++) { gint error [2]; bitmap <<= 1; /* FIXME: What to do about alpha? */ error [0] = chafa_color_diff_fast (&block [i].col, &color_pair->colors [0]); error [1] = chafa_color_diff_fast (&block [i].col, &color_pair->colors [1]); if (error [0] > error [1]) bitmap |= 1; } return bitmap; } /* Get cell's pixels sorted by a specific channel. Sorts on demand and caches * the results. */ static const guint8 * work_cell_get_sorted_pixels (ChafaWorkCell *wcell, gint ch) { guint8 *index; index = &wcell->pixels_sorted_index [ch] [0]; if (wcell->have_pixels_sorted_by_channel [ch]) return index; chafa_sort_pixel_index_by_channel (index, wcell->pixels, CHAFA_SYMBOL_N_PIXELS, ch); wcell->have_pixels_sorted_by_channel [ch] = TRUE; return index; } void chafa_work_cell_init (ChafaWorkCell *wcell, const ChafaPixel *src_image, gint src_width, gint cx, gint cy) { memset (wcell->have_pixels_sorted_by_channel, 0, sizeof (wcell->have_pixels_sorted_by_channel)); fetch_canvas_pixel_block (src_image, src_width, wcell->pixels, cx, cy); wcell->dominant_channel = -1; } static gint work_cell_get_dominant_channel (ChafaWorkCell *wcell) { const guint8 *sorted_pixels [4]; gint best_range; gint best_ch; gint i; if (wcell->dominant_channel >= 0) return wcell->dominant_channel; for (i = 0; i < 4; i++) sorted_pixels [i] = work_cell_get_sorted_pixels (wcell, i); best_range = wcell->pixels [sorted_pixels [0] [CHAFA_SYMBOL_N_PIXELS - 1]].col.ch [0] - wcell->pixels [sorted_pixels [0] [0]].col.ch [0]; best_ch = 0; for (i = 1; i < 4; i++) { gint range = wcell->pixels [sorted_pixels [i] [CHAFA_SYMBOL_N_PIXELS - 1]].col.ch [i] - wcell->pixels [sorted_pixels [i] [0]].col.ch [i]; if (range > best_range) { best_range = range; best_ch = i; } } wcell->dominant_channel = best_ch; return wcell->dominant_channel; } static void work_cell_get_dominant_channels_for_symbol (ChafaWorkCell *wcell, const ChafaSymbol *sym, gint *bg_ch_out, gint *fg_ch_out) { gint16 min [2] [4] = { { G_MAXINT16, G_MAXINT16, G_MAXINT16, G_MAXINT16 }, { G_MAXINT16, G_MAXINT16, G_MAXINT16, G_MAXINT16 } }; gint16 max [2] [4] = { { G_MININT16, G_MININT16, G_MININT16, G_MININT16 }, { G_MININT16, G_MININT16, G_MININT16, G_MININT16 } }; gint16 range [2] [4]; gint ch, best_ch [2]; const guint8 *sorted_pixels [4]; gint i, j; if (sym->popcount == 0) { *bg_ch_out = work_cell_get_dominant_channel (wcell); *fg_ch_out = -1; return; } else if (sym->popcount == CHAFA_SYMBOL_N_PIXELS) { *bg_ch_out = -1; *fg_ch_out = work_cell_get_dominant_channel (wcell); return; } for (i = 0; i < 4; i++) sorted_pixels [i] = work_cell_get_sorted_pixels (wcell, i); /* Get minimums */ for (j = 0; j < 4; j++) { gint pen_a = sym->coverage [sorted_pixels [j] [0]]; min [pen_a] [j] = wcell->pixels [sorted_pixels [j] [0]].col.ch [j]; for (i = 1; ; i++) { gint pen_b = sym->coverage [sorted_pixels [j] [i]]; if (pen_b != pen_a) { min [pen_b] [j] = wcell->pixels [sorted_pixels [j] [i]].col.ch [j]; break; } } } /* Get maximums */ for (j = 0; j < 4; j++) { gint pen_a = sym->coverage [sorted_pixels [j] [CHAFA_SYMBOL_N_PIXELS - 1]]; max [pen_a] [j] = wcell->pixels [sorted_pixels [j] [CHAFA_SYMBOL_N_PIXELS - 1]].col.ch [j]; for (i = CHAFA_SYMBOL_N_PIXELS - 2; ; i--) { gint pen_b = sym->coverage [sorted_pixels [j] [i]]; if (pen_b != pen_a) { max [pen_b] [j] = wcell->pixels [sorted_pixels [j] [i]].col.ch [j]; break; } } } /* Find channel with the greatest range */ for (ch = 0; ch < 4; ch++) { range [0] [ch] = max [0] [ch] - min [0] [ch]; range [1] [ch] = max [1] [ch] - min [1] [ch]; } best_ch [0] = 0; best_ch [1] = 0; for (ch = 1; ch < 4; ch++) { if (range [0] [ch] > range [0] [best_ch [0]]) best_ch [0] = ch; if (range [1] [ch] > range [1] [best_ch [1]]) best_ch [1] = ch; } *bg_ch_out = best_ch [0]; *fg_ch_out = best_ch [1]; } void chafa_work_cell_get_contrasting_color_pair (ChafaWorkCell *wcell, ChafaColorPair *color_pair_out) { const guint8 *sorted_pixels; sorted_pixels = work_cell_get_sorted_pixels (wcell, work_cell_get_dominant_channel (wcell)); /* Choose two colors by median cut */ color_pair_out->colors [CHAFA_COLOR_PAIR_BG] = wcell->pixels [sorted_pixels [0]].col; color_pair_out->colors [CHAFA_COLOR_PAIR_FG] = wcell->pixels [sorted_pixels [CHAFA_SYMBOL_N_PIXELS - 1]].col; } static const ChafaPixel * work_cell_get_nth_sorted_pixel (ChafaWorkCell *wcell, const ChafaSymbol *sym, gint channel, gint pen, gint n) { const guint8 *sorted_pixels; gint i, j; pen ^= 1; sorted_pixels = work_cell_get_sorted_pixels (wcell, channel); for (i = 0, j = 0; ; i++) { j += (sym->coverage [sorted_pixels [i]] ^ pen); if (j > n) return &wcell->pixels [sorted_pixels [i]]; } g_assert_not_reached (); return NULL; } void chafa_work_cell_get_median_colors_for_symbol (ChafaWorkCell *wcell, const ChafaSymbol *sym, ChafaColorPair *color_pair_out) { gint bg_ch, fg_ch; /* This is extremely slow and makes almost no difference */ work_cell_get_dominant_channels_for_symbol (wcell, sym, &bg_ch, &fg_ch); if (bg_ch < 0) { color_pair_out->colors [0] = color_pair_out->colors [1] = work_cell_get_nth_sorted_pixel (wcell, sym, fg_ch, 1, sym->popcount / 2)->col; } else if (fg_ch < 0) { color_pair_out->colors [0] = color_pair_out->colors [1] = work_cell_get_nth_sorted_pixel (wcell, sym, bg_ch, 0, (CHAFA_SYMBOL_N_PIXELS - sym->popcount) / 2)->col; } else { color_pair_out->colors [CHAFA_COLOR_PAIR_FG] = work_cell_get_nth_sorted_pixel (wcell, sym, fg_ch, 1, sym->popcount / 2)->col; color_pair_out->colors [CHAFA_COLOR_PAIR_BG] = work_cell_get_nth_sorted_pixel (wcell, sym, bg_ch, 0, (CHAFA_SYMBOL_N_PIXELS - sym->popcount) / 2)->col; } } chafa-1.18.2/chafa/internal/chafa-work-cell.h000066400000000000000000000041701517447374300206540ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_WORK_CELL_H__ #define __CHAFA_WORK_CELL_H__ G_BEGIN_DECLS typedef struct ChafaWorkCell ChafaWorkCell; struct ChafaWorkCell { ChafaPixel pixels [CHAFA_SYMBOL_N_PIXELS]; guint8 pixels_sorted_index [4] [CHAFA_SYMBOL_N_PIXELS]; guint8 have_pixels_sorted_by_channel [4]; gint dominant_channel; }; /* Currently unused */ typedef enum { CHAFA_PICK_CONSIDER_INVERTED = (1 << 0), CHAFA_PICK_HAVE_ALPHA = (1 << 1) } ChafaPickFlags; void chafa_work_cell_init (ChafaWorkCell *wcell, const ChafaPixel *src_image, gint src_width, gint cx, gint cy); void chafa_work_cell_get_mean_colors_for_symbol (const ChafaWorkCell *wcell, const ChafaSymbol *sym, ChafaColorPair *color_pair_out); void chafa_work_cell_get_median_colors_for_symbol (ChafaWorkCell *wcell, const ChafaSymbol *sym, ChafaColorPair *color_pair_out); void chafa_work_cell_get_contrasting_color_pair (ChafaWorkCell *wcell, ChafaColorPair *color_pair_out); void chafa_work_cell_calc_mean_color (const ChafaWorkCell *wcell, ChafaColor *color_out); guint64 chafa_work_cell_to_bitmap (const ChafaWorkCell *wcell, const ChafaColorPair *color_pair); G_END_DECLS #endif /* __CHAFA_WORK_CELL_H__ */ chafa-1.18.2/chafa/internal/smolscale/000077500000000000000000000000001517447374300175245ustar00rootroot00000000000000chafa-1.18.2/chafa/internal/smolscale/COPYING000066400000000000000000000013301517447374300205540ustar00rootroot00000000000000This software is Copyright © 2019 Hans Petter Jansson. All rights reserved. You may use and redistribute this software under the terms and conditions laid out in either the BSD 4-clause license (see COPYING.BSD-4) or the LGPL version 3 (see COPYING.LGPLv3). The practical intent is that you should be able to use the software in an LGPLv3-compatible project without giving credit (although it would be nice if you did so). However, if you're using it in a closed-source project, you must either publish it separately in an LGPLv3-licensed library and link with that, or credit the contributors in your advertising materials. If you want to use it under a different license, feel free to contact me by e-mail at . chafa-1.18.2/chafa/internal/smolscale/COPYING.BSD-4000066400000000000000000000032751517447374300213360ustar00rootroot00000000000000Copyright © 2019 Hans Petter Jansson. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 4. All advertising materials mentioning features or use of this software must display the following acknowledgement: 'This product includes software developed by Hans Petter Jansson (https://hpjansson.org/).' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. chafa-1.18.2/chafa/internal/smolscale/COPYING.LGPLv3000066400000000000000000000167441517447374300216010ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. chafa-1.18.2/chafa/internal/smolscale/Makefile.am000066400000000000000000000014041517447374300215570ustar00rootroot00000000000000noinst_LTLIBRARIES = libsmolscale.la SMOLSCALE_CFLAGS = $(LIBCHAFA_CFLAGS) SMOLSCALE_LDFLAGS = $(LIBCHAFA_LDFLAGS) if HAVE_AVX2_INTRINSICS SMOLSCALE_CFLAGS += -DSMOL_WITH_AVX2 endif if !HAVE_BUILTIN_ASSUME_ALIGNED SMOLSCALE_CFLAGS += -DSMOL_DISABLE_ASSUME_ALIGNED endif libsmolscale_la_CFLAGS = $(SMOLSCALE_CFLAGS) libsmolscale_la_LDFLAGS = $(SMOLSCALE_LDFLAGS) libsmolscale_la_LIBADD = libsmolscale_la_SOURCES = \ smolscale.c \ smolscale.h \ smolscale-generic.c \ smolscale-private.h if HAVE_AVX2_INTRINSICS noinst_LTLIBRARIES += libsmolscale-avx2.la libsmolscale_la_LIBADD += libsmolscale-avx2.la libsmolscale_avx2_la_SOURCES = smolscale-avx2.c libsmolscale_avx2_la_CFLAGS = $(SMOLSCALE_CFLAGS) -mavx2 libsmolscale_avx2_la_LDFLAGS = $(SMOLSCALE_LDFLAGS) endif chafa-1.18.2/chafa/internal/smolscale/README000066400000000000000000000025041517447374300204050ustar00rootroot00000000000000Smolscale ========= Smolscale is a smol piece of C code for quickly scaling images to a reasonable level of quality using CPU resources only (no GPU). It operates on 4-channel data with 32 bits per pixel, i.e. packed RGBA, ARGB, BGRA, etc. It supports both premultiplied and unassociated alpha and can convert between the two. It is host byte ordering agnostic. The design goals are: * High throughput: Optimized code, within reason. Easily parallelizable. * Decent quality: No "jaggies" as produced by nearest-neighbor scaling. * Low memory overhead: Mostly on the stack. * Simplicity: A modern C toolchain as the only dependency. * Ease of use: One-shot and row-batch APIs. Usage ----- First, read COPYING. If your project meets the requirements, you should be able to copy the following files into it and add it to your build with minimal fuss: smolscale.c smolscale.h smolscale-private.h If you want AVX2 SIMD support, optionally copy this additional file and compile everything with -DSMOL_WITH_AVX2: smolscale-avx2.c Keep in mind that this file is mostly just a straight copy of the generic code for the time being. Still, you will get a performance boost by building it with -mavx2 and letting Smolscale pick the implementation at runtime. The API documentation lives in smolscale.h along with the public declarations. chafa-1.18.2/chafa/internal/smolscale/smolscale-avx2.c000066400000000000000000004121401517447374300225320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright © 2019-2025 Hans Petter Jansson. See COPYING for details. */ #include /* assert */ #include /* malloc, free, alloca */ #include /* ptrdiff_t */ #include /* memset */ #include #include #include "smolscale-private.h" /* ---------------------- * * Context initialization * * ---------------------- */ /* Number of horizontal pixels to process in a single batch. The define exists for * clarity and cannot be changed without significant changes to the code elsewhere. */ #define BILIN_HORIZ_BATCH_PIXELS 16 /* Batched precalc array layout: * * 16 offsets followed by 16 factors, repeating until epilogue. The epilogue * has offsets and factors alternating one by one, and will always have fewer * than 16 o/f pairs: * * ooooooooooooooooffffffffffffffffooooooooooooooooffffffffffffffffofofofofof... * * 16 offsets layout: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 * 16 factors layout: 0 2 4 6 8 10 12 14 1 3 5 7 9 11 13 15 */ static uint32_t array_offset_offset (uint32_t elem_i, int max_index, int do_batches) { if (do_batches && (max_index - ((elem_i / BILIN_HORIZ_BATCH_PIXELS) * BILIN_HORIZ_BATCH_PIXELS) >= BILIN_HORIZ_BATCH_PIXELS)) { return (elem_i / (BILIN_HORIZ_BATCH_PIXELS)) * (BILIN_HORIZ_BATCH_PIXELS * 2) + (elem_i % BILIN_HORIZ_BATCH_PIXELS); } else { return elem_i * 2; } } static uint32_t array_offset_factor (uint32_t elem_i, int max_index, int do_batches) { const uint8_t o [BILIN_HORIZ_BATCH_PIXELS] = { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 }; if (do_batches && (max_index - ((elem_i / BILIN_HORIZ_BATCH_PIXELS) * BILIN_HORIZ_BATCH_PIXELS) >= BILIN_HORIZ_BATCH_PIXELS)) { return (elem_i / (BILIN_HORIZ_BATCH_PIXELS)) * (BILIN_HORIZ_BATCH_PIXELS * 2) + BILIN_HORIZ_BATCH_PIXELS + o [elem_i % BILIN_HORIZ_BATCH_PIXELS]; } else { return elem_i * 2 + 1; } } static void precalc_linear_range (uint16_t *array_out, int first_index, int last_index, int max_index, uint64_t first_sample_ofs, uint64_t sample_step, int sample_ofs_px_max, int32_t dest_clip_before_px, int do_batches, int *array_i_inout) { uint64_t sample_ofs; int i; sample_ofs = first_sample_ofs; for (i = first_index; i < last_index; i++) { uint16_t sample_ofs_px = sample_ofs / SMOL_BILIN_MULTIPLIER; if (sample_ofs_px >= sample_ofs_px_max - 1) { if (i >= dest_clip_before_px) { array_out [array_offset_offset ((*array_i_inout), max_index, do_batches)] = sample_ofs_px_max - 2; array_out [array_offset_factor ((*array_i_inout), max_index, do_batches)] = 0; (*array_i_inout)++; } continue; } if (i >= dest_clip_before_px) { array_out [array_offset_offset ((*array_i_inout), max_index, do_batches)] = sample_ofs_px; array_out [array_offset_factor ((*array_i_inout), max_index, do_batches)] = SMOL_SMALL_MUL - ((sample_ofs / (SMOL_BILIN_MULTIPLIER / SMOL_SMALL_MUL)) % SMOL_SMALL_MUL); (*array_i_inout)++; } sample_ofs += sample_step; } } static void precalc_bilinear_array (uint16_t *array, uint64_t src_dim_spx, uint64_t dest_ofs_spx, uint64_t dest_dim_spx, uint32_t dest_dim_prehalving_px, unsigned int n_halvings, int32_t dest_clip_before_px, int32_t dest_clip_after_px, unsigned int do_batches) { uint32_t src_dim_px = SMOL_SPX_TO_PX (src_dim_spx); uint64_t first_sample_ofs [3]; uint64_t sample_step; int i = 0; assert (src_dim_px > 1); dest_ofs_spx %= SMOL_SUBPIXEL_MUL; if (src_dim_spx > dest_dim_spx) { /* Minification */ sample_step = ((uint64_t) src_dim_spx * SMOL_BILIN_MULTIPLIER) / dest_dim_spx; first_sample_ofs [0] = (sample_step - SMOL_BILIN_MULTIPLIER) / 2; first_sample_ofs [1] = ((sample_step - SMOL_BILIN_MULTIPLIER) / 2) + ((sample_step * (SMOL_SUBPIXEL_MUL - dest_ofs_spx) * (1 << n_halvings)) / SMOL_SUBPIXEL_MUL); } else { /* Magnification */ sample_step = ((src_dim_spx - SMOL_SUBPIXEL_MUL) * SMOL_BILIN_MULTIPLIER) / (dest_dim_spx > SMOL_SUBPIXEL_MUL ? (dest_dim_spx - SMOL_SUBPIXEL_MUL) : 1); first_sample_ofs [0] = 0; first_sample_ofs [1] = (sample_step * (SMOL_SUBPIXEL_MUL - dest_ofs_spx)) / SMOL_SUBPIXEL_MUL; } first_sample_ofs [2] = ((((uint64_t) src_dim_spx * SMOL_BILIN_MULTIPLIER * 2) / SMOL_SUBPIXEL_MUL) + sample_step - SMOL_BILIN_MULTIPLIER) / 2 - sample_step * (1U << n_halvings); /* Left fringe */ precalc_linear_range (array, 0, 1 << n_halvings, dest_dim_prehalving_px - dest_clip_after_px, first_sample_ofs [0], sample_step, src_dim_px, dest_clip_before_px, do_batches, &i); /* Check to prevent overruns when the output size is exactly 1 */ if (dest_dim_prehalving_px > (1U << n_halvings)) { /* Main range */ precalc_linear_range (array, 1 << n_halvings, dest_dim_prehalving_px - (1 << n_halvings), dest_dim_prehalving_px - dest_clip_after_px, first_sample_ofs [1], sample_step, src_dim_px, dest_clip_before_px, do_batches, &i); /* Right fringe */ precalc_linear_range (array, dest_dim_prehalving_px - (1 << n_halvings), dest_dim_prehalving_px, dest_dim_prehalving_px - dest_clip_after_px, first_sample_ofs [2], sample_step, src_dim_px, dest_clip_before_px, do_batches, &i); } } static void precalc_boxes_array (uint32_t *array, uint32_t *span_step, uint32_t *span_mul, uint32_t src_dim_spx, int32_t dest_dim, uint32_t dest_ofs_spx, uint32_t dest_dim_spx, int32_t dest_clip_before_px) { uint64_t fracF, frac_stepF; uint64_t f; uint64_t stride; uint64_t a, b; int i, dest_i; dest_ofs_spx %= SMOL_SUBPIXEL_MUL; /* Output sample can't be less than a pixel. Fringe opacity is applied in * a separate step. FIXME: May cause wrong subpixel distribution -- revisit. */ if (dest_dim_spx < 256) dest_dim_spx = 256; frac_stepF = ((uint64_t) src_dim_spx * SMOL_BIG_MUL) / (uint64_t) dest_dim_spx; fracF = 0; stride = frac_stepF / (uint64_t) SMOL_BIG_MUL; f = (frac_stepF / SMOL_SMALL_MUL) % SMOL_SMALL_MUL; /* We divide by (b + 1) instead of just (b) to avoid overflows in * scale_128bpp_half(), which would affect horizontal box scaling. The * fudge factor counters limited precision in the inverted division * operation. It causes 16-bit values to undershoot by less than 127/65535 * (<.2%). Since the final output is 8-bit, and rounding neutralizes the * error, this doesn't matter. */ a = (SMOL_BOXES_MULTIPLIER * 255); b = ((stride * 255) + ((f * 255) / 256)); *span_step = frac_stepF / SMOL_SMALL_MUL; *span_mul = (a + (b / 2)) / (b + 1); /* Left fringe */ i = 0; dest_i = 0; if (dest_i >= dest_clip_before_px) array [i++] = 0; /* Main range */ fracF = ((frac_stepF * (SMOL_SUBPIXEL_MUL - dest_ofs_spx)) / SMOL_SUBPIXEL_MUL); for (dest_i = 1; dest_i < dest_dim - 1; dest_i++) { if (dest_i >= dest_clip_before_px) array [i++] = fracF / SMOL_SMALL_MUL; fracF += frac_stepF; } /* Right fringe */ if (dest_dim > 1 && dest_i >= dest_clip_before_px) array [i++] = (((uint64_t) src_dim_spx * SMOL_SMALL_MUL - frac_stepF) / SMOL_SMALL_MUL); } static void init_dim (SmolDim *dim, int do_batches) { if (dim->filter_type == SMOL_FILTER_ONE || dim->filter_type == SMOL_FILTER_COPY) { } else if (dim->filter_type == SMOL_FILTER_BOX) { precalc_boxes_array (dim->precalc, &dim->span_step, &dim->span_mul, dim->src_size_spx, dim->placement_size_px, dim->placement_ofs_spx, dim->placement_size_spx, dim->clip_before_px); } else /* SMOL_FILTER_BILINEAR_?H */ { precalc_bilinear_array (dim->precalc, dim->src_size_spx, dim->placement_ofs_spx, dim->placement_size_prehalving_spx, dim->placement_size_prehalving_px, dim->n_halvings, dim->clip_before_px, dim->clip_after_px, do_batches); } } static void init_horizontal (SmolScaleCtx *scale_ctx) { init_dim (&scale_ctx->hdim, scale_ctx->storage_type == SMOL_STORAGE_64BPP ? TRUE : FALSE); } static void init_vertical (SmolScaleCtx *scale_ctx) { init_dim (&scale_ctx->vdim, FALSE); } /* ----------------- * * Premultiplication * * ----------------- */ static SMOL_INLINE void premul_u_to_p8_128bpp (uint64_t * SMOL_RESTRICT inout, uint8_t alpha) { inout [0] = (((inout [0] + 0x0000000100000001) * ((uint16_t) alpha + 1) - 0x0000000100000001) >> 8) & 0x000000ff000000ff; inout [1] = (((inout [1] + 0x0000000100000001) * ((uint16_t) alpha + 1) - 0x0000000100000001) >> 8) & 0x000000ff000000ff; } static SMOL_INLINE void unpremul_p8_to_u_128bpp (const uint64_t *in, uint64_t *out, uint8_t alpha) { out [0] = ((in [0] * _smol_inv_div_p8_lut [alpha]) >> INVERTED_DIV_SHIFT_P8) & 0x000000ff000000ff; out [1] = ((in [1] * _smol_inv_div_p8_lut [alpha]) >> INVERTED_DIV_SHIFT_P8) & 0x000000ff000000ff; } static SMOL_INLINE uint64_t premul_u_to_p8_64bpp (const uint64_t in, uint8_t alpha) { return (((in + 0x0001000100010001) * ((uint16_t) alpha + 1) - 0x0001000100010001) >> 8) & 0x00ff00ff00ff00ff; } static SMOL_INLINE uint64_t unpremul_p8_to_u_64bpp (const uint64_t in, uint8_t alpha) { uint64_t in_128bpp [2]; uint64_t out_128bpp [2]; in_128bpp [0] = (in & 0x000000ff000000ff); in_128bpp [1] = (in & 0x00ff000000ff0000) >> 16; unpremul_p8_to_u_128bpp (in_128bpp, out_128bpp, alpha); return out_128bpp [0] | (out_128bpp [1] << 16); } static SMOL_INLINE void premul_u_to_p16_128bpp (uint64_t *inout, uint8_t alpha) { inout [0] = inout [0] * alpha; inout [1] = inout [1] * alpha; } static SMOL_INLINE void unpremul_p16_to_u_128bpp (const uint64_t * SMOL_RESTRICT in, uint64_t * SMOL_RESTRICT out, uint8_t alpha) { out [0] = ((in [0] * _smol_inv_div_p16_lut [alpha]) >> INVERTED_DIV_SHIFT_P16) & 0x000000ff000000ffULL; out [1] = ((in [1] * _smol_inv_div_p16_lut [alpha]) >> INVERTED_DIV_SHIFT_P16) & 0x000000ff000000ffULL; } /* --------- * * Repacking * * --------- */ /* PACK_SHUF_MM256_EPI8_32_TO_128() * * Generates a shuffling register for packing 8bpc pixel channels in the * provided order. The order (1, 2, 3, 4) is neutral and corresponds to * * _mm256_set_epi8 (13,12,15,14, 9,8,11,10, 5,4,7,6, 1,0,3,2, * 13,12,15,14, 9,8,11,10, 5,4,7,6, 1,0,3,2); */ #define SHUF_ORDER_32_TO_128 0x01000302U #define SHUF_CH_32_TO_128(n) ((char) (SHUF_ORDER_32_TO_128 >> ((4 - (n)) * 8))) #define SHUF_QUAD_CH_32_TO_128(q, n) (4 * (q) + SHUF_CH_32_TO_128 (n)) #define SHUF_QUAD_32_TO_128(q, a, b, c, d) \ SHUF_QUAD_CH_32_TO_128 ((q), (a)), \ SHUF_QUAD_CH_32_TO_128 ((q), (b)), \ SHUF_QUAD_CH_32_TO_128 ((q), (c)), \ SHUF_QUAD_CH_32_TO_128 ((q), (d)) #define PACK_SHUF_EPI8_LANE_32_TO_128(a, b, c, d) \ SHUF_QUAD_32_TO_128 (3, (a), (b), (c), (d)), \ SHUF_QUAD_32_TO_128 (2, (a), (b), (c), (d)), \ SHUF_QUAD_32_TO_128 (1, (a), (b), (c), (d)), \ SHUF_QUAD_32_TO_128 (0, (a), (b), (c), (d)) #define PACK_SHUF_MM256_EPI8_32_TO_128(a, b, c, d) _mm256_set_epi8 ( \ PACK_SHUF_EPI8_LANE_32_TO_128 ((a), (b), (c), (d)), \ PACK_SHUF_EPI8_LANE_32_TO_128 ((a), (b), (c), (d))) /* PACK_SHUF_MM256_EPI8_32_TO_64() * * 64bpp version. Packs only once, so fewer contortions required. */ #define SHUF_CH_32_TO_64(n) ((char) (4 - (n))) #define SHUF_QUAD_CH_32_TO_64(q, n) (4 * (q) + SHUF_CH_32_TO_64 (n)) #define SHUF_QUAD_32_TO_64(q, a, b, c, d) \ SHUF_QUAD_CH_32_TO_64 ((q), (a)), \ SHUF_QUAD_CH_32_TO_64 ((q), (b)), \ SHUF_QUAD_CH_32_TO_64 ((q), (c)), \ SHUF_QUAD_CH_32_TO_64 ((q), (d)) #define PACK_SHUF_EPI8_LANE_32_TO_64(a, b, c, d) \ SHUF_QUAD_32_TO_64 (3, (a), (b), (c), (d)), \ SHUF_QUAD_32_TO_64 (2, (a), (b), (c), (d)), \ SHUF_QUAD_32_TO_64 (1, (a), (b), (c), (d)), \ SHUF_QUAD_32_TO_64 (0, (a), (b), (c), (d)) #define PACK_SHUF_MM256_EPI8_32_TO_64(a, b, c, d) _mm256_set_epi8 ( \ PACK_SHUF_EPI8_LANE_32_TO_64 ((a), (b), (c), (d)), \ PACK_SHUF_EPI8_LANE_32_TO_64 ((a), (b), (c), (d))) /* It's nice to be able to shift by a negative amount */ #define SHIFT_S(in, s) ((s >= 0) ? (in) << (s) : (in) >> -(s)) /* This is kind of bulky (~13 x86 insns), but it's about the same as using * unions, and we don't have to worry about endianness. */ #define PACK_FROM_1234_64BPP(in, a, b, c, d) \ ((SHIFT_S ((in), ((a) - 1) * 16 + 8 - 32) & 0xff000000) \ | (SHIFT_S ((in), ((b) - 1) * 16 + 8 - 40) & 0x00ff0000) \ | (SHIFT_S ((in), ((c) - 1) * 16 + 8 - 48) & 0x0000ff00) \ | (SHIFT_S ((in), ((d) - 1) * 16 + 8 - 56) & 0x000000ff)) #define PACK_FROM_1234_128BPP(in, a, b, c, d) \ ((SHIFT_S ((in [((a) - 1) >> 1]), (((a) - 1) & 1) * 32 + 24 - 32) & 0xff000000) \ | (SHIFT_S ((in [((b) - 1) >> 1]), (((b) - 1) & 1) * 32 + 24 - 40) & 0x00ff0000) \ | (SHIFT_S ((in [((c) - 1) >> 1]), (((c) - 1) & 1) * 32 + 24 - 48) & 0x0000ff00) \ | (SHIFT_S ((in [((d) - 1) >> 1]), (((d) - 1) & 1) * 32 + 24 - 56) & 0x000000ff)) #define SWAP_2_AND_3(n) ((n) == 2 ? 3 : (n) == 3 ? 2 : n) #define PACK_FROM_1324_64BPP(in, a, b, c, d) \ ((SHIFT_S ((in), (SWAP_2_AND_3 (a) - 1) * 16 + 8 - 32) & 0xff000000) \ | (SHIFT_S ((in), (SWAP_2_AND_3 (b) - 1) * 16 + 8 - 40) & 0x00ff0000) \ | (SHIFT_S ((in), (SWAP_2_AND_3 (c) - 1) * 16 + 8 - 48) & 0x0000ff00) \ | (SHIFT_S ((in), (SWAP_2_AND_3 (d) - 1) * 16 + 8 - 56) & 0x000000ff)) /* ---------------------- * * Repacking: 24/32 -> 64 * * ---------------------- */ static void unpack_8x_1234_p8_to_xxxx_p8_64bpp (const uint32_t * SMOL_RESTRICT *in, uint64_t * SMOL_RESTRICT *out, uint64_t *out_max, const __m256i channel_shuf) { const __m256i zero = _mm256_setzero_si256 (); const __m256i * SMOL_RESTRICT my_in = (const __m256i * SMOL_RESTRICT) *in; __m256i * SMOL_RESTRICT my_out = (__m256i * SMOL_RESTRICT) *out; __m256i m0, m1, m2; SMOL_ASSUME_ALIGNED (my_out, __m256i * SMOL_RESTRICT); while ((ptrdiff_t) (my_out + 2) <= (ptrdiff_t) out_max) { m0 = _mm256_loadu_si256 (my_in); my_in++; m0 = _mm256_shuffle_epi8 (m0, channel_shuf); m0 = _mm256_permute4x64_epi64 (m0, SMOL_4X2BIT (3, 1, 2, 0)); m1 = _mm256_unpacklo_epi8 (m0, zero); m2 = _mm256_unpackhi_epi8 (m0, zero); _mm256_store_si256 (my_out, m1); my_out++; _mm256_store_si256 (my_out, m2); my_out++; } *out = (uint64_t * SMOL_RESTRICT) my_out; *in = (const uint32_t * SMOL_RESTRICT) my_in; } static SMOL_INLINE uint64_t unpack_pixel_123_p8_to_132a_p8_64bpp (const uint8_t *p) { return ((uint64_t) p [0] << 48) | ((uint32_t) p [1] << 16) | ((uint64_t) p [2] << 32) | 0xff; } SMOL_REPACK_ROW_DEF (123, 24, 8, PREMUL8, COMPRESSED, 1324, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_123_p8_to_132a_p8_64bpp (src_row); src_row += 3; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_p8_to_1324_p8_64bpp (uint32_t p) { return (((uint64_t) p & 0xff00ff00) << 24) | (p & 0x00ff00ff); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 1324, 64, 64, PREMUL8, COMPRESSED) { const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_64 (1, 3, 2, 4); unpack_8x_1234_p8_to_xxxx_p8_64bpp (&src_row, &dest_row, dest_row_max, channel_shuf); while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_p8_to_3241_p8_64bpp (uint32_t p) { return (((uint64_t) p & 0x0000ff00) << 40) | (((uint64_t) p & 0x00ff00ff) << 16) | (p >> 24); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 3241, 64, 64, PREMUL8, COMPRESSED) { const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_64 (3, 2, 4, 1); unpack_8x_1234_p8_to_xxxx_p8_64bpp (&src_row, &dest_row, dest_row_max, channel_shuf); while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_p8_to_3241_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_p8_to_2431_p8_64bpp (uint32_t p) { uint64_t p64 = p; return ((p64 & 0x00ff00ff) << 32) | ((p64 & 0x0000ff00) << 8) | ((p64 & 0xff000000) >> 24); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 2431, 64, 64, PREMUL8, COMPRESSED) { const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_64 (2, 4, 3, 1); unpack_8x_1234_p8_to_xxxx_p8_64bpp (&src_row, &dest_row, dest_row_max, channel_shuf); while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_p8_to_2431_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_a234_u_to_324a_p8_64bpp (uint32_t p) { uint64_t p64 = (((uint64_t) p & 0x0000ff00) << 40) | (((uint64_t) p & 0x00ff00ff) << 16); uint8_t alpha = p >> 24; return premul_u_to_p8_64bpp (p64, alpha) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 3241, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_a234_u_to_324a_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_u_to_2431_p8_64bpp (uint32_t p) { uint64_t p64 = (((uint64_t) p & 0x00ff00ff) << 32) | (((uint64_t) p & 0x0000ff00) << 8); uint8_t alpha = p >> 24; return premul_u_to_p8_64bpp (p64, alpha) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2431, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_u_to_2431_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_123a_u_to_132a_p8_64bpp (uint32_t p) { uint64_t p64 = (((uint64_t) p & 0xff00ff00) << 24) | (p & 0x00ff0000); uint8_t alpha = p & 0xff; return premul_u_to_p8_64bpp (p64, alpha) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1324, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_123a_u_to_132a_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END /* ----------------------- * * Repacking: 24/32 -> 128 * * ----------------------- */ static void unpack_8x_xxxx_u_to_123a_p16_128bpp (const uint32_t * SMOL_RESTRICT *in, uint64_t * SMOL_RESTRICT *out, uint64_t *out_max, const __m256i channel_shuf) { const __m256i zero = _mm256_setzero_si256 (); const __m256i factor_shuf = _mm256_set_epi8 ( -1, 12, -1, -1, -1, 12, -1, 12, -1, 4, -1, -1, -1, 4, -1, 4, -1, 12, -1, -1, -1, 12, -1, 12, -1, 4, -1, -1, -1, 4, -1, 4); const __m256i alpha_mul = _mm256_set_epi16 ( 0, 0x100, 0, 0, 0, 0x100, 0, 0, 0, 0x100, 0, 0, 0, 0x100, 0, 0); const __m256i alpha_add = _mm256_set_epi16 ( 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0, 0x80, 0, 0); const __m256i * SMOL_RESTRICT my_in = (const __m256i * SMOL_RESTRICT) *in; __m256i * SMOL_RESTRICT my_out = (__m256i * SMOL_RESTRICT) *out; __m256i m0, m1, m2, m3, m4, m5, m6; __m256i fact1, fact2; SMOL_ASSUME_ALIGNED (my_out, __m256i * SMOL_RESTRICT); while ((ptrdiff_t) (my_out + 4) <= (ptrdiff_t) out_max) { m0 = _mm256_loadu_si256 (my_in); my_in++; m0 = _mm256_shuffle_epi8 (m0, channel_shuf); m0 = _mm256_permute4x64_epi64 (m0, SMOL_4X2BIT (3, 1, 2, 0)); m1 = _mm256_unpacklo_epi8 (m0, zero); m2 = _mm256_unpackhi_epi8 (m0, zero); fact1 = _mm256_shuffle_epi8 (m1, factor_shuf); fact2 = _mm256_shuffle_epi8 (m2, factor_shuf); fact1 = _mm256_or_si256 (fact1, alpha_mul); fact2 = _mm256_or_si256 (fact2, alpha_mul); m1 = _mm256_mullo_epi16 (m1, fact1); m2 = _mm256_mullo_epi16 (m2, fact2); m1 = _mm256_add_epi16 (m1, alpha_add); m2 = _mm256_add_epi16 (m2, alpha_add); m1 = _mm256_permute4x64_epi64 (m1, SMOL_4X2BIT (3, 1, 2, 0)); m2 = _mm256_permute4x64_epi64 (m2, SMOL_4X2BIT (3, 1, 2, 0)); m3 = _mm256_unpacklo_epi16 (m1, zero); m4 = _mm256_unpackhi_epi16 (m1, zero); m5 = _mm256_unpacklo_epi16 (m2, zero); m6 = _mm256_unpackhi_epi16 (m2, zero); _mm256_store_si256 (my_out, m3); my_out++; _mm256_store_si256 (my_out, m4); my_out++; _mm256_store_si256 (my_out, m5); my_out++; _mm256_store_si256 (my_out, m6); my_out++; } *out = (uint64_t * SMOL_RESTRICT) my_out; *in = (const uint32_t * SMOL_RESTRICT) my_in; } static SMOL_INLINE void unpack_pixel_123_p8_to_123a_p8_128bpp (const uint8_t *in, uint64_t *out) { out [0] = ((uint64_t) in [0] << 32) | in [1]; out [1] = ((uint64_t) in [2] << 32) | 0xff; } SMOL_REPACK_ROW_DEF (123, 24, 8, PREMUL8, COMPRESSED, 1234, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123_p8_to_123a_p8_128bpp (src_row, dest_row); src_row += 3; dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_p8_to_123a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; out [0] = ((p64 & 0xff000000) << 8) | ((p64 & 0x00ff0000) >> 16); out [1] = ((p64 & 0x0000ff00) << 24) | (p64 & 0x000000ff); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 1234, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123a_p8_to_123a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_p8_to_234a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; out [0] = ((p64 & 0x00ff0000) << 16) | ((p64 & 0x0000ff00) >> 8); out [1] = ((p64 & 0x000000ff) << 32) | ((p64 & 0xff000000) >> 24); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 2341, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_a234_p8_to_234a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_u_to_234a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = (((uint64_t) p & 0x00ff00ff) << 32) | (((uint64_t) p & 0x0000ff00) << 8); uint8_t alpha = p >> 24; p64 = premul_u_to_p8_64bpp (p64, alpha) | alpha; out [0] = (p64 >> 16) & 0x000000ff000000ff; out [1] = p64 & 0x000000ff000000ff; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2341, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_a234_u_to_234a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_u_to_234a_p16_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint64_t alpha = p >> 24; out [0] = (((((p64 & 0x00ff0000) << 16) | ((p64 & 0x0000ff00) >> 8)) * alpha)); out [1] = (((((p64 & 0x000000ff) << 32) * alpha))) | (alpha << 8) | 0x80; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2341, 128, 64, PREMUL16, COMPRESSED) { const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_128 (2, 3, 4, 1); unpack_8x_xxxx_u_to_123a_p16_128bpp (&src_row, &dest_row, dest_row_max, channel_shuf); while (dest_row != dest_row_max) { unpack_pixel_a234_u_to_234a_p16_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_u_to_123a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = (((uint64_t) p & 0xff00ff00) << 24) | (p & 0x00ff0000); uint8_t alpha = p & 0xff; p64 = premul_u_to_p8_64bpp (p64, alpha) | ((uint64_t) alpha); out [0] = (p64 >> 16) & 0x000000ff000000ff; out [1] = p64 & 0x000000ff000000ff; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1234, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123a_u_to_123a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_u_to_123a_p16_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint64_t alpha = p & 0xff; out [0] = (((((p64 & 0xff000000) << 8) | ((p64 & 0x00ff0000) >> 16)) * alpha)); out [1] = (((((p64 & 0x0000ff00) << 24) * alpha))) | (alpha << 8) | 0x80; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1234, 128, 64, PREMUL16, COMPRESSED) { const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_128 (1, 2, 3, 4); unpack_8x_xxxx_u_to_123a_p16_128bpp (&src_row, &dest_row, dest_row_max, channel_shuf); while (dest_row != dest_row_max) { unpack_pixel_123a_u_to_123a_p16_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END /* ---------------------- * * Repacking: 64 -> 24/32 * * ---------------------- */ static void pack_8x_1234_p8_to_xxxx_p8_64bpp (const uint64_t * SMOL_RESTRICT *in, uint32_t * SMOL_RESTRICT *out, uint32_t * out_max, const __m256i channel_shuf) { const __m256i * SMOL_RESTRICT my_in = (const __m256i * SMOL_RESTRICT) *in; __m256i * SMOL_RESTRICT my_out = (__m256i * SMOL_RESTRICT) *out; __m256i m0, m1; SMOL_ASSUME_ALIGNED (my_in, const __m256i * SMOL_RESTRICT); while ((ptrdiff_t) (my_out + 1) <= (ptrdiff_t) out_max) { /* Load inputs */ m0 = _mm256_stream_load_si256 (my_in); my_in++; m1 = _mm256_stream_load_si256 (my_in); my_in++; /* Pack and store */ m0 = _mm256_packus_epi16 (m0, m1); m0 = _mm256_shuffle_epi8 (m0, channel_shuf); m0 = _mm256_permute4x64_epi64 (m0, SMOL_4X2BIT (3, 1, 2, 0)); _mm256_storeu_si256 (my_out, m0); my_out++; } *out = (uint32_t * SMOL_RESTRICT) my_out; *in = (const uint64_t * SMOL_RESTRICT) my_in; } static SMOL_INLINE uint32_t pack_pixel_1234_p8_to_1324_p8_64bpp (uint64_t in) { return in | (in >> 24); } SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 132, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p >> 24; *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 132, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p >> 24; *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 231, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; *(dest_row++) = p >> 24; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 231, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; *(dest_row++) = p >> 24; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 324, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; *(dest_row++) = p; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 324, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row >> 24; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; *(dest_row++) = p; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 423, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p; *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 423, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row >> 24; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p; *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 1324, 32, 32, PREMUL8, COMPRESSED) { const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_64 (1, 3, 2, 4); pack_8x_1234_p8_to_xxxx_p8_64bpp (&src_row, &dest_row, dest_row_max, channel_shuf); while (dest_row != dest_row_max) { *(dest_row++) = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 1324, 32, 32, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; *(dest_row++) = pack_pixel_1234_p8_to_1324_p8_64bpp (t); src_row++; } } SMOL_REPACK_ROW_DEF_END #define DEF_REPACK_FROM_1234_64BPP_TO_32BPP(a, b, c, d) \ SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, PREMUL8, COMPRESSED) { \ const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_64 ((a), (b), (c), (d)); \ pack_8x_1234_p8_to_xxxx_p8_64bpp (&src_row, &dest_row, dest_row_max, \ channel_shuf); \ while (dest_row != dest_row_max) \ { \ *(dest_row++) = PACK_FROM_1234_64BPP (*src_row, a, b, c, d); \ src_row++; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint8_t alpha = *src_row; \ uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_64BPP (t, a, b, c, d); \ src_row++; \ } \ } SMOL_REPACK_ROW_DEF_END DEF_REPACK_FROM_1234_64BPP_TO_32BPP (1, 4, 2, 3) DEF_REPACK_FROM_1234_64BPP_TO_32BPP (2, 3, 1, 4) DEF_REPACK_FROM_1234_64BPP_TO_32BPP (4, 1, 3, 2) DEF_REPACK_FROM_1234_64BPP_TO_32BPP (4, 2, 3, 1) /* ----------------------- * * Repacking: 128 -> 24/32 * * ----------------------- */ static void pack_8x_123a_p16_to_xxxx_u_128bpp (const uint64_t * SMOL_RESTRICT *in, uint32_t * SMOL_RESTRICT *out, uint32_t * out_max, const __m256i channel_shuf) { #define ALPHA_MUL (1 << (INVERTED_DIV_SHIFT_P16 - 8)) #define ALPHA_MASK SMOL_8X1BIT (0, 1, 0, 0, 0, 1, 0, 0) const __m256i ones = _mm256_set_epi32 ( ALPHA_MUL, ALPHA_MUL, ALPHA_MUL, ALPHA_MUL, ALPHA_MUL, ALPHA_MUL, ALPHA_MUL, ALPHA_MUL); const __m256i alpha_clean_mask = _mm256_set_epi32 ( 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff); const __m256i * SMOL_RESTRICT my_in = (const __m256i * SMOL_RESTRICT) *in; __m256i * SMOL_RESTRICT my_out = (__m256i * SMOL_RESTRICT) *out; __m256i m0, m1, m2, m3, m4, m5, m6, m7, m8; SMOL_ASSUME_ALIGNED (my_in, const __m256i * SMOL_RESTRICT); while ((ptrdiff_t) (my_out + 1) <= (ptrdiff_t) out_max) { /* Load inputs */ m0 = _mm256_stream_load_si256 (my_in); my_in++; m1 = _mm256_stream_load_si256 (my_in); my_in++; m2 = _mm256_stream_load_si256 (my_in); my_in++; m3 = _mm256_stream_load_si256 (my_in); my_in++; /* Load alpha factors */ m4 = _mm256_slli_si256 (m0, 4); m6 = _mm256_srli_si256 (m3, 4); m5 = _mm256_blend_epi32 (m4, m1, ALPHA_MASK); m7 = _mm256_blend_epi32 (m6, m2, ALPHA_MASK); m7 = _mm256_srli_si256 (m7, 4); m4 = _mm256_blend_epi32 (m5, m7, SMOL_8X1BIT (0, 0, 1, 1, 0, 0, 1, 1)); m4 = _mm256_srli_epi32 (m4, 8); m4 = _mm256_and_si256 (m4, alpha_clean_mask); m4 = _mm256_i32gather_epi32 ((const void *) _smol_inv_div_p16_lut, m4, 4); /* 2 pixels times 4 */ m5 = _mm256_shuffle_epi32 (m4, SMOL_4X2BIT (3, 3, 3, 3)); m6 = _mm256_shuffle_epi32 (m4, SMOL_4X2BIT (2, 2, 2, 2)); m7 = _mm256_shuffle_epi32 (m4, SMOL_4X2BIT (1, 1, 1, 1)); m8 = _mm256_shuffle_epi32 (m4, SMOL_4X2BIT (0, 0, 0, 0)); m5 = _mm256_blend_epi32 (m5, ones, ALPHA_MASK); m6 = _mm256_blend_epi32 (m6, ones, ALPHA_MASK); m7 = _mm256_blend_epi32 (m7, ones, ALPHA_MASK); m8 = _mm256_blend_epi32 (m8, ones, ALPHA_MASK); m5 = _mm256_mullo_epi32 (m5, m0); m6 = _mm256_mullo_epi32 (m6, m1); m7 = _mm256_mullo_epi32 (m7, m2); m8 = _mm256_mullo_epi32 (m8, m3); m5 = _mm256_srli_epi32 (m5, INVERTED_DIV_SHIFT_P16); m6 = _mm256_srli_epi32 (m6, INVERTED_DIV_SHIFT_P16); m7 = _mm256_srli_epi32 (m7, INVERTED_DIV_SHIFT_P16); m8 = _mm256_srli_epi32 (m8, INVERTED_DIV_SHIFT_P16); /* Pack and store */ m0 = _mm256_packus_epi32 (m5, m6); m1 = _mm256_packus_epi32 (m7, m8); m0 = _mm256_packus_epi16 (m0, m1); m0 = _mm256_shuffle_epi8 (m0, channel_shuf); m0 = _mm256_permute4x64_epi64 (m0, SMOL_4X2BIT (3, 1, 2, 0)); m0 = _mm256_shuffle_epi32 (m0, SMOL_4X2BIT (3, 1, 2, 0)); _mm256_storeu_si256 (my_out, m0); my_out += 1; } *out = (uint32_t * SMOL_RESTRICT) my_out; *in = (const uint64_t * SMOL_RESTRICT) my_in; #undef ALPHA_MUL #undef ALPHA_MASK } SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 123, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = *src_row >> 32; *(dest_row++) = *(src_row++); *(dest_row++) = *(src_row++) >> 32; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 123, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1]; unpremul_p8_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, COMPRESSED, 123, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1]; unpremul_p16_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 321, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = src_row [1] >> 32; *(dest_row++) = src_row [0]; *(dest_row++) = src_row [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 321, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1]; unpremul_p8_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, COMPRESSED, 321, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1] >> 8; unpremul_p16_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END #define DEF_REPACK_FROM_1234_128BPP_TO_32BPP(a, b, c, d) \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, PREMUL8, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ *(dest_row++) = PACK_FROM_1234_128BPP (src_row, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = src_row [1]; \ unpremul_p8_to_u_128bpp (src_row, t, alpha); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, COMPRESSED, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ const __m256i channel_shuf = PACK_SHUF_MM256_EPI8_32_TO_128 ((a), (b), (c), (d)); \ pack_8x_123a_p16_to_xxxx_u_128bpp (&src_row, &dest_row, dest_row_max, \ channel_shuf); \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = src_row [1] >> 8; \ unpremul_p16_to_u_128bpp (src_row, t, alpha); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END DEF_REPACK_FROM_1234_128BPP_TO_32BPP (1, 2, 3, 4) DEF_REPACK_FROM_1234_128BPP_TO_32BPP (3, 2, 1, 4) DEF_REPACK_FROM_1234_128BPP_TO_32BPP (4, 1, 2, 3) DEF_REPACK_FROM_1234_128BPP_TO_32BPP (4, 3, 2, 1) /* -------------- * * Filter helpers * * -------------- */ #define LERP_SIMD256_EPI32(a, b, f) \ _mm256_add_epi32 ( \ _mm256_srli_epi32 ( \ _mm256_mullo_epi32 ( \ _mm256_sub_epi32 ((a), (b)), (f)), 8), (b)) #define LERP_SIMD128_EPI32(a, b, f) \ _mm_add_epi32 ( \ _mm_srli_epi32 ( \ _mm_mullo_epi32 ( \ _mm_sub_epi32 ((a), (b)), (f)), 8), (b)) #define LERP_SIMD256_EPI32_AND_MASK(a, b, f, mask) \ _mm256_and_si256 (LERP_SIMD256_EPI32 ((a), (b), (f)), (mask)) #define LERP_SIMD128_EPI32_AND_MASK(a, b, f, mask) \ _mm_and_si128 (LERP_SIMD128_EPI32 ((a), (b), (f)), (mask)) static SMOL_INLINE const char * src_row_ofs_to_pointer (const SmolScaleCtx *scale_ctx, uint32_t src_row_ofs) { return scale_ctx->src_pixels + scale_ctx->src_rowstride * src_row_ofs; } static SMOL_INLINE uint64_t weight_pixel_64bpp (uint64_t p, uint16_t w) { return ((p * w) >> 8) & 0x00ff00ff00ff00ffULL; } /* p and out may be the same address */ static SMOL_INLINE void weight_pixel_128bpp (const uint64_t *p, uint64_t *out, uint16_t w) { out [0] = ((p [0] * w) >> 8) & 0x00ffffff00ffffffULL; out [1] = ((p [1] * w) >> 8) & 0x00ffffff00ffffffULL; } static SMOL_INLINE void sum_parts_64bpp (const uint64_t * SMOL_RESTRICT *parts_in, uint64_t * SMOL_RESTRICT accum, uint32_t n) { const uint64_t *pp_end; const uint64_t * SMOL_RESTRICT pp = *parts_in; SMOL_ASSUME_ALIGNED_TO (pp, const uint64_t *, sizeof (uint64_t)); for (pp_end = pp + n; pp < pp_end; pp++) { *accum += *pp; } *parts_in = pp; } static SMOL_INLINE void sum_parts_128bpp (const uint64_t * SMOL_RESTRICT *parts_in, uint64_t * SMOL_RESTRICT accum, uint32_t n) { const uint64_t *pp_end; const uint64_t * SMOL_RESTRICT pp = *parts_in; SMOL_ASSUME_ALIGNED_TO (pp, const uint64_t *, sizeof (uint64_t) * 2); for (pp_end = pp + n * 2; pp < pp_end; ) { accum [0] += *(pp++); accum [1] += *(pp++); } *parts_in = pp; } static SMOL_INLINE uint64_t scale_64bpp (uint64_t accum, uint64_t multiplier) { uint64_t a, b; /* Average the inputs */ a = ((accum & 0x0000ffff0000ffffULL) * multiplier + (SMOL_BOXES_MULTIPLIER / 2) + ((SMOL_BOXES_MULTIPLIER / 2) << 32)) / SMOL_BOXES_MULTIPLIER; b = (((accum & 0xffff0000ffff0000ULL) >> 16) * multiplier + (SMOL_BOXES_MULTIPLIER / 2) + ((SMOL_BOXES_MULTIPLIER / 2) << 32)) / SMOL_BOXES_MULTIPLIER; /* Return pixel */ return (a & 0x000000ff000000ffULL) | ((b & 0x000000ff000000ffULL) << 16); } static SMOL_INLINE uint64_t scale_128bpp_half (uint64_t accum, uint64_t multiplier) { uint64_t a, b; a = accum & 0x00000000ffffffffULL; a = (a * multiplier + SMOL_BOXES_MULTIPLIER / 2) / SMOL_BOXES_MULTIPLIER; b = (accum & 0xffffffff00000000ULL) >> 32; b = (b * multiplier + SMOL_BOXES_MULTIPLIER / 2) / SMOL_BOXES_MULTIPLIER; return a | (b << 32); } static SMOL_INLINE void scale_and_store_128bpp (const uint64_t * SMOL_RESTRICT accum, uint64_t multiplier, uint64_t * SMOL_RESTRICT *row_parts_out) { *(*row_parts_out)++ = scale_128bpp_half (accum [0], multiplier); *(*row_parts_out)++ = scale_128bpp_half (accum [1], multiplier); } static void add_parts (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n) { const uint64_t *parts_in_max = parts_in + n; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in + 4 <= parts_in_max) { __m256i m0, m1; m0 = _mm256_stream_load_si256 ((const __m256i *) parts_in); parts_in += 4; m1 = _mm256_load_si256 ((__m256i *) parts_acc_out); m0 = _mm256_add_epi32 (m0, m1); _mm256_store_si256 ((__m256i *) parts_acc_out, m0); parts_acc_out += 4; } while (parts_in < parts_in_max) *(parts_acc_out++) += *(parts_in++); } static void copy_weighted_parts_64bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { *(parts_acc_out++) = weight_pixel_64bpp (*(parts_in++), w); } } static void copy_weighted_parts_128bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n * 2; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { weight_pixel_128bpp (parts_in, parts_acc_out, w); parts_in += 2; parts_acc_out += 2; } } static void add_weighted_parts_64bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { *(parts_acc_out++) += weight_pixel_64bpp (*(parts_in++), w); } } static void add_weighted_parts_128bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n * 2; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { uint64_t t [2]; weight_pixel_128bpp (parts_in, t, w); parts_acc_out [0] += t [0]; parts_acc_out [1] += t [1]; parts_in += 2; parts_acc_out += 2; } } static SMOL_INLINE void apply_subpixel_opacity_64bpp (uint64_t * SMOL_RESTRICT u64_inout, uint16_t opacity) { *u64_inout = ((*u64_inout * opacity) >> SMOL_SUBPIXEL_SHIFT) & 0x00ff00ff00ff00ffULL; } static SMOL_INLINE void apply_subpixel_opacity_128bpp_half (uint64_t * SMOL_RESTRICT u64_inout, uint16_t opacity) { *u64_inout = ((*u64_inout * opacity) >> SMOL_SUBPIXEL_SHIFT) & 0x00ffffff00ffffffULL; } static SMOL_INLINE void apply_subpixel_opacity_128bpp (uint64_t *u64_inout, uint16_t opacity) { apply_subpixel_opacity_128bpp_half (u64_inout, opacity); apply_subpixel_opacity_128bpp_half (u64_inout + 1, opacity); } static void apply_subpixel_opacity_row_copy_64bpp (uint64_t * SMOL_RESTRICT u64_in, uint64_t * SMOL_RESTRICT u64_out, int n_pixels, uint16_t opacity) { uint64_t *u64_out_max = u64_out + n_pixels; while (u64_out != u64_out_max) { *u64_out = *u64_in++; apply_subpixel_opacity_64bpp (u64_out, opacity); u64_out++; } } static void apply_subpixel_opacity_row_copy_128bpp (uint64_t * SMOL_RESTRICT u64_in, uint64_t * SMOL_RESTRICT u64_out, int n_pixels, uint16_t opacity) { uint64_t *u64_out_max = u64_out + (n_pixels * 2); while (u64_out != u64_out_max) { u64_out [0] = u64_in [0]; u64_out [1] = u64_in [1]; apply_subpixel_opacity_128bpp_half (u64_out, opacity); apply_subpixel_opacity_128bpp_half (u64_out + 1, opacity); u64_in += 2; u64_out += 2; } } static void apply_horiz_edge_opacity (const SmolScaleCtx *scale_ctx, uint64_t *row_parts) { if (scale_ctx->storage_type == SMOL_STORAGE_64BPP) { apply_subpixel_opacity_64bpp (&row_parts [0], scale_ctx->hdim.first_opacity); apply_subpixel_opacity_64bpp (&row_parts [scale_ctx->hdim.placement_size_px - 1], scale_ctx->hdim.last_opacity); } else { apply_subpixel_opacity_128bpp (&row_parts [0], scale_ctx->hdim.first_opacity); apply_subpixel_opacity_128bpp (&row_parts [(scale_ctx->hdim.placement_size_px - 1) * 2], scale_ctx->hdim.last_opacity); } } /* ------------------ * * Horizontal scaling * * ------------------ */ #define CONTROL_4X2BIT_1_0_3_2 (SMOL_4X2BIT (1, 0, 3, 2)) #define CONTROL_4X2BIT_3_1_2_0 (SMOL_4X2BIT (3, 1, 2, 0)) #define CONTROL_8X1BIT_1_1_0_0_1_1_0_0 (SMOL_8X1BIT (1, 1, 0, 0, 1, 1, 0, 0)) static SMOL_INLINE void hadd_pixels_16x_to_8x_64bpp (__m256i i0, __m256i i1, __m256i i2, __m256i i3, __m256i * SMOL_RESTRICT o0, __m256i * SMOL_RESTRICT o1) { __m256i t0, t1, t2, t3; t0 = _mm256_shuffle_epi32 (i0, CONTROL_4X2BIT_1_0_3_2); t1 = _mm256_shuffle_epi32 (i1, CONTROL_4X2BIT_1_0_3_2); t2 = _mm256_shuffle_epi32 (i2, CONTROL_4X2BIT_1_0_3_2); t3 = _mm256_shuffle_epi32 (i3, CONTROL_4X2BIT_1_0_3_2); t0 = _mm256_add_epi16 (t0, i0); t1 = _mm256_add_epi16 (t1, i1); t2 = _mm256_add_epi16 (t2, i2); t3 = _mm256_add_epi16 (t3, i3); t0 = _mm256_blend_epi32 (t0, t1, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); t1 = _mm256_blend_epi32 (t2, t3, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); t0 = _mm256_permute4x64_epi64 (t0, CONTROL_4X2BIT_3_1_2_0); t1 = _mm256_permute4x64_epi64 (t1, CONTROL_4X2BIT_3_1_2_0); *o0 = t0; *o1 = t1; } static SMOL_INLINE void hadd_pixels_8x_to_4x_64bpp (__m256i i0, __m256i i1, __m256i * SMOL_RESTRICT o0) { __m256i t0, t1; t0 = _mm256_shuffle_epi32 (i0, CONTROL_4X2BIT_1_0_3_2); t1 = _mm256_shuffle_epi32 (i1, CONTROL_4X2BIT_1_0_3_2); t0 = _mm256_add_epi16 (t0, i0); t1 = _mm256_add_epi16 (t1, i1); t0 = _mm256_blend_epi32 (t0, t1, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); t0 = _mm256_permute4x64_epi64 (t0, CONTROL_4X2BIT_3_1_2_0); *o0 = t0; } static SMOL_INLINE void interp_horizontal_bilinear_batch_64bpp (const uint64_t * SMOL_RESTRICT row_parts_in, const uint16_t * SMOL_RESTRICT precalc_x, __m256i * SMOL_RESTRICT o0, __m256i * SMOL_RESTRICT o1, __m256i * SMOL_RESTRICT o2, __m256i * SMOL_RESTRICT o3) { const __m256i mask = _mm256_set_epi16 (0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff); const __m256i shuf_0 = _mm256_set_epi8 (3, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0, 1, 0, 3, 2, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0, 1, 0); const __m256i shuf_1 = _mm256_set_epi8 (7, 6, 7, 6, 7, 6, 7, 6, 5, 4, 5, 4, 5, 4, 5, 4, 7, 6, 7, 6, 7, 6, 7, 6, 5, 4, 5, 4, 5, 4, 5, 4); const __m256i shuf_2 = _mm256_set_epi8 (11, 10, 11, 10, 11, 10, 11, 10, 9, 8, 9, 8, 9, 8, 9, 8, 11, 10, 11, 10, 11, 10, 11, 10, 9, 8, 9, 8, 9, 8, 9, 8); const __m256i shuf_3 = _mm256_set_epi8 (15, 14, 15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 13, 12, 15, 14, 15, 14, 15, 14, 15, 14, 13, 12, 13, 12, 13, 12, 13, 12); __m256i m0, m1, m2, m3; __m256i f0, f1, f2, f3; __m256i q00, q10, q20, q30, q40, q50, q60, q70; __m256i q01, q11, q21, q31, q41, q51, q61, q71; __m256i p00, p01, p10, p11, p20, p21, p30, p31; __m256i f; /* Fetch pixel pairs to interpolate between, two pairs per ymm register. * This looks clumsy, but it's a lot faster than using _mm256_i32gather_epi64(), * as benchmarked on both Haswell and Tiger Lake. */ q00 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [0]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [1])), 1); q10 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [2]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [3])), 1); q20 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [4]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [5])), 1); q30 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [6]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [7])), 1); q40 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [8]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [9])), 1); q50 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [10]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [11])), 1); q60 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [12]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [13])), 1); q70 = _mm256_inserti128_si256 (_mm256_castsi128_si256 ( _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [14]))), _mm_loadu_si128 ((const __m128i *) (row_parts_in + precalc_x [15])), 1); f = _mm256_load_si256 ((const __m256i *) (precalc_x + 16)); /* Factors */ /* 0123 -> 0x2x, 1x3x. 4567 -> x4x6, x5x7. Etc. */ q01 = _mm256_shuffle_epi32 (q00, CONTROL_4X2BIT_1_0_3_2); q11 = _mm256_shuffle_epi32 (q10, CONTROL_4X2BIT_1_0_3_2); q21 = _mm256_shuffle_epi32 (q20, CONTROL_4X2BIT_1_0_3_2); q31 = _mm256_shuffle_epi32 (q30, CONTROL_4X2BIT_1_0_3_2); q41 = _mm256_shuffle_epi32 (q40, CONTROL_4X2BIT_1_0_3_2); q51 = _mm256_shuffle_epi32 (q50, CONTROL_4X2BIT_1_0_3_2); q61 = _mm256_shuffle_epi32 (q60, CONTROL_4X2BIT_1_0_3_2); q71 = _mm256_shuffle_epi32 (q70, CONTROL_4X2BIT_1_0_3_2); /* 0x2x, x4x6 -> 0426. 1x3x, x5x7 -> 1537. Etc. */ p00 = _mm256_blend_epi32 (q00, q11, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p10 = _mm256_blend_epi32 (q20, q31, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p20 = _mm256_blend_epi32 (q40, q51, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p30 = _mm256_blend_epi32 (q60, q71, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p01 = _mm256_blend_epi32 (q01, q10, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p11 = _mm256_blend_epi32 (q21, q30, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p21 = _mm256_blend_epi32 (q41, q50, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); p31 = _mm256_blend_epi32 (q61, q70, CONTROL_8X1BIT_1_1_0_0_1_1_0_0); /* Interpolation. 0426 vs 1537. Etc. */ m0 = _mm256_sub_epi16 (p00, p01); m1 = _mm256_sub_epi16 (p10, p11); m2 = _mm256_sub_epi16 (p20, p21); m3 = _mm256_sub_epi16 (p30, p31); f0 = _mm256_shuffle_epi8 (f, shuf_0); f1 = _mm256_shuffle_epi8 (f, shuf_1); f2 = _mm256_shuffle_epi8 (f, shuf_2); f3 = _mm256_shuffle_epi8 (f, shuf_3); m0 = _mm256_mullo_epi16 (m0, f0); m1 = _mm256_mullo_epi16 (m1, f1); m2 = _mm256_mullo_epi16 (m2, f2); m3 = _mm256_mullo_epi16 (m3, f3); m0 = _mm256_srli_epi16 (m0, 8); m1 = _mm256_srli_epi16 (m1, 8); m2 = _mm256_srli_epi16 (m2, 8); m3 = _mm256_srli_epi16 (m3, 8); m0 = _mm256_add_epi16 (m0, p01); m1 = _mm256_add_epi16 (m1, p11); m2 = _mm256_add_epi16 (m2, p21); m3 = _mm256_add_epi16 (m3, p31); m0 = _mm256_and_si256 (m0, mask); m1 = _mm256_and_si256 (m1, mask); m2 = _mm256_and_si256 (m2, mask); m3 = _mm256_and_si256 (m3, mask); /* [0426/1537] -> [0246/1357]. Etc. */ *o0 = _mm256_permute4x64_epi64 (m0, CONTROL_4X2BIT_3_1_2_0); *o1 = _mm256_permute4x64_epi64 (m1, CONTROL_4X2BIT_3_1_2_0); *o2 = _mm256_permute4x64_epi64 (m2, CONTROL_4X2BIT_3_1_2_0); *o3 = _mm256_permute4x64_epi64 (m3, CONTROL_4X2BIT_3_1_2_0); } static void interp_horizontal_bilinear_batch_to_4x_64bpp (const uint64_t * SMOL_RESTRICT row_parts_in, const uint16_t * SMOL_RESTRICT precalc_x, __m256i * SMOL_RESTRICT o0) { __m256i m0, m1, m2, m3, s0, s1; interp_horizontal_bilinear_batch_64bpp (row_parts_in, precalc_x, &m0, &m1, &m2, &m3); hadd_pixels_16x_to_8x_64bpp (m0, m1, m2, m3, &s0, &s1); hadd_pixels_8x_to_4x_64bpp (s0, s1, o0); } static void interp_horizontal_bilinear_4x_batch_to_4x_64bpp (const uint64_t * SMOL_RESTRICT row_parts_in, const uint16_t * SMOL_RESTRICT precalc_x, __m256i * SMOL_RESTRICT o0) { __m256i t0, t1, t2, t3; interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x, &t0); interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x + 32, &t1); interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x + 64, &t2); interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x + 96, &t3); hadd_pixels_16x_to_8x_64bpp (t0, t1, t2, t3, &t0, &t1); hadd_pixels_8x_to_4x_64bpp (t0, t1, o0); } /* Note that precalc_x must point to offsets and factors interleaved one by one, i.e. * offset - factor - offset - factor, and not 16x as with the batch function. */ static SMOL_INLINE void interp_horizontal_bilinear_epilogue_64bpp (const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out, uint64_t * SMOL_RESTRICT row_parts_out_max, const uint16_t * SMOL_RESTRICT precalc_x, int n_halvings) { while (row_parts_out != row_parts_out_max) { uint64_t accum = 0; int i; for (i = 0; i < (1 << (n_halvings)); i++) { uint64_t p, q; uint64_t F; p = *(row_parts_in + (*precalc_x)); q = *(row_parts_in + (*precalc_x) + 1); precalc_x++; F = *(precalc_x++); accum += ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; } *(row_parts_out++) = ((accum) >> (n_halvings)) & 0x00ff00ff00ff00ffULL; } } static void interp_horizontal_bilinear_0h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 16 <= row_parts_out_max) { __m256i m0, m1, m2, m3; interp_horizontal_bilinear_batch_64bpp (row_parts_in, precalc_x, &m0, &m1, &m2, &m3); _mm256_store_si256 ((__m256i *) row_parts_out + 0, m0); _mm256_store_si256 ((__m256i *) row_parts_out + 1, m1); _mm256_store_si256 ((__m256i *) row_parts_out + 2, m2); _mm256_store_si256 ((__m256i *) row_parts_out + 3, m3); row_parts_out += 16; precalc_x += 32; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 0); } static void interp_horizontal_bilinear_1h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 8 <= row_parts_out_max) { __m256i m0, m1, m2, m3, s0, s1; interp_horizontal_bilinear_batch_64bpp (row_parts_in, precalc_x, &m0, &m1, &m2, &m3); hadd_pixels_16x_to_8x_64bpp (m0, m1, m2, m3, &s0, &s1); s0 = _mm256_srli_epi16 (s0, 1); s1 = _mm256_srli_epi16 (s1, 1); _mm256_store_si256 ((__m256i *) row_parts_out, s0); _mm256_store_si256 ((__m256i *) row_parts_out + 1, s1); row_parts_out += 8; precalc_x += 32; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 1); } static void interp_horizontal_bilinear_2h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 4 <= row_parts_out_max) { __m256i t; interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x, &t); t = _mm256_srli_epi16 (t, 2); _mm256_store_si256 ((__m256i *) row_parts_out, t); row_parts_out += 4; precalc_x += 32; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 2); } static void interp_horizontal_bilinear_3h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 4 <= row_parts_out_max) { __m256i s0, s1; interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x, &s0); interp_horizontal_bilinear_batch_to_4x_64bpp (row_parts_in, precalc_x + 32, &s1); hadd_pixels_8x_to_4x_64bpp (s0, s1, &s0); s0 = _mm256_srli_epi16 (s0, 3); _mm256_store_si256 ((__m256i *) row_parts_out, s0); row_parts_out += 4; precalc_x += 64; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 3); } static void interp_horizontal_bilinear_4h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 4 <= row_parts_out_max) { __m256i t0; interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x, &t0); t0 = _mm256_srli_epi16 (t0, 4); _mm256_store_si256 ((__m256i *) row_parts_out, t0); row_parts_out += 4; precalc_x += 128; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 4); } static void interp_horizontal_bilinear_5h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 4 <= row_parts_out_max) { __m256i t0, t1; interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x, &t0); interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x + 128, &t1); hadd_pixels_8x_to_4x_64bpp (t0, t1, &t0); t0 = _mm256_srli_epi16 (t0, 5); _mm256_store_si256 ((__m256i *) row_parts_out, t0); row_parts_out += 4; precalc_x += 256; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 5); } static void interp_horizontal_bilinear_6h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t * SMOL_RESTRICT); SMOL_ASSUME_ALIGNED (precalc_x, const uint16_t * SMOL_RESTRICT); while (row_parts_out + 4 <= row_parts_out_max) { __m256i t0, t1, t2, t3; interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x, &t0); interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x + 128, &t1); interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x + 256, &t2); interp_horizontal_bilinear_4x_batch_to_4x_64bpp (row_parts_in, precalc_x + 384, &t3); hadd_pixels_16x_to_8x_64bpp (t0, t1, t2, t3, &t0, &t1); hadd_pixels_8x_to_4x_64bpp (t0, t1, &t0); t0 = _mm256_srli_epi16 (t0, 6); _mm256_store_si256 ((__m256i *) row_parts_out, t0); row_parts_out += 4; precalc_x += 512; } interp_horizontal_bilinear_epilogue_64bpp (row_parts_in, row_parts_out, row_parts_out_max, precalc_x, 6); } static void interp_horizontal_bilinear_0h_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px * 2; const __m256i mask256 = _mm256_set_epi32 ( 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff); const __m128i mask128 = _mm_set_epi32 ( 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff); const __m256i zero = _mm256_setzero_si256 (); SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t *); while (row_parts_out + 4 <= row_parts_out_max) { __m256i factors; __m256i m0, m1; __m128i n0, n1, n2, n3, n4, n5; const uint64_t * SMOL_RESTRICT p0; p0 = row_parts_in + *(precalc_x++) * 2; n4 = _mm_set1_epi16 (*(precalc_x++)); n0 = _mm_load_si128 ((const __m128i *) p0); n1 = _mm_load_si128 ((const __m128i *) p0 + 1); p0 = row_parts_in + *(precalc_x++) * 2; n5 = _mm_set1_epi16 (*(precalc_x++)); n2 = _mm_load_si128 ((const __m128i *) p0); n3 = _mm_load_si128 ((const __m128i *) p0 + 1); m0 = _mm256_set_m128i (n2, n0); m1 = _mm256_set_m128i (n3, n1); factors = _mm256_set_m128i (n5, n4); factors = _mm256_blend_epi16 (factors, zero, 0xaa); m0 = LERP_SIMD256_EPI32_AND_MASK (m0, m1, factors, mask256); _mm256_store_si256 ((__m256i *) row_parts_out, m0); row_parts_out += 4; } /* No need for a loop here; let compiler know we're doing it at most once */ if (row_parts_out != row_parts_out_max) { __m128i factors; __m128i m0, m1; uint32_t f; const uint64_t * SMOL_RESTRICT p0; p0 = row_parts_in + *(precalc_x++) * 2; f = *(precalc_x++); factors = _mm_set1_epi32 ((uint32_t) f); m0 = _mm_load_si128 ((const __m128i *) p0); m1 = _mm_load_si128 ((const __m128i *) p0 + 1); m0 = LERP_SIMD128_EPI32_AND_MASK (m0, m1, factors, mask128); _mm_store_si128 ((__m128i *) row_parts_out, m0); row_parts_out += 2; } } #define DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(n_halvings) \ static void \ interp_horizontal_bilinear_##n_halvings##h_128bpp (const SmolScaleCtx *scale_ctx, \ const uint64_t * SMOL_RESTRICT row_parts_in, \ uint64_t * SMOL_RESTRICT row_parts_out) \ { \ const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; \ uint64_t *row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px * 2; \ const __m256i mask256 = _mm256_set_epi32 ( \ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, \ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff); \ const __m128i mask128 = _mm_set_epi32 ( \ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff); \ const __m256i zero256 = _mm256_setzero_si256 (); \ int i; \ \ SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t *); \ SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t *); \ \ while (row_parts_out != row_parts_out_max) \ { \ __m256i a0 = _mm256_setzero_si256 (); \ __m128i a1; \ \ for (i = 0; i < (1 << ((n_halvings) - 1)); i++) \ { \ __m256i m0, m1; \ __m256i factors; \ __m128i n0, n1, n2, n3, n4, n5; \ const uint64_t * SMOL_RESTRICT p0; \ \ p0 = row_parts_in + *(precalc_x++) * 2; \ n4 = _mm_set1_epi16 (*(precalc_x++)); \ n0 = _mm_load_si128 ((const __m128i *) p0); \ n1 = _mm_load_si128 ((const __m128i *) p0 + 1); \ \ p0 = row_parts_in + *(precalc_x++) * 2; \ n5 = _mm_set1_epi16 (*(precalc_x++)); \ n2 = _mm_load_si128 ((const __m128i *) p0); \ n3 = _mm_load_si128 ((const __m128i *) p0 + 1); \ \ m0 = _mm256_set_m128i (n2, n0); \ m1 = _mm256_set_m128i (n3, n1); \ factors = _mm256_set_m128i (n5, n4); \ factors = _mm256_blend_epi16 (factors, zero256, 0xaa); \ \ m0 = LERP_SIMD256_EPI32_AND_MASK (m0, m1, factors, mask256); \ a0 = _mm256_add_epi32 (a0, m0); \ } \ \ a1 = _mm_add_epi32 (_mm256_extracti128_si256 (a0, 0), \ _mm256_extracti128_si256 (a0, 1)); \ a1 = _mm_srli_epi32 (a1, (n_halvings)); \ a1 = _mm_and_si128 (a1, mask128); \ _mm_store_si128 ((__m128i *) row_parts_out, a1); \ row_parts_out += 2; \ } \ } DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(1) DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(2) DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(3) DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(4) DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(5) DEF_INTERP_HORIZONTAL_BILINEAR_128BPP(6) static SMOL_INLINE void unpack_box_precalc (const uint32_t precalc, uint32_t step, uint32_t *ofs0, uint32_t *ofs1, uint32_t *f0, uint32_t *f1, uint32_t *n) { *ofs0 = precalc; *ofs1 = *ofs0 + step; *f0 = 256 - (*ofs0 % SMOL_SUBPIXEL_MUL); *f1 = *ofs1 % SMOL_SUBPIXEL_MUL; *ofs0 /= SMOL_SUBPIXEL_MUL; *ofs1 /= SMOL_SUBPIXEL_MUL; *n = *ofs1 - *ofs0 - 1; } static void interp_horizontal_boxes_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t *src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { const uint64_t * SMOL_RESTRICT pp; const uint32_t *precalc_x = scale_ctx->hdim.precalc; uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px; uint64_t accum; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); while (dest_row_parts < dest_row_parts_max) { uint32_t ofs0, ofs1; uint32_t f0, f1; uint32_t n; unpack_box_precalc (*(precalc_x++), scale_ctx->hdim.span_step, &ofs0, &ofs1, &f0, &f1, &n); pp = src_row_parts + ofs0; accum = weight_pixel_64bpp (*(pp++), f0); sum_parts_64bpp (&pp, &accum, n); accum += weight_pixel_64bpp (*pp, f1); *(dest_row_parts++) = scale_64bpp (accum, scale_ctx->hdim.span_mul); } } static void interp_horizontal_boxes_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t *src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { const uint64_t * SMOL_RESTRICT pp; const uint32_t *precalc_x = scale_ctx->hdim.precalc; uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px * 2; uint64_t accum [2]; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); while (dest_row_parts < dest_row_parts_max) { uint32_t ofs0, ofs1; uint32_t f0, f1; uint32_t n; uint64_t t [2]; unpack_box_precalc (*(precalc_x++), scale_ctx->hdim.span_step, &ofs0, &ofs1, &f0, &f1, &n); pp = src_row_parts + (ofs0 * 2); weight_pixel_128bpp (pp, accum, f0); pp += 2; sum_parts_128bpp (&pp, accum, n); weight_pixel_128bpp (pp, t, f1); accum [0] += t [0]; accum [1] += t [1]; scale_and_store_128bpp (accum, scale_ctx->hdim.span_mul, (uint64_t * SMOL_RESTRICT *) &dest_row_parts); } } static void interp_horizontal_one_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { uint64_t *row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px; uint64_t part; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t *); part = *row_parts_in; while (row_parts_out != row_parts_out_max) *(row_parts_out++) = part; } static void interp_horizontal_one_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { uint64_t *row_parts_out_max = row_parts_out + scale_ctx->hdim.placement_size_px * 2; SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t *); while (row_parts_out != row_parts_out_max) { *(row_parts_out++) = row_parts_in [0]; *(row_parts_out++) = row_parts_in [1]; } } static void interp_horizontal_copy_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t *); memcpy (row_parts_out, row_parts_in, scale_ctx->hdim.placement_size_px * sizeof (uint64_t)); } static void interp_horizontal_copy_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT row_parts_in, uint64_t * SMOL_RESTRICT row_parts_out) { SMOL_ASSUME_ALIGNED (row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (row_parts_out, uint64_t *); memcpy (row_parts_out, row_parts_in, scale_ctx->hdim.placement_size_px * 2 * sizeof (uint64_t)); } static void scale_horizontal (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, const char *src_row, uint64_t *dest_row_parts) { uint64_t * SMOL_RESTRICT src_row_unpacked; src_row_unpacked = local_ctx->parts_row [3]; /* 32-bit unpackers need 32-bit alignment */ if ((((uintptr_t) src_row) & 3) && scale_ctx->src_pixel_type != SMOL_PIXEL_RGB8 && scale_ctx->src_pixel_type != SMOL_PIXEL_BGR8) { if (!local_ctx->src_aligned) local_ctx->src_aligned = smol_alloc_aligned (scale_ctx->hdim.src_size_px * sizeof (uint32_t), &local_ctx->src_aligned_storage); memcpy (local_ctx->src_aligned, src_row, scale_ctx->hdim.src_size_px * sizeof (uint32_t)); src_row = (const char *) local_ctx->src_aligned; } scale_ctx->src_unpack_row_func (src_row, src_row_unpacked, scale_ctx->hdim.src_size_px); scale_ctx->hfilter_func (scale_ctx, src_row_unpacked, dest_row_parts); apply_horiz_edge_opacity (scale_ctx, dest_row_parts); } /* ---------------- * * Vertical scaling * * ---------------- */ static void update_local_ctx_bilinear (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; uint32_t new_src_ofs = precalc_y [dest_row_index * 2]; if (new_src_ofs == local_ctx->src_ofs) return; if (new_src_ofs == local_ctx->src_ofs + 1) { uint64_t *t = local_ctx->parts_row [0]; local_ctx->parts_row [0] = local_ctx->parts_row [1]; local_ctx->parts_row [1] = t; scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, new_src_ofs + 1), local_ctx->parts_row [1]); } else { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, new_src_ofs), local_ctx->parts_row [0]); scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, new_src_ofs + 1), local_ctx->parts_row [1]); } local_ctx->src_ofs = new_src_ofs; } static void interp_vertical_bilinear_store_64bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_row_parts_in, const uint64_t * SMOL_RESTRICT bottom_row_parts_in, uint64_t * SMOL_RESTRICT parts_out, uint32_t width) { const __m256i mask = _mm256_set_epi16 (0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff); uint64_t *parts_out_last = parts_out + width; __m256i F256; SMOL_ASSUME_ALIGNED (top_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_out, uint64_t *); F256 = _mm256_set1_epi16 ((uint16_t) F); while (parts_out + 4 <= parts_out_last) { __m256i m0, m1; m0 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); top_row_parts_in += 4; m1 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); bottom_row_parts_in += 4; m0 = _mm256_sub_epi16 (m0, m1); m0 = _mm256_mullo_epi16 (m0, F256); m0 = _mm256_srli_epi16 (m0, 8); m0 = _mm256_add_epi16 (m0, m1); m0 = _mm256_and_si256 (m0, mask); _mm256_store_si256 ((__m256i *) parts_out, m0); parts_out += 4; } while (parts_out != parts_out_last) { uint64_t p, q; p = *(top_row_parts_in++); q = *(bottom_row_parts_in++); *(parts_out++) = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; } } static void interp_vertical_bilinear_store_with_opacity_64bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT dest_parts, uint32_t width, uint16_t opacity) { uint64_t *parts_dest_last = dest_parts + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *dest_parts = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; apply_subpixel_opacity_64bpp (dest_parts, opacity); dest_parts++; } while (dest_parts != parts_dest_last); } static void interp_vertical_bilinear_add_64bpp (uint16_t F, const uint64_t *top_row_parts_in, const uint64_t *bottom_row_parts_in, uint64_t *accum_out, uint32_t width) { const __m256i mask = _mm256_set_epi16 (0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff); uint64_t *accum_out_last = accum_out + width; __m256i F256; SMOL_ASSUME_ALIGNED (top_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (accum_out, uint64_t *); F256 = _mm256_set1_epi16 ((uint16_t) F); while (accum_out + 4 <= accum_out_last) { __m256i m0, m1, o0; m0 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); top_row_parts_in += 4; m1 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); bottom_row_parts_in += 4; o0 = _mm256_load_si256 ((const __m256i *) accum_out); m0 = _mm256_sub_epi16 (m0, m1); m0 = _mm256_mullo_epi16 (m0, F256); m0 = _mm256_srli_epi16 (m0, 8); m0 = _mm256_add_epi16 (m0, m1); m0 = _mm256_and_si256 (m0, mask); o0 = _mm256_add_epi16 (o0, m0); _mm256_store_si256 ((__m256i *) accum_out, o0); accum_out += 4; } while (accum_out != accum_out_last) { uint64_t p, q; p = *(top_row_parts_in++); q = *(bottom_row_parts_in++); *(accum_out++) += ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; } } static void interp_vertical_bilinear_store_128bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_row_parts_in, const uint64_t * SMOL_RESTRICT bottom_row_parts_in, uint64_t * SMOL_RESTRICT parts_out, uint32_t width) { uint64_t *parts_out_last = parts_out + width; const __m256i mask = _mm256_set_epi32 ( 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff); __m256i F256; SMOL_ASSUME_ALIGNED (top_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_out, uint64_t *); F256 = _mm256_set1_epi32 ((uint32_t) F); while (parts_out + 8 <= parts_out_last) { __m256i m0, m1, m2, m3; m0 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); top_row_parts_in += 4; m2 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); top_row_parts_in += 4; m1 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); bottom_row_parts_in += 4; m3 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); bottom_row_parts_in += 4; m0 = _mm256_sub_epi32 (m0, m1); m2 = _mm256_sub_epi32 (m2, m3); m0 = _mm256_mullo_epi32 (m0, F256); m2 = _mm256_mullo_epi32 (m2, F256); m0 = _mm256_srli_epi32 (m0, 8); m2 = _mm256_srli_epi32 (m2, 8); m0 = _mm256_add_epi32 (m0, m1); m2 = _mm256_add_epi32 (m2, m3); m0 = _mm256_and_si256 (m0, mask); m2 = _mm256_and_si256 (m2, mask); _mm256_store_si256 ((__m256i *) parts_out, m0); parts_out += 4; _mm256_store_si256 ((__m256i *) parts_out, m2); parts_out += 4; } while (parts_out != parts_out_last) { uint64_t p, q; p = *(top_row_parts_in++); q = *(bottom_row_parts_in++); *(parts_out++) = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; } } static void interp_vertical_bilinear_store_with_opacity_128bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT dest_parts, uint32_t width, uint16_t opacity) { uint64_t *parts_dest_last = dest_parts + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *dest_parts = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; apply_subpixel_opacity_128bpp_half (dest_parts, opacity); dest_parts++; } while (dest_parts != parts_dest_last); } static void interp_vertical_bilinear_add_128bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_row_parts_in, const uint64_t * SMOL_RESTRICT bottom_row_parts_in, uint64_t * SMOL_RESTRICT accum_out, uint32_t width) { uint64_t *accum_out_last = accum_out + width; const __m256i mask = _mm256_set_epi32 ( 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff); __m256i F256; SMOL_ASSUME_ALIGNED (top_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_row_parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (accum_out, uint64_t *); F256 = _mm256_set1_epi32 ((uint32_t) F); while (accum_out + 8 <= accum_out_last) { __m256i m0, m1, m2, m3, o0, o1; m0 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); top_row_parts_in += 4; m2 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); top_row_parts_in += 4; m1 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); bottom_row_parts_in += 4; m3 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); bottom_row_parts_in += 4; o0 = _mm256_load_si256 ((const __m256i *) accum_out); o1 = _mm256_load_si256 ((const __m256i *) (accum_out + 4)); m0 = _mm256_sub_epi32 (m0, m1); m2 = _mm256_sub_epi32 (m2, m3); m0 = _mm256_mullo_epi32 (m0, F256); m2 = _mm256_mullo_epi32 (m2, F256); m0 = _mm256_srli_epi32 (m0, 8); m2 = _mm256_srli_epi32 (m2, 8); m0 = _mm256_add_epi32 (m0, m1); m2 = _mm256_add_epi32 (m2, m3); m0 = _mm256_and_si256 (m0, mask); m2 = _mm256_and_si256 (m2, mask); o0 = _mm256_add_epi32 (o0, m0); o1 = _mm256_add_epi32 (o1, m2); _mm256_store_si256 ((__m256i *) accum_out, o0); accum_out += 4; _mm256_store_si256 ((__m256i *) accum_out, o1); accum_out += 4; } while (accum_out != accum_out_last) { uint64_t p, q; p = *(top_row_parts_in++); q = *(bottom_row_parts_in++); *(accum_out++) += ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; } } #define DEF_INTERP_VERTICAL_BILINEAR_FINAL(n_halvings) \ static void \ interp_vertical_bilinear_final_##n_halvings##h_64bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_row_parts_in, \ const uint64_t * SMOL_RESTRICT bottom_row_parts_in, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width) \ { \ const __m256i mask = _mm256_set_epi16 (0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, \ 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff, 0x00ff); \ uint64_t *accum_inout_last = accum_inout + width; \ __m256i F256; \ \ SMOL_ASSUME_ALIGNED (top_row_parts_in, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_row_parts_in, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ F256 = _mm256_set1_epi16 ((uint16_t) F); \ \ while (accum_inout + 4 <= accum_inout_last) \ { \ __m256i m0, m1, o0; \ \ m0 = _mm256_load_si256 ((const __m256i *) top_row_parts_in); \ top_row_parts_in += 4; \ m1 = _mm256_load_si256 ((const __m256i *) bottom_row_parts_in); \ bottom_row_parts_in += 4; \ o0 = _mm256_load_si256 ((const __m256i *) accum_inout); \ \ m0 = _mm256_sub_epi16 (m0, m1); \ m0 = _mm256_mullo_epi16 (m0, F256); \ m0 = _mm256_srli_epi16 (m0, 8); \ m0 = _mm256_add_epi16 (m0, m1); \ m0 = _mm256_and_si256 (m0, mask); \ \ o0 = _mm256_add_epi16 (o0, m0); \ o0 = _mm256_srli_epi16 (o0, n_halvings); \ \ _mm256_store_si256 ((__m256i *) accum_inout, o0); \ accum_inout += 4; \ } \ \ while (accum_inout != accum_inout_last) \ { \ uint64_t p, q; \ \ p = *(top_row_parts_in++); \ q = *(bottom_row_parts_in++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ff00ff00ff00ffULL; \ \ *(accum_inout++) = p; \ } \ } \ static void \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_64bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width, \ uint16_t opacity) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ff00ff00ff00ffULL; \ \ apply_subpixel_opacity_64bpp (&p, opacity); \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } \ \ static void \ interp_vertical_bilinear_final_##n_halvings##h_128bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ffffff00ffffffULL; \ \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } \ \ static void \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_128bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width, \ uint16_t opacity) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ffffff00ffffffULL; \ \ apply_subpixel_opacity_128bpp_half (&p, opacity); \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } #define DEF_SCALE_DEST_ROW_BILINEAR(n_halvings) \ static int \ scale_dest_row_bilinear_##n_halvings##h_64bpp (const SmolScaleCtx *scale_ctx, \ SmolLocalCtx *local_ctx, \ uint32_t dest_row_index) \ { \ uint16_t *precalc_y = scale_ctx->vdim.precalc; \ uint32_t bilin_index = dest_row_index << (n_halvings); \ unsigned int i; \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_store_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px); \ bilin_index++; \ \ for (i = 0; i < (1 << (n_halvings)) - 2; i++) \ { \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_add_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px); \ bilin_index++; \ } \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ \ if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px, \ scale_ctx->vdim.first_opacity); \ else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px, \ scale_ctx->vdim.last_opacity); \ else \ interp_vertical_bilinear_final_##n_halvings##h_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px); \ \ return 2; \ } \ \ static int \ scale_dest_row_bilinear_##n_halvings##h_128bpp (const SmolScaleCtx *scale_ctx, \ SmolLocalCtx *local_ctx, \ uint32_t dest_row_index) \ { \ uint16_t *precalc_y = scale_ctx->vdim.precalc; \ uint32_t bilin_index = dest_row_index << (n_halvings); \ unsigned int i; \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_store_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2); \ bilin_index++; \ \ for (i = 0; i < (1 << (n_halvings)) - 2; i++) \ { \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_add_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2); \ bilin_index++; \ } \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ \ if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2, \ scale_ctx->vdim.first_opacity); \ else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2, \ scale_ctx->vdim.last_opacity); \ else \ interp_vertical_bilinear_final_##n_halvings##h_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2); \ \ return 2; \ } static int scale_dest_row_bilinear_0h_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; update_local_ctx_bilinear (scale_ctx, local_ctx, dest_row_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_store_with_opacity_64bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_store_with_opacity_64bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_store_64bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px); return 2; } static int scale_dest_row_bilinear_0h_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; update_local_ctx_bilinear (scale_ctx, local_ctx, dest_row_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_store_with_opacity_128bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_store_with_opacity_128bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_store_128bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2); return 2; } DEF_INTERP_VERTICAL_BILINEAR_FINAL(1) static int scale_dest_row_bilinear_1h_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; uint32_t bilin_index = dest_row_index << 1; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); interp_vertical_bilinear_store_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px); bilin_index++; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_final_1h_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px); return 2; } static int scale_dest_row_bilinear_1h_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; uint32_t bilin_index = dest_row_index << 1; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); interp_vertical_bilinear_store_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2); bilin_index++; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_final_1h_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2); return 2; } DEF_INTERP_VERTICAL_BILINEAR_FINAL(2) DEF_SCALE_DEST_ROW_BILINEAR(2) DEF_INTERP_VERTICAL_BILINEAR_FINAL(3) DEF_SCALE_DEST_ROW_BILINEAR(3) DEF_INTERP_VERTICAL_BILINEAR_FINAL(4) DEF_SCALE_DEST_ROW_BILINEAR(4) DEF_INTERP_VERTICAL_BILINEAR_FINAL(5) DEF_SCALE_DEST_ROW_BILINEAR(5) DEF_INTERP_VERTICAL_BILINEAR_FINAL(6) DEF_SCALE_DEST_ROW_BILINEAR(6) static void finalize_vertical_64bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT parts_out, uint32_t n) { uint64_t *parts_out_max = parts_out + n; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_out, uint64_t *); while (parts_out != parts_out_max) { *(parts_out++) = scale_64bpp (*(accums++), multiplier); } } static void finalize_vertical_with_opacity_64bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n, uint16_t opacity) { uint64_t *parts_dest_max = dest_parts + n; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { *dest_parts = scale_64bpp (*(accums++), multiplier); apply_subpixel_opacity_64bpp (dest_parts, opacity); dest_parts++; } } static int scale_dest_row_box_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint32_t *precalc_y = scale_ctx->vdim.precalc; uint32_t ofs_y, ofs_y_max; uint32_t w1, w2; uint32_t n, i; unpack_box_precalc (precalc_y [dest_row_index], scale_ctx->vdim.span_step, &ofs_y, &ofs_y_max, &w1, &w2, &n); /* First input row */ scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); copy_weighted_parts_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w1); ofs_y++; /* Add up whole input rows */ for (i = 0; i < n; i++) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_parts (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px); ofs_y++; } /* Last input row */ if (ofs_y < scale_ctx->vdim.src_size_px) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_weighted_parts_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w2); } /* Finalize */ if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) { finalize_vertical_with_opacity_64bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (dest_row_index == scale_ctx->vdim.placement_size_px - 1 && scale_ctx->vdim.last_opacity < 256) { finalize_vertical_with_opacity_64bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { finalize_vertical_64bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px); } return 0; } static void finalize_vertical_128bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n) { uint64_t *parts_dest_max = dest_parts + n * 2; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { *(dest_parts++) = scale_128bpp_half (*(accums++), multiplier); *(dest_parts++) = scale_128bpp_half (*(accums++), multiplier); } } static void finalize_vertical_with_opacity_128bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n, uint16_t opacity) { uint64_t *parts_dest_max = dest_parts + n * 2; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { dest_parts [0] = scale_128bpp_half (*(accums++), multiplier); dest_parts [1] = scale_128bpp_half (*(accums++), multiplier); apply_subpixel_opacity_128bpp (dest_parts, opacity); dest_parts += 2; } } static int scale_dest_row_box_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint32_t *precalc_y = scale_ctx->vdim.precalc; uint32_t ofs_y, ofs_y_max; uint32_t w1, w2; uint32_t n, i; unpack_box_precalc (precalc_y [dest_row_index], scale_ctx->vdim.span_step, &ofs_y, &ofs_y_max, &w1, &w2, &n); /* First input row */ scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); copy_weighted_parts_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w1); ofs_y++; /* Add up whole input rows */ for (i = 0; i < n; i++) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_parts (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px * 2); ofs_y++; } /* Last input row */ if (ofs_y < scale_ctx->vdim.src_size_px) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_weighted_parts_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w2); } if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) { finalize_vertical_with_opacity_128bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (dest_row_index == scale_ctx->vdim.placement_size_px - 1 && scale_ctx->vdim.last_opacity < 256) { finalize_vertical_with_opacity_128bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { finalize_vertical_128bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px); } return 0; } static int scale_dest_row_one_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t row_index) { /* Scale the row and store it */ if (local_ctx->src_ofs != 0) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, 0), local_ctx->parts_row [0]); local_ctx->src_ofs = 0; } if (row_index == 0 && scale_ctx->vdim.first_opacity < 256) { apply_subpixel_opacity_row_copy_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) { apply_subpixel_opacity_row_copy_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { memcpy (local_ctx->parts_row [1], local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px * sizeof (uint64_t)); } return 1; } static int scale_dest_row_one_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t row_index) { /* Scale the row and store it */ if (local_ctx->src_ofs != 0) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, 0), local_ctx->parts_row [0]); local_ctx->src_ofs = 0; } if (row_index == 0 && scale_ctx->vdim.first_opacity < 256) { apply_subpixel_opacity_row_copy_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) { apply_subpixel_opacity_row_copy_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { memcpy (local_ctx->parts_row [1], local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px * sizeof (uint64_t) * 2); } return 1; } static int scale_dest_row_copy (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t row_index) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, row_index), local_ctx->parts_row [0]); return 0; } /* --------------- * * Function tables * * --------------- */ #define R SMOL_REPACK_META static const SmolRepackMeta repack_meta [] = { R (123, 24, PREMUL8, COMPRESSED, 1324, 64, PREMUL8, COMPRESSED), R (123, 24, PREMUL8, COMPRESSED, 1234, 128, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 1324, 64, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 2431, 64, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 3241, 64, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 1324, 64, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 2431, 64, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 3241, 64, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 1234, 128, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 2341, 128, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 1234, 128, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 2341, 128, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 1234, 128, PREMUL16, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 2341, 128, PREMUL16, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 132, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 231, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 324, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 423, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 132, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 231, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 324, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 423, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1324, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1423, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 2314, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4132, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4231, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1324, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1423, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 2314, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4132, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4231, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 123, 24, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 321, 24, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 123, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 321, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 123, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 321, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 1234, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 3214, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4123, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4321, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 1234, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 3214, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4123, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4321, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 1234, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 3214, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 4123, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 4321, 32, UNASSOCIATED, COMPRESSED), SMOL_REPACK_META_LAST }; #undef R static const SmolImplementation implementation = { /* Horizontal init */ init_horizontal, /* Vertical init */ init_vertical, { /* Horizontal filters */ { /* 24bpp */ NULL }, { /* 32bpp */ NULL }, { /* 64bpp */ interp_horizontal_copy_64bpp, interp_horizontal_one_64bpp, interp_horizontal_bilinear_0h_64bpp, interp_horizontal_bilinear_1h_64bpp, interp_horizontal_bilinear_2h_64bpp, interp_horizontal_bilinear_3h_64bpp, interp_horizontal_bilinear_4h_64bpp, interp_horizontal_bilinear_5h_64bpp, interp_horizontal_bilinear_6h_64bpp, interp_horizontal_boxes_64bpp }, { /* 128bpp */ interp_horizontal_copy_128bpp, interp_horizontal_one_128bpp, interp_horizontal_bilinear_0h_128bpp, interp_horizontal_bilinear_1h_128bpp, interp_horizontal_bilinear_2h_128bpp, interp_horizontal_bilinear_3h_128bpp, interp_horizontal_bilinear_4h_128bpp, interp_horizontal_bilinear_5h_128bpp, interp_horizontal_bilinear_6h_128bpp, interp_horizontal_boxes_128bpp } }, { /* Vertical filters */ { /* 24bpp */ NULL }, { /* 32bpp */ NULL }, { /* 64bpp */ scale_dest_row_copy, scale_dest_row_one_64bpp, scale_dest_row_bilinear_0h_64bpp, scale_dest_row_bilinear_1h_64bpp, scale_dest_row_bilinear_2h_64bpp, scale_dest_row_bilinear_3h_64bpp, scale_dest_row_bilinear_4h_64bpp, scale_dest_row_bilinear_5h_64bpp, scale_dest_row_bilinear_6h_64bpp, scale_dest_row_box_64bpp }, { /* 128bpp */ scale_dest_row_copy, scale_dest_row_one_128bpp, scale_dest_row_bilinear_0h_128bpp, scale_dest_row_bilinear_1h_128bpp, scale_dest_row_bilinear_2h_128bpp, scale_dest_row_bilinear_3h_128bpp, scale_dest_row_bilinear_4h_128bpp, scale_dest_row_bilinear_5h_128bpp, scale_dest_row_bilinear_6h_128bpp, scale_dest_row_box_128bpp } }, { /* Composite over color */ { { NULL, NULL, NULL }, { NULL, NULL, NULL } }, /* 24bpp - unused */ { { NULL, NULL, NULL }, { NULL, NULL, NULL } }, /* 32bpp - unused */ { { NULL, NULL, NULL }, { NULL, NULL, NULL } }, /* 64bpp */ { { NULL, NULL, NULL }, { NULL, NULL, NULL } }, /* 128bpp */ }, { /* Composite over dest */ NULL, NULL, NULL, NULL }, { /* Clear dest */ NULL, NULL, NULL, NULL }, repack_meta }; const SmolImplementation * _smol_get_avx2_implementation (void) { return &implementation; } chafa-1.18.2/chafa/internal/smolscale/smolscale-generic.c000066400000000000000000003443331517447374300232760ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright © 2019-2025 Hans Petter Jansson. See COPYING for details. */ #include #include /* malloc, free, alloca */ #include /* memset */ #include #include "smolscale-private.h" /* ---------------------- * * Context initialization * * ---------------------- */ /* Linear precalc array: * * Each sample is extracted from a pair of adjacent pixels. The sample precalc * consists of the first pixel's index, followed by its sample fraction [0..256]. * The second sample is implicitly taken at index+1 and weighted as 256-fraction. * _ _ _ * In |_| |_| |_| * \_/ \_/ <- two samples per output pixel * Out |_| |_| * * When halving, * _ _ _ * In |_| |_| |_| * \_/ \_/ <- four samples per output pixel * |_| |_| * \_/ <- halving * Out |_| */ static void precalc_linear_range (uint16_t *array_out, int first_index, int last_index, uint64_t first_sample_ofs, uint64_t sample_step, int sample_ofs_px_max, int32_t dest_clip_before_px, int *array_i_inout) { uint64_t sample_ofs; int i; sample_ofs = first_sample_ofs; for (i = first_index; i < last_index; i++) { uint16_t sample_ofs_px = sample_ofs / SMOL_BILIN_MULTIPLIER; if (sample_ofs_px >= sample_ofs_px_max - 1) { if (i >= dest_clip_before_px) { array_out [(*array_i_inout) * 2] = sample_ofs_px_max - 2; array_out [(*array_i_inout) * 2 + 1] = 0; (*array_i_inout)++; } continue; } if (i >= dest_clip_before_px) { array_out [(*array_i_inout) * 2] = sample_ofs_px; array_out [(*array_i_inout) * 2 + 1] = SMOL_SMALL_MUL - ((sample_ofs / (SMOL_BILIN_MULTIPLIER / SMOL_SMALL_MUL)) % SMOL_SMALL_MUL); (*array_i_inout)++; } sample_ofs += sample_step; } } static void precalc_bilinear_array (uint16_t *array, uint64_t src_dim_spx, uint64_t dest_ofs_spx, uint64_t dest_dim_spx, uint32_t dest_dim_prehalving_px, unsigned int n_halvings, int32_t dest_clip_before_px) { uint32_t src_dim_px = SMOL_SPX_TO_PX (src_dim_spx); uint64_t first_sample_ofs [3]; uint64_t sample_step; int i = 0; assert (src_dim_px > 1); dest_ofs_spx %= SMOL_SUBPIXEL_MUL; if (src_dim_spx > dest_dim_spx) { /* Minification */ sample_step = ((uint64_t) src_dim_spx * SMOL_BILIN_MULTIPLIER) / dest_dim_spx; first_sample_ofs [0] = (sample_step - SMOL_BILIN_MULTIPLIER) / 2; first_sample_ofs [1] = ((sample_step - SMOL_BILIN_MULTIPLIER) / 2) + ((sample_step * (SMOL_SUBPIXEL_MUL - dest_ofs_spx) * (1 << n_halvings)) / SMOL_SUBPIXEL_MUL); } else { /* Magnification */ sample_step = ((src_dim_spx - SMOL_SUBPIXEL_MUL) * SMOL_BILIN_MULTIPLIER) / (dest_dim_spx > SMOL_SUBPIXEL_MUL ? (dest_dim_spx - SMOL_SUBPIXEL_MUL) : 1); first_sample_ofs [0] = 0; first_sample_ofs [1] = (sample_step * (SMOL_SUBPIXEL_MUL - dest_ofs_spx)) / SMOL_SUBPIXEL_MUL; } first_sample_ofs [2] = ((((uint64_t) src_dim_spx * SMOL_BILIN_MULTIPLIER * 2) / SMOL_SUBPIXEL_MUL) + sample_step - SMOL_BILIN_MULTIPLIER) / 2 - sample_step * (1U << n_halvings); /* Left fringe */ precalc_linear_range (array, 0, 1 << n_halvings, first_sample_ofs [0], sample_step, src_dim_px, dest_clip_before_px, &i); /* Check to prevent overruns when the output size is exactly 1 */ if (dest_dim_prehalving_px > (1U << n_halvings)) { /* Main range */ precalc_linear_range (array, 1 << n_halvings, dest_dim_prehalving_px - (1 << n_halvings), first_sample_ofs [1], sample_step, src_dim_px, dest_clip_before_px, &i); /* Right fringe */ precalc_linear_range (array, dest_dim_prehalving_px - (1 << n_halvings), dest_dim_prehalving_px, first_sample_ofs [2], sample_step, src_dim_px, dest_clip_before_px, &i); } } static void precalc_boxes_array (uint32_t *array, uint32_t *span_step, uint32_t *span_mul, uint32_t src_dim_spx, int32_t dest_dim, uint32_t dest_ofs_spx, uint32_t dest_dim_spx, int32_t dest_clip_before_px) { uint64_t fracF, frac_stepF; uint64_t f; uint64_t stride; uint64_t a, b; int i, dest_i; dest_ofs_spx %= SMOL_SUBPIXEL_MUL; /* Output sample can't be less than a pixel. Fringe opacity is applied in * a separate step. FIXME: May cause wrong subpixel distribution -- revisit. */ if (dest_dim_spx < 256) dest_dim_spx = 256; frac_stepF = ((uint64_t) src_dim_spx * SMOL_BIG_MUL) / (uint64_t) dest_dim_spx; fracF = 0; stride = frac_stepF / (uint64_t) SMOL_BIG_MUL; f = (frac_stepF / SMOL_SMALL_MUL) % SMOL_SMALL_MUL; /* We divide by (b + 1) instead of just (b) to avoid overflows in * scale_128bpp_half(), which would affect horizontal box scaling. The * fudge factor counters limited precision in the inverted division * operation. It causes 16-bit values to undershoot by less than 127/65535 * (<.2%). Since the final output is 8-bit, and rounding neutralizes the * error, this doesn't matter. */ a = (SMOL_BOXES_MULTIPLIER * 255); b = ((stride * 255) + ((f * 255) / 256)); *span_step = frac_stepF / SMOL_SMALL_MUL; *span_mul = (a + (b / 2)) / (b + 1); /* Left fringe */ i = 0; dest_i = 0; if (dest_i >= dest_clip_before_px) array [i++] = 0; /* Main range */ fracF = ((frac_stepF * (SMOL_SUBPIXEL_MUL - dest_ofs_spx)) / SMOL_SUBPIXEL_MUL); for (dest_i = 1; dest_i < dest_dim - 1; dest_i++) { if (dest_i >= dest_clip_before_px) array [i++] = fracF / SMOL_SMALL_MUL; fracF += frac_stepF; } /* Right fringe */ if (dest_dim > 1 && dest_i >= dest_clip_before_px) array [i++] = (((uint64_t) src_dim_spx * SMOL_SMALL_MUL - frac_stepF) / SMOL_SMALL_MUL); } static void init_dim (SmolDim *dim) { if (dim->filter_type == SMOL_FILTER_ONE || dim->filter_type == SMOL_FILTER_COPY) { } else if (dim->filter_type == SMOL_FILTER_BOX) { precalc_boxes_array (dim->precalc, &dim->span_step, &dim->span_mul, dim->src_size_spx, dim->placement_size_px, dim->placement_ofs_spx, dim->placement_size_spx, dim->clip_before_px); } else /* SMOL_FILTER_BILINEAR_?H */ { precalc_bilinear_array (dim->precalc, dim->src_size_spx, dim->placement_ofs_spx, dim->placement_size_prehalving_spx, dim->placement_size_prehalving_px, dim->n_halvings, dim->clip_before_px); } } static void init_horizontal (SmolScaleCtx *scale_ctx) { init_dim (&scale_ctx->hdim); } static void init_vertical (SmolScaleCtx *scale_ctx) { init_dim (&scale_ctx->vdim); } /* ---------------------- * * sRGB/linear conversion * * ---------------------- */ static void from_srgb_pixel_xxxa_128bpp (uint64_t * SMOL_RESTRICT pixel_inout) { uint64_t part; part = pixel_inout [0]; pixel_inout [0] = ((uint64_t) _smol_from_srgb_lut [part >> 32] << 32) | _smol_from_srgb_lut [part & 0xff]; part = pixel_inout [1]; pixel_inout [1] = ((uint64_t) _smol_from_srgb_lut [part >> 32] << 32) | ((part & 0xffffffff) << 3) | 7; } static void to_srgb_pixel_xxxa_128bpp (const uint64_t *pixel_in, uint64_t *pixel_out) { pixel_out [0] = (((uint64_t) _smol_to_srgb_lut [pixel_in [0] >> 32]) << 32) | _smol_to_srgb_lut [pixel_in [0] & 0xffff]; pixel_out [1] = (((uint64_t) _smol_to_srgb_lut [pixel_in [1] >> 32]) << 32) | (pixel_in [1] & 0xffffffff); /* FIXME: No need to preserve alpha? */ } /* Fetches alpha from linear pixel. Input alpha is in the range [0x000..0x7ff]. * Returned alpha is in the range [0x00..0xff], rounded towards 0xff. */ static SMOL_INLINE uint8_t get_alpha_from_linear_xxxa_128bpp (const uint64_t * SMOL_RESTRICT pixel_in) { uint16_t alpha = (pixel_in [1] + 7) >> 3; return (uint8_t) (alpha - (alpha >> 8)); /* Turn 0x100 into 0xff */ } /* ----------------- * * Premultiplication * * ----------------- */ static SMOL_INLINE void premul_u_to_p8_128bpp (uint64_t * SMOL_RESTRICT inout, uint16_t alpha) { inout [0] = ((inout [0] * (alpha + 1)) >> 8) & 0x000000ff000000ff; inout [1] = ((inout [1] * (alpha + 1)) >> 8) & 0x000000ff000000ff; } static SMOL_INLINE void unpremul_p8_to_u_128bpp (const uint64_t *in, uint64_t *out, uint8_t alpha) { out [0] = ((in [0] * _smol_inv_div_p8_lut [alpha]) >> INVERTED_DIV_SHIFT_P8) & 0x000000ff000000ff; out [1] = ((in [1] * _smol_inv_div_p8_lut [alpha]) >> INVERTED_DIV_SHIFT_P8) & 0x000000ff000000ff; } static SMOL_INLINE uint64_t premul_u_to_p8_64bpp (const uint64_t in, uint16_t alpha) { return ((in * (alpha + 1)) >> 8) & 0x00ff00ff00ff00ff; } static SMOL_INLINE uint64_t unpremul_p8_to_u_64bpp (const uint64_t in, uint8_t alpha) { uint64_t in_128bpp [2]; uint64_t dest_128bpp [2]; in_128bpp [0] = (in & 0x000000ff000000ff); in_128bpp [1] = (in & 0x00ff000000ff0000) >> 16; unpremul_p8_to_u_128bpp (in_128bpp, dest_128bpp, alpha); return dest_128bpp [0] | (dest_128bpp [1] << 16); } static SMOL_INLINE void premul_ul_to_p8l_128bpp (uint64_t * SMOL_RESTRICT inout, uint16_t alpha) { inout [0] = ((inout [0] * (alpha + 1)) >> 8) & 0x000007ff000007ff; inout [1] = (((inout [1] * (alpha + 1)) >> 8) & 0x000007ff00000000) | (inout [1] & 0x000007ff); } static SMOL_INLINE void unpremul_p8l_to_ul_128bpp (const uint64_t *in, uint64_t *out, uint8_t alpha) { out [0] = ((in [0] * _smol_inv_div_p8l_lut [alpha]) >> INVERTED_DIV_SHIFT_P8L) & 0x000007ff000007ff; out [1] = ((in [1] * _smol_inv_div_p8l_lut [alpha]) >> INVERTED_DIV_SHIFT_P8L) & 0x000007ff000007ff; } static SMOL_INLINE void premul_u_to_p16_128bpp (uint64_t *inout, uint8_t alpha) { inout [0] = inout [0] * ((uint16_t) alpha + 2); inout [1] = inout [1] * ((uint16_t) alpha + 2); } static SMOL_INLINE void unpremul_p16_to_u_128bpp (const uint64_t * SMOL_RESTRICT in, uint64_t * SMOL_RESTRICT out, uint8_t alpha) { out [0] = ((in [0] * _smol_inv_div_p16_lut [alpha]) >> INVERTED_DIV_SHIFT_P16) & 0x000000ff000000ffULL; out [1] = ((in [1] * _smol_inv_div_p16_lut [alpha]) >> INVERTED_DIV_SHIFT_P16) & 0x000000ff000000ffULL; } static SMOL_INLINE void premul_ul_to_p16l_128bpp (uint64_t *inout, uint8_t alpha) { inout [0] = inout [0] * ((uint16_t) alpha + 2); inout [1] = inout [1] * ((uint16_t) alpha + 2); } static SMOL_INLINE void unpremul_p16l_to_ul_128bpp (const uint64_t * SMOL_RESTRICT in, uint64_t * SMOL_RESTRICT out, uint8_t alpha) { out [0] = ((in [0] * _smol_inv_div_p16l_lut [alpha]) >> INVERTED_DIV_SHIFT_P16L) & 0x000007ff000007ffULL; out [1] = ((in [1] * _smol_inv_div_p16l_lut [alpha]) >> INVERTED_DIV_SHIFT_P16L) & 0x000007ff000007ffULL; } /* --------- * * Repacking * * --------- */ /* It's nice to be able to shift by a negative amount */ #define SHIFT_S(in, s) ((s >= 0) ? (in) << (s) : (in) >> -(s)) /* This is kind of bulky (~13 x86 insns), but it's about the same as using * unions, and we don't have to worry about endianness. */ #define PACK_FROM_1234_64BPP(in, a, b, c, d) \ ((SHIFT_S ((in), ((a) - 1) * 16 + 8 - 32) & 0xff000000) \ | (SHIFT_S ((in), ((b) - 1) * 16 + 8 - 40) & 0x00ff0000) \ | (SHIFT_S ((in), ((c) - 1) * 16 + 8 - 48) & 0x0000ff00) \ | (SHIFT_S ((in), ((d) - 1) * 16 + 8 - 56) & 0x000000ff)) #define PACK_FROM_1234_128BPP(in, a, b, c, d) \ ((SHIFT_S ((in [((a) - 1) >> 1]), (((a) - 1) & 1) * 32 + 24 - 32) & 0xff000000) \ | (SHIFT_S ((in [((b) - 1) >> 1]), (((b) - 1) & 1) * 32 + 24 - 40) & 0x00ff0000) \ | (SHIFT_S ((in [((c) - 1) >> 1]), (((c) - 1) & 1) * 32 + 24 - 48) & 0x0000ff00) \ | (SHIFT_S ((in [((d) - 1) >> 1]), (((d) - 1) & 1) * 32 + 24 - 56) & 0x000000ff)) #define SWAP_2_AND_3(n) ((n) == 2 ? 3 : (n) == 3 ? 2 : n) #define PACK_FROM_1324_64BPP(in, a, b, c, d) \ ((SHIFT_S ((in), (SWAP_2_AND_3 (a) - 1) * 16 + 8 - 32) & 0xff000000) \ | (SHIFT_S ((in), (SWAP_2_AND_3 (b) - 1) * 16 + 8 - 40) & 0x00ff0000) \ | (SHIFT_S ((in), (SWAP_2_AND_3 (c) - 1) * 16 + 8 - 48) & 0x0000ff00) \ | (SHIFT_S ((in), (SWAP_2_AND_3 (d) - 1) * 16 + 8 - 56) & 0x000000ff)) /* ---------------------- * * Repacking: 24/32 -> 64 * * ---------------------- */ static SMOL_INLINE uint64_t unpack_pixel_123_p8_to_132a_p8_64bpp (const uint8_t *p) { return ((uint64_t) p [0] << 48) | ((uint32_t) p [1] << 16) | ((uint64_t) p [2] << 32) | 0xff; } SMOL_REPACK_ROW_DEF (123, 24, 8, PREMUL8, COMPRESSED, 1324, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_123_p8_to_132a_p8_64bpp (src_row); src_row += 3; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_p8_to_1324_p8_64bpp (uint32_t p) { return (((uint64_t) p & 0xff00ff00) << 24) | (p & 0x00ff00ff); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 1324, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_p8_to_3241_p8_64bpp (uint32_t p) { return (((uint64_t) p & 0x0000ff00) << 40) | (((uint64_t) p & 0x00ff00ff) << 16) | (p >> 24); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 3241, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_p8_to_3241_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_p8_to_2431_p8_64bpp (uint32_t p) { uint64_t p64 = p; return ((p64 & 0x00ff00ff) << 32) | ((p64 & 0x0000ff00) << 8) | ((p64 & 0xff000000) >> 24); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 2431, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_p8_to_2431_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_a234_u_to_324a_p8_64bpp (uint32_t p) { uint64_t p64 = (((uint64_t) p & 0x0000ff00) << 40) | (((uint64_t) p & 0x00ff00ff) << 16); uint8_t alpha = p >> 24; return (premul_u_to_p8_64bpp (p64, alpha) & 0xffffffffffffff00ULL) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 3241, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_a234_u_to_324a_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_1234_u_to_2431_p8_64bpp (uint32_t p) { uint64_t p64 = (((uint64_t) p & 0x00ff00ff) << 32) | (((uint64_t) p & 0x0000ff00) << 8); uint8_t alpha = p >> 24; return (premul_u_to_p8_64bpp (p64, alpha) & 0xffffffffffffff00ULL) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2431, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_1234_u_to_2431_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE uint64_t unpack_pixel_123a_u_to_132a_p8_64bpp (uint32_t p) { uint64_t p64 = (((uint64_t) p & 0xff00ff00) << 24) | (p & 0x00ff0000); uint8_t alpha = p & 0xff; return (premul_u_to_p8_64bpp (p64, alpha) & 0xffffffffffffff00ULL) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1324, 64, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = unpack_pixel_123a_u_to_132a_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END /* ----------------------- * * Repacking: 24/32 -> 128 * * ----------------------- */ static SMOL_INLINE void unpack_pixel_123_p8_to_123a_p8_128bpp (const uint8_t *in, uint64_t *out) { out [0] = ((uint64_t) in [0] << 32) | in [1]; out [1] = ((uint64_t) in [2] << 32) | 0xff; } SMOL_REPACK_ROW_DEF (123, 24, 8, PREMUL8, COMPRESSED, 1234, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123_p8_to_123a_p8_128bpp (src_row, dest_row); src_row += 3; dest_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (123, 24, 8, PREMUL8, COMPRESSED, 1234, 128, 64, PREMUL8, LINEAR) { while (dest_row != dest_row_max) { uint8_t alpha; unpack_pixel_123_p8_to_123a_p8_128bpp (src_row, dest_row); alpha = dest_row [1]; from_srgb_pixel_xxxa_128bpp (dest_row); dest_row [1] = (dest_row [1] & 0xffffffff00000000) | (alpha << 3) | 7; src_row += 3; dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_p8_to_123a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; out [0] = ((p64 & 0xff000000) << 8) | ((p64 & 0x00ff0000) >> 16); out [1] = ((p64 & 0x0000ff00) << 24) | (p64 & 0x000000ff); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 1234, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123a_p8_to_123a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 1234, 128, 64, PREMUL8, LINEAR) { while (dest_row != dest_row_max) { uint8_t alpha; unpack_pixel_123a_p8_to_123a_p8_128bpp (*(src_row++), dest_row); alpha = dest_row [1]; from_srgb_pixel_xxxa_128bpp (dest_row); dest_row [1] = (dest_row [1] & 0xffffffff00000000) | (alpha << 3) | 7; dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_p8_to_234a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; out [0] = ((p64 & 0x00ff0000) << 16) | ((p64 & 0x0000ff00) >> 8); out [1] = ((p64 & 0x000000ff) << 32) | ((p64 & 0xff000000) >> 24); } SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 2341, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_a234_p8_to_234a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 32, 32, PREMUL8, COMPRESSED, 2341, 128, 64, PREMUL8, LINEAR) { while (dest_row != dest_row_max) { uint8_t alpha; unpack_pixel_a234_p8_to_234a_p8_128bpp (*(src_row++), dest_row); alpha = dest_row [1]; from_srgb_pixel_xxxa_128bpp (dest_row); dest_row [1] = (dest_row [1] & 0xffffffff00000000) | (alpha << 3) | 7; dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_u_to_234a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = (((uint64_t) p & 0x00ff00ff) << 32) | (((uint64_t) p & 0x0000ff00) << 8); uint8_t alpha = p >> 24; p64 = (premul_u_to_p8_64bpp (p64, alpha) & 0xffffffffffffff00) | alpha; out [0] = (p64 >> 16) & 0x000000ff000000ff; out [1] = p64 & 0x000000ff000000ff; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2341, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_a234_u_to_234a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_u_to_234a_pl_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint8_t alpha = p >> 24; out [0] = ((p64 & 0x00ff0000) << 16) | ((p64 & 0x0000ff00) >> 8); out [1] = ((p64 & 0x000000ff) << 32) | alpha; from_srgb_pixel_xxxa_128bpp (out); premul_ul_to_p8l_128bpp (out, alpha); } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2341, 128, 64, PREMUL8, LINEAR) { while (dest_row != dest_row_max) { unpack_pixel_a234_u_to_234a_pl_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_u_to_234a_p16_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint8_t alpha = p >> 24; out [0] = ((p64 & 0x00ff0000) << 16) | ((p64 & 0x0000ff00) >> 8); out [1] = ((p64 & 0x000000ff) << 32); premul_u_to_p16_128bpp (out, alpha); out [1] |= (((uint16_t) alpha) << 8) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2341, 128, 64, PREMUL16, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_a234_u_to_234a_p16_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_a234_u_to_234a_p16l_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint8_t alpha = p >> 24; out [0] = ((p64 & 0x00ff0000) << 16) | ((p64 & 0x0000ff00) >> 8); out [1] = ((p64 & 0x000000ff) << 32); from_srgb_pixel_xxxa_128bpp (out); out [0] *= alpha; out [1] *= alpha; out [1] = (out [1] & 0xffffffff00000000ULL) | (alpha << 8) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 2341, 128, 64, PREMUL16, LINEAR) { while (dest_row != dest_row_max) { unpack_pixel_a234_u_to_234a_p16l_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_u_to_123a_p8_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = (((uint64_t) p & 0xff00ff00) << 24) | (p & 0x00ff0000); uint8_t alpha = p; p64 = (premul_u_to_p8_64bpp (p64, alpha) & 0xffffffffffffff00ULL) | alpha; out [0] = (p64 >> 16) & 0x000000ff000000ff; out [1] = p64 & 0x000000ff000000ff; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1234, 128, 64, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123a_u_to_123a_p8_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_u_to_123a_pl_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint8_t alpha = p; out [0] = ((p64 & 0xff000000) << 8) | ((p64 & 0x00ff0000) >> 16); out [1] = ((p64 & 0x0000ff00) << 24) | alpha; from_srgb_pixel_xxxa_128bpp (out); premul_ul_to_p8l_128bpp (out, alpha); } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1234, 128, 64, PREMUL8, LINEAR) { while (dest_row != dest_row_max) { unpack_pixel_123a_u_to_123a_pl_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_u_to_123a_p16_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint8_t alpha = p; out [0] = ((p64 & 0xff000000) << 8) | ((p64 & 0x00ff0000) >> 16); out [1] = ((p64 & 0x0000ff00) << 24); premul_u_to_p16_128bpp (out, alpha); out [1] |= (((uint16_t) alpha) << 8) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1234, 128, 64, PREMUL16, COMPRESSED) { while (dest_row != dest_row_max) { unpack_pixel_123a_u_to_123a_p16_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END static SMOL_INLINE void unpack_pixel_123a_u_to_123a_p16l_128bpp (uint32_t p, uint64_t *out) { uint64_t p64 = p; uint8_t alpha = p; out [0] = ((p64 & 0xff000000) << 8) | ((p64 & 0x00ff0000) >> 16); out [1] = ((p64 & 0x0000ff00) << 24); from_srgb_pixel_xxxa_128bpp (out); premul_ul_to_p16l_128bpp (out, alpha); out [1] = (out [1] & 0xffffffff00000000ULL) | ((uint16_t) alpha << 8) | alpha; } SMOL_REPACK_ROW_DEF (1234, 32, 32, UNASSOCIATED, COMPRESSED, 1234, 128, 64, PREMUL16, LINEAR) { while (dest_row != dest_row_max) { unpack_pixel_123a_u_to_123a_p16l_128bpp (*(src_row++), dest_row); dest_row += 2; } } SMOL_REPACK_ROW_DEF_END /* ---------------------- * * Repacking: 64 -> 24/32 * * ---------------------- */ static SMOL_INLINE uint32_t pack_pixel_1234_p8_to_1324_p8_64bpp (uint64_t in) { return in | (in >> 24); } SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 132, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p >> 24; *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 132, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p >> 24; *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 231, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; *(dest_row++) = p >> 24; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 231, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; *(dest_row++) = p >> 24; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 324, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; *(dest_row++) = p; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 324, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row >> 24; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p >> 16; *(dest_row++) = p >> 8; *(dest_row++) = p; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 423, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); *(dest_row++) = p; *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 423, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row >> 24; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; uint32_t p = pack_pixel_1234_p8_to_1324_p8_64bpp (t); *(dest_row++) = p; *(dest_row++) = p >> 8; *(dest_row++) = p >> 16; src_row++; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 1324, 32, 32, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = pack_pixel_1234_p8_to_1324_p8_64bpp (*(src_row++)); } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, 1324, 32, 32, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint8_t alpha = *src_row; uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; *(dest_row++) = pack_pixel_1234_p8_to_1324_p8_64bpp (t); src_row++; } } SMOL_REPACK_ROW_DEF_END #define DEF_REPACK_FROM_1234_64BPP_TO_32BPP(a, b, c, d) \ SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, PREMUL8, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ *(dest_row++) = PACK_FROM_1234_64BPP (*src_row, a, b, c, d); \ src_row++; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 64, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint8_t alpha = *src_row; \ uint64_t t = (unpremul_p8_to_u_64bpp (*src_row, alpha) & 0xffffffffffffff00ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_64BPP (t, a, b, c, d); \ src_row++; \ } \ } SMOL_REPACK_ROW_DEF_END DEF_REPACK_FROM_1234_64BPP_TO_32BPP (1, 4, 2, 3) DEF_REPACK_FROM_1234_64BPP_TO_32BPP (2, 3, 1, 4) DEF_REPACK_FROM_1234_64BPP_TO_32BPP (4, 1, 3, 2) DEF_REPACK_FROM_1234_64BPP_TO_32BPP (4, 2, 3, 1) /* ----------------------- * * Repacking: 128 -> 24/32 * * ----------------------- */ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 123, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = *src_row >> 32; *(dest_row++) = *(src_row++); *(dest_row++) = *(src_row++) >> 32; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, LINEAR, 123, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = get_alpha_from_linear_xxxa_128bpp (src_row); unpremul_p8l_to_ul_128bpp (src_row, t, alpha); to_srgb_pixel_xxxa_128bpp (src_row, t); *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 123, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1]; unpremul_p8_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, LINEAR, 123, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = get_alpha_from_linear_xxxa_128bpp (src_row); unpremul_p8l_to_ul_128bpp (src_row, t, alpha); to_srgb_pixel_xxxa_128bpp (t, t); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, COMPRESSED, 123, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1] >> 8; unpremul_p16_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } \ } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, LINEAR, 123, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1] >> 8; unpremul_p16_to_u_128bpp (src_row, t, alpha); to_srgb_pixel_xxxa_128bpp (t, t); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [0] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [1] >> 32; src_row += 2; } \ } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 321, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { *(dest_row++) = src_row [1] >> 32; *(dest_row++) = src_row [0]; *(dest_row++) = src_row [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, LINEAR, 321, 24, 8, PREMUL8, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = get_alpha_from_linear_xxxa_128bpp (src_row); unpremul_p8l_to_ul_128bpp (src_row, t, alpha); to_srgb_pixel_xxxa_128bpp (t, t); *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, 321, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1]; unpremul_p8_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, LINEAR, 321, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = get_alpha_from_linear_xxxa_128bpp (src_row); unpremul_p8l_to_ul_128bpp (src_row, t, alpha); to_srgb_pixel_xxxa_128bpp (t, t); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, COMPRESSED, 321, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1] >> 8; unpremul_p16_to_u_128bpp (src_row, t, alpha); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, LINEAR, 321, 24, 8, UNASSOCIATED, COMPRESSED) { while (dest_row != dest_row_max) { uint64_t t [2]; uint8_t alpha = src_row [1] >> 8; unpremul_p16_to_u_128bpp (src_row, t, alpha); to_srgb_pixel_xxxa_128bpp (t, t); t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; *(dest_row++) = t [1] >> 32; *(dest_row++) = t [0]; *(dest_row++) = t [0] >> 32; src_row += 2; } } SMOL_REPACK_ROW_DEF_END #define DEF_REPACK_FROM_1234_128BPP_TO_32BPP(a, b, c, d) \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, PREMUL8, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ *(dest_row++) = PACK_FROM_1234_128BPP (src_row, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, LINEAR, \ a##b##c##d, 32, 32, PREMUL8, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = get_alpha_from_linear_xxxa_128bpp (src_row); \ to_srgb_pixel_xxxa_128bpp (src_row, t); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, COMPRESSED, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = src_row [1]; \ unpremul_p8_to_u_128bpp (src_row, t, alpha); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL8, LINEAR, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = get_alpha_from_linear_xxxa_128bpp (src_row); \ unpremul_p8l_to_ul_128bpp (src_row, t, alpha); \ to_srgb_pixel_xxxa_128bpp (t, t); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, COMPRESSED, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = src_row [1] >> 8; \ unpremul_p16_to_u_128bpp (src_row, t, alpha); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END \ SMOL_REPACK_ROW_DEF (1234, 128, 64, PREMUL16, LINEAR, \ a##b##c##d, 32, 32, UNASSOCIATED, COMPRESSED) { \ while (dest_row != dest_row_max) \ { \ uint64_t t [2]; \ uint8_t alpha = src_row [1] >> 8; \ unpremul_p16l_to_ul_128bpp (src_row, t, alpha); \ to_srgb_pixel_xxxa_128bpp (t, t); \ t [1] = (t [1] & 0xffffffff00000000ULL) | alpha; \ *(dest_row++) = PACK_FROM_1234_128BPP (t, a, b, c, d); \ src_row += 2; \ } \ } SMOL_REPACK_ROW_DEF_END DEF_REPACK_FROM_1234_128BPP_TO_32BPP (1, 2, 3, 4) DEF_REPACK_FROM_1234_128BPP_TO_32BPP (3, 2, 1, 4) DEF_REPACK_FROM_1234_128BPP_TO_32BPP (4, 1, 2, 3) DEF_REPACK_FROM_1234_128BPP_TO_32BPP (4, 3, 2, 1) /* -------------- * * Filter helpers * * -------------- */ static SMOL_INLINE const char * src_row_ofs_to_pointer (const SmolScaleCtx *scale_ctx, uint32_t src_row_ofs) { return scale_ctx->src_pixels + scale_ctx->src_rowstride * src_row_ofs; } static SMOL_INLINE uint64_t weight_pixel_64bpp (uint64_t p, uint16_t w) { return ((p * w) >> 8) & 0x00ff00ff00ff00ffULL; } /* p and out may be the same address */ static SMOL_INLINE void weight_pixel_128bpp (const uint64_t *p, uint64_t *out, uint16_t w) { out [0] = ((p [0] * w) >> 8) & 0x00ffffff00ffffffULL; out [1] = ((p [1] * w) >> 8) & 0x00ffffff00ffffffULL; } static SMOL_INLINE void sum_parts_64bpp (const uint64_t * SMOL_RESTRICT *parts_in, uint64_t * SMOL_RESTRICT accum, uint32_t n) { const uint64_t * SMOL_RESTRICT pp = *parts_in; const uint64_t *pp_end; SMOL_ASSUME_ALIGNED_TO (pp, const uint64_t *, sizeof (uint64_t)); for (pp_end = pp + n; pp < pp_end; pp++) { *accum += *pp; } *parts_in = pp; } static SMOL_INLINE void sum_parts_128bpp (const uint64_t * SMOL_RESTRICT *parts_in, uint64_t * SMOL_RESTRICT accum, uint32_t n) { const uint64_t * SMOL_RESTRICT pp = *parts_in; const uint64_t *pp_end; SMOL_ASSUME_ALIGNED_TO (pp, const uint64_t *, sizeof (uint64_t) * 2); for (pp_end = pp + n * 2; pp < pp_end; ) { accum [0] += *(pp++); accum [1] += *(pp++); } *parts_in = pp; } static SMOL_INLINE uint64_t scale_64bpp (uint64_t accum, uint64_t multiplier) { uint64_t a, b; a = ((accum & 0x0000ffff0000ffffULL) * multiplier + (SMOL_BOXES_MULTIPLIER / 2) + ((SMOL_BOXES_MULTIPLIER / 2) << 32)) / SMOL_BOXES_MULTIPLIER; b = (((accum & 0xffff0000ffff0000ULL) >> 16) * multiplier + (SMOL_BOXES_MULTIPLIER / 2) + ((SMOL_BOXES_MULTIPLIER / 2) << 32)) / SMOL_BOXES_MULTIPLIER; return (a & 0x000000ff000000ffULL) | ((b & 0x000000ff000000ffULL) << 16); } static SMOL_INLINE uint64_t scale_128bpp_half (uint64_t accum, uint64_t multiplier) { uint64_t a, b; a = accum & 0x00000000ffffffffULL; a = (a * multiplier + SMOL_BOXES_MULTIPLIER / 2) / SMOL_BOXES_MULTIPLIER; b = (accum & 0xffffffff00000000ULL) >> 32; b = (b * multiplier + SMOL_BOXES_MULTIPLIER / 2) / SMOL_BOXES_MULTIPLIER; return a | (b << 32); } static SMOL_INLINE void scale_and_store_128bpp (const uint64_t * SMOL_RESTRICT accum, uint64_t multiplier, uint64_t * SMOL_RESTRICT *dest_row_parts) { *(*dest_row_parts)++ = scale_128bpp_half (accum [0], multiplier); *(*dest_row_parts)++ = scale_128bpp_half (accum [1], multiplier); } static void add_parts (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n) { const uint64_t *parts_in_max = parts_in + n; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) *(parts_acc_out++) += *(parts_in++); } static void copy_weighted_parts_64bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { *(parts_acc_out++) = weight_pixel_64bpp (*(parts_in++), w); } } static void copy_weighted_parts_128bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n * 2; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { weight_pixel_128bpp (parts_in, parts_acc_out, w); parts_in += 2; parts_acc_out += 2; } } static void add_weighted_parts_64bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { *(parts_acc_out++) += weight_pixel_64bpp (*(parts_in++), w); } } static void add_weighted_parts_128bpp (const uint64_t * SMOL_RESTRICT parts_in, uint64_t * SMOL_RESTRICT parts_acc_out, uint32_t n, uint16_t w) { const uint64_t *parts_in_max = parts_in + n * 2; SMOL_ASSUME_ALIGNED (parts_in, const uint64_t *); SMOL_ASSUME_ALIGNED (parts_acc_out, uint64_t *); while (parts_in < parts_in_max) { uint64_t t [2]; weight_pixel_128bpp (parts_in, t, w); parts_acc_out [0] += t [0]; parts_acc_out [1] += t [1]; parts_in += 2; parts_acc_out += 2; } } static SMOL_INLINE void apply_subpixel_opacity_64bpp (uint64_t * SMOL_RESTRICT u64_inout, uint16_t opacity) { *u64_inout = ((*u64_inout * opacity) >> SMOL_SUBPIXEL_SHIFT) & 0x00ff00ff00ff00ffULL; } static SMOL_INLINE void apply_subpixel_opacity_128bpp_half (uint64_t * SMOL_RESTRICT u64_inout, uint16_t opacity) { *u64_inout = ((*u64_inout * opacity) >> SMOL_SUBPIXEL_SHIFT) & 0x00ffffff00ffffffULL; } static SMOL_INLINE void apply_subpixel_opacity_128bpp (uint64_t *u64_inout, uint16_t opacity) { apply_subpixel_opacity_128bpp_half (u64_inout, opacity); apply_subpixel_opacity_128bpp_half (u64_inout + 1, opacity); } static void apply_subpixel_opacity_row_copy_64bpp (uint64_t * SMOL_RESTRICT u64_in, uint64_t * SMOL_RESTRICT u64_out, int n_pixels, uint16_t opacity) { uint64_t *u64_out_max = u64_out + n_pixels; while (u64_out != u64_out_max) { *u64_out = *u64_in++; apply_subpixel_opacity_64bpp (u64_out, opacity); u64_out++; } } static void apply_subpixel_opacity_row_copy_128bpp (uint64_t * SMOL_RESTRICT u64_in, uint64_t * SMOL_RESTRICT u64_out, int n_pixels, uint16_t opacity) { uint64_t *u64_out_max = u64_out + (n_pixels * 2); while (u64_out != u64_out_max) { u64_out [0] = u64_in [0]; u64_out [1] = u64_in [1]; apply_subpixel_opacity_128bpp_half (u64_out, opacity); apply_subpixel_opacity_128bpp_half (u64_out + 1, opacity); u64_in += 2; u64_out += 2; } } static void apply_horiz_edge_opacity (const SmolScaleCtx *scale_ctx, uint64_t *row_parts) { if (scale_ctx->storage_type == SMOL_STORAGE_64BPP) { apply_subpixel_opacity_64bpp (&row_parts [0], scale_ctx->hdim.first_opacity); apply_subpixel_opacity_64bpp (&row_parts [scale_ctx->hdim.placement_size_px - 1], scale_ctx->hdim.last_opacity); } else { apply_subpixel_opacity_128bpp (&row_parts [0], scale_ctx->hdim.first_opacity); apply_subpixel_opacity_128bpp (&row_parts [(scale_ctx->hdim.placement_size_px - 1) * 2], scale_ctx->hdim.last_opacity); } } /* ------------------ * * Horizontal scaling * * ------------------ */ #define DEF_INTERP_HORIZONTAL_BILINEAR(n_halvings) \ static void \ interp_horizontal_bilinear_##n_halvings##h_64bpp (const SmolScaleCtx *scale_ctx, \ const uint64_t * SMOL_RESTRICT src_row_parts, \ uint64_t * SMOL_RESTRICT dest_row_parts) \ { \ const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; \ uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px; \ uint64_t p, q; \ uint64_t F; \ int i; \ \ SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); \ \ do \ { \ uint64_t accum = 0; \ \ for (i = 0; i < (1 << (n_halvings)); i++) \ { \ uint64_t pixel_ofs = *(precalc_x++); \ F = *(precalc_x++); \ \ p = src_row_parts [pixel_ofs]; \ q = src_row_parts [pixel_ofs + 1]; \ \ accum += ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; \ } \ *(dest_row_parts++) = ((accum) >> (n_halvings)) & 0x00ff00ff00ff00ffULL; \ } \ while (dest_row_parts != dest_row_parts_max); \ } \ \ static void \ interp_horizontal_bilinear_##n_halvings##h_128bpp (const SmolScaleCtx *scale_ctx, \ const uint64_t * SMOL_RESTRICT src_row_parts, \ uint64_t * SMOL_RESTRICT dest_row_parts) \ { \ const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; \ uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px * 2; \ uint64_t p, q; \ uint64_t F; \ int i; \ \ SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); \ \ do \ { \ uint64_t accum [2] = { 0 }; \ \ for (i = 0; i < (1 << (n_halvings)); i++) \ { \ uint32_t pixel_ofs = *(precalc_x++) * 2; \ F = *(precalc_x++); \ \ p = src_row_parts [pixel_ofs]; \ q = src_row_parts [pixel_ofs + 2]; \ \ accum [0] += ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; \ \ p = src_row_parts [pixel_ofs + 1]; \ q = src_row_parts [pixel_ofs + 3]; \ \ accum [1] += ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; \ } \ *(dest_row_parts++) = ((accum [0]) >> (n_halvings)) & 0x00ffffff00ffffffULL; \ *(dest_row_parts++) = ((accum [1]) >> (n_halvings)) & 0x00ffffff00ffffffULL; \ } \ while (dest_row_parts != dest_row_parts_max); \ } static void interp_horizontal_bilinear_0h_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px; uint64_t p, q; uint64_t F; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); do { uint32_t pixel_ofs = *(precalc_x++); F = *(precalc_x++); p = src_row_parts [pixel_ofs]; q = src_row_parts [pixel_ofs + 1]; *(dest_row_parts++) = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; } while (dest_row_parts != dest_row_parts_max); } static void interp_horizontal_bilinear_0h_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { const uint16_t * SMOL_RESTRICT precalc_x = scale_ctx->hdim.precalc; uint64_t * SMOL_RESTRICT dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px * 2; uint64_t p, q; uint64_t F; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); do { uint32_t pixel_ofs = *(precalc_x++) * 2; F = *(precalc_x++); p = src_row_parts [pixel_ofs]; q = src_row_parts [pixel_ofs + 2]; *(dest_row_parts++) = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; p = src_row_parts [pixel_ofs + 1]; q = src_row_parts [pixel_ofs + 3]; *(dest_row_parts++) = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; } while (dest_row_parts != dest_row_parts_max); } DEF_INTERP_HORIZONTAL_BILINEAR(1) DEF_INTERP_HORIZONTAL_BILINEAR(2) DEF_INTERP_HORIZONTAL_BILINEAR(3) DEF_INTERP_HORIZONTAL_BILINEAR(4) DEF_INTERP_HORIZONTAL_BILINEAR(5) DEF_INTERP_HORIZONTAL_BILINEAR(6) static SMOL_INLINE void unpack_box_precalc (const uint32_t precalc, uint32_t step, uint32_t *ofs0, uint32_t *ofs1, uint32_t *f0, uint32_t *f1, uint32_t *n) { *ofs0 = precalc; *ofs1 = *ofs0 + step; *f0 = 256 - (*ofs0 % SMOL_SUBPIXEL_MUL); *f1 = *ofs1 % SMOL_SUBPIXEL_MUL; *ofs0 /= SMOL_SUBPIXEL_MUL; *ofs1 /= SMOL_SUBPIXEL_MUL; *n = *ofs1 - *ofs0 - 1; } static void interp_horizontal_boxes_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t *src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { const uint64_t * SMOL_RESTRICT pp; const uint32_t *precalc_x = scale_ctx->hdim.precalc; uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px; uint64_t accum; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); while (dest_row_parts < dest_row_parts_max) { uint32_t ofs0, ofs1; uint32_t f0, f1; uint32_t n; unpack_box_precalc (*(precalc_x++), scale_ctx->hdim.span_step, &ofs0, &ofs1, &f0, &f1, &n); pp = src_row_parts + ofs0; accum = weight_pixel_64bpp (*(pp++), f0); sum_parts_64bpp (&pp, &accum, n); accum += weight_pixel_64bpp (*pp, f1); *(dest_row_parts++) = scale_64bpp (accum, scale_ctx->hdim.span_mul); } } static void interp_horizontal_boxes_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t *src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { const uint64_t * SMOL_RESTRICT pp; const uint32_t *precalc_x = scale_ctx->hdim.precalc; uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px * 2; uint64_t accum [2]; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); while (dest_row_parts < dest_row_parts_max) { uint32_t ofs0, ofs1; uint32_t f0, f1; uint32_t n; uint64_t t [2]; unpack_box_precalc (*(precalc_x++), scale_ctx->hdim.span_step, &ofs0, &ofs1, &f0, &f1, &n); pp = src_row_parts + (ofs0 * 2); weight_pixel_128bpp (pp, accum, f0); pp += 2; sum_parts_128bpp ((const uint64_t * SMOL_RESTRICT *) &pp, accum, n); weight_pixel_128bpp (pp, t, f1); accum [0] += t [0]; accum [1] += t [1]; scale_and_store_128bpp (accum, scale_ctx->hdim.span_mul, (uint64_t * SMOL_RESTRICT *) &dest_row_parts); } } static void interp_horizontal_one_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px; uint64_t part; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); part = *src_row_parts; while (dest_row_parts != dest_row_parts_max) *(dest_row_parts++) = part; } static void interp_horizontal_one_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { uint64_t *dest_row_parts_max = dest_row_parts + scale_ctx->hdim.placement_size_px * 2; SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); while (dest_row_parts != dest_row_parts_max) { *(dest_row_parts++) = src_row_parts [0]; *(dest_row_parts++) = src_row_parts [1]; } } static void interp_horizontal_copy_64bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); memcpy (dest_row_parts, src_row_parts, scale_ctx->hdim.placement_size_px * sizeof (uint64_t)); } static void interp_horizontal_copy_128bpp (const SmolScaleCtx *scale_ctx, const uint64_t * SMOL_RESTRICT src_row_parts, uint64_t * SMOL_RESTRICT dest_row_parts) { SMOL_ASSUME_ALIGNED (src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_row_parts, uint64_t *); memcpy (dest_row_parts, src_row_parts, scale_ctx->hdim.placement_size_px * 2 * sizeof (uint64_t)); } static void scale_horizontal (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, const char *src_row, uint64_t *dest_row_parts) { uint64_t * SMOL_RESTRICT src_row_unpacked; src_row_unpacked = local_ctx->parts_row [3]; /* 32-bit unpackers need 32-bit alignment */ if ((((uintptr_t) src_row) & 3) && scale_ctx->src_pixel_type != SMOL_PIXEL_RGB8 && scale_ctx->src_pixel_type != SMOL_PIXEL_BGR8) { if (!local_ctx->src_aligned) local_ctx->src_aligned = smol_alloc_aligned (scale_ctx->hdim.src_size_px * sizeof (uint32_t), &local_ctx->src_aligned_storage); memcpy (local_ctx->src_aligned, src_row, scale_ctx->hdim.src_size_px * sizeof (uint32_t)); src_row = (const char *) local_ctx->src_aligned; } scale_ctx->src_unpack_row_func (src_row, src_row_unpacked, scale_ctx->hdim.src_size_px); scale_ctx->hfilter_func (scale_ctx, src_row_unpacked, dest_row_parts); apply_horiz_edge_opacity (scale_ctx, dest_row_parts); } /* ---------------- * * Vertical scaling * * ---------------- */ static void update_local_ctx_bilinear (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; uint32_t new_src_ofs = precalc_y [dest_row_index * 2]; if (new_src_ofs == local_ctx->src_ofs) return; if (new_src_ofs == local_ctx->src_ofs + 1) { uint64_t *t = local_ctx->parts_row [0]; local_ctx->parts_row [0] = local_ctx->parts_row [1]; local_ctx->parts_row [1] = t; scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, new_src_ofs + 1), local_ctx->parts_row [1]); } else { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, new_src_ofs), local_ctx->parts_row [0]); scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, new_src_ofs + 1), local_ctx->parts_row [1]); } local_ctx->src_ofs = new_src_ofs; } static void interp_vertical_bilinear_store_64bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT dest_parts, uint32_t width) { uint64_t *parts_dest_last = dest_parts + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *(dest_parts++) = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; } while (dest_parts != parts_dest_last); } static void interp_vertical_bilinear_store_with_opacity_64bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT dest_parts, uint32_t width, uint16_t opacity) { uint64_t *parts_dest_last = dest_parts + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *dest_parts = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; apply_subpixel_opacity_64bpp (dest_parts, opacity); dest_parts++; } while (dest_parts != parts_dest_last); } static void interp_vertical_bilinear_add_64bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT accum_out, uint32_t width) { uint64_t *accum_dest_last = accum_out + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (accum_out, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *(accum_out++) += ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; } while (accum_out != accum_dest_last); } static void interp_vertical_bilinear_store_128bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT dest_parts, uint32_t width) { uint64_t *parts_dest_last = dest_parts + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *(dest_parts++) = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; } while (dest_parts != parts_dest_last); } static void interp_vertical_bilinear_store_with_opacity_128bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT dest_parts, uint32_t width, uint16_t opacity) { uint64_t *parts_dest_last = dest_parts + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *dest_parts = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; apply_subpixel_opacity_128bpp_half (dest_parts, opacity); dest_parts++; } while (dest_parts != parts_dest_last); } static void interp_vertical_bilinear_add_128bpp (uint64_t F, const uint64_t * SMOL_RESTRICT top_src_row_parts, const uint64_t * SMOL_RESTRICT bottom_src_row_parts, uint64_t * SMOL_RESTRICT accum_out, uint32_t width) { uint64_t *accum_dest_last = accum_out + width; SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); SMOL_ASSUME_ALIGNED (accum_out, uint64_t *); do { uint64_t p, q; p = *(top_src_row_parts++); q = *(bottom_src_row_parts++); *(accum_out++) += ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; } while (accum_out != accum_dest_last); } #define DEF_INTERP_VERTICAL_BILINEAR_FINAL(n_halvings) \ static void \ interp_vertical_bilinear_final_##n_halvings##h_64bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ff00ff00ff00ffULL; \ \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } \ \ static void \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_64bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width, \ uint16_t opacity) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ff00ff00ff00ffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ff00ff00ff00ffULL; \ \ apply_subpixel_opacity_64bpp (&p, opacity); \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } \ \ static void \ interp_vertical_bilinear_final_##n_halvings##h_128bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ffffff00ffffffULL; \ \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } \ \ static void \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_128bpp (uint64_t F, \ const uint64_t * SMOL_RESTRICT top_src_row_parts, \ const uint64_t * SMOL_RESTRICT bottom_src_row_parts, \ uint64_t * SMOL_RESTRICT accum_inout, \ uint32_t width, \ uint16_t opacity) \ { \ uint64_t *accum_inout_last = accum_inout + width; \ \ SMOL_ASSUME_ALIGNED (top_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (bottom_src_row_parts, const uint64_t *); \ SMOL_ASSUME_ALIGNED (accum_inout, uint64_t *); \ \ do \ { \ uint64_t p, q; \ \ p = *(top_src_row_parts++); \ q = *(bottom_src_row_parts++); \ \ p = ((((p - q) * F) >> 8) + q) & 0x00ffffff00ffffffULL; \ p = ((p + *accum_inout) >> n_halvings) & 0x00ffffff00ffffffULL; \ \ apply_subpixel_opacity_128bpp_half (&p, opacity); \ *(accum_inout++) = p; \ } \ while (accum_inout != accum_inout_last); \ } #define DEF_SCALE_DEST_ROW_BILINEAR(n_halvings) \ static int \ scale_dest_row_bilinear_##n_halvings##h_64bpp (const SmolScaleCtx *scale_ctx, \ SmolLocalCtx *local_ctx, \ uint32_t dest_row_index) \ { \ uint16_t *precalc_y = scale_ctx->vdim.precalc; \ uint32_t bilin_index = dest_row_index << (n_halvings); \ unsigned int i; \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_store_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px); \ bilin_index++; \ \ for (i = 0; i < (1 << (n_halvings)) - 2; i++) \ { \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_add_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px); \ bilin_index++; \ } \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ \ if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px, \ scale_ctx->vdim.first_opacity); \ else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px, \ scale_ctx->vdim.last_opacity); \ else \ interp_vertical_bilinear_final_##n_halvings##h_64bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px); \ \ return 2; \ } \ \ static int \ scale_dest_row_bilinear_##n_halvings##h_128bpp (const SmolScaleCtx *scale_ctx, \ SmolLocalCtx *local_ctx, \ uint32_t dest_row_index) \ { \ uint16_t *precalc_y = scale_ctx->vdim.precalc; \ uint32_t bilin_index = dest_row_index << (n_halvings); \ unsigned int i; \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_store_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2); \ bilin_index++; \ \ for (i = 0; i < (1 << (n_halvings)) - 2; i++) \ { \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ interp_vertical_bilinear_add_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2); \ bilin_index++; \ } \ \ update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); \ \ if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2, \ scale_ctx->vdim.first_opacity); \ else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) \ interp_vertical_bilinear_final_##n_halvings##h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2, \ scale_ctx->vdim.last_opacity); \ else \ interp_vertical_bilinear_final_##n_halvings##h_128bpp (precalc_y [bilin_index * 2 + 1], \ local_ctx->parts_row [0], \ local_ctx->parts_row [1], \ local_ctx->parts_row [2], \ scale_ctx->hdim.placement_size_px * 2); \ \ return 2; \ } static int scale_dest_row_bilinear_0h_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; update_local_ctx_bilinear (scale_ctx, local_ctx, dest_row_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_store_with_opacity_64bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_store_with_opacity_64bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_store_64bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px); return 2; } static int scale_dest_row_bilinear_0h_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; update_local_ctx_bilinear (scale_ctx, local_ctx, dest_row_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_store_with_opacity_128bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_store_with_opacity_128bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_store_128bpp (precalc_y [dest_row_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2); return 2; } DEF_INTERP_VERTICAL_BILINEAR_FINAL(1) static int scale_dest_row_bilinear_1h_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; uint32_t bilin_index = dest_row_index << 1; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); interp_vertical_bilinear_store_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px); bilin_index++; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_final_1h_64bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px); return 2; } static int scale_dest_row_bilinear_1h_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint16_t *precalc_y = scale_ctx->vdim.precalc; uint32_t bilin_index = dest_row_index << 1; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); interp_vertical_bilinear_store_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2); bilin_index++; update_local_ctx_bilinear (scale_ctx, local_ctx, bilin_index); if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.first_opacity); else if (dest_row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) interp_vertical_bilinear_final_1h_with_opacity_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2, scale_ctx->vdim.last_opacity); else interp_vertical_bilinear_final_1h_128bpp (precalc_y [bilin_index * 2 + 1], local_ctx->parts_row [0], local_ctx->parts_row [1], local_ctx->parts_row [2], scale_ctx->hdim.placement_size_px * 2); return 2; } DEF_INTERP_VERTICAL_BILINEAR_FINAL(2) DEF_SCALE_DEST_ROW_BILINEAR(2) DEF_INTERP_VERTICAL_BILINEAR_FINAL(3) DEF_SCALE_DEST_ROW_BILINEAR(3) DEF_INTERP_VERTICAL_BILINEAR_FINAL(4) DEF_SCALE_DEST_ROW_BILINEAR(4) DEF_INTERP_VERTICAL_BILINEAR_FINAL(5) DEF_SCALE_DEST_ROW_BILINEAR(5) DEF_INTERP_VERTICAL_BILINEAR_FINAL(6) DEF_SCALE_DEST_ROW_BILINEAR(6) static void finalize_vertical_64bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n) { uint64_t *parts_dest_max = dest_parts + n; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { *(dest_parts++) = scale_64bpp (*(accums++), multiplier); } } static void finalize_vertical_with_opacity_64bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n, uint16_t opacity) { uint64_t *parts_dest_max = dest_parts + n; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { *dest_parts = scale_64bpp (*(accums++), multiplier); apply_subpixel_opacity_64bpp (dest_parts, opacity); dest_parts++; } } static int scale_dest_row_box_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint32_t *precalc_y = scale_ctx->vdim.precalc; uint32_t ofs_y, ofs_y_max; uint32_t w1, w2; uint32_t n, i; unpack_box_precalc (precalc_y [dest_row_index], scale_ctx->vdim.span_step, &ofs_y, &ofs_y_max, &w1, &w2, &n); /* First input row */ scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); copy_weighted_parts_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w1); ofs_y++; /* Add up whole input rows */ for (i = 0; i < n; i++) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_parts (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px); ofs_y++; } /* Last input row */ if (ofs_y < scale_ctx->vdim.src_size_px) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_weighted_parts_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w2); } /* Finalize */ if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) { finalize_vertical_with_opacity_64bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (dest_row_index == scale_ctx->vdim.placement_size_px - 1 && scale_ctx->vdim.last_opacity < 256) { finalize_vertical_with_opacity_64bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { finalize_vertical_64bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px); } return 0; } static void finalize_vertical_128bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n) { uint64_t *parts_dest_max = dest_parts + n * 2; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { *(dest_parts++) = scale_128bpp_half (*(accums++), multiplier); *(dest_parts++) = scale_128bpp_half (*(accums++), multiplier); } } static void finalize_vertical_with_opacity_128bpp (const uint64_t * SMOL_RESTRICT accums, uint64_t multiplier, uint64_t * SMOL_RESTRICT dest_parts, uint32_t n, uint16_t opacity) { uint64_t *parts_dest_max = dest_parts + n * 2; SMOL_ASSUME_ALIGNED (accums, const uint64_t *); SMOL_ASSUME_ALIGNED (dest_parts, uint64_t *); while (dest_parts != parts_dest_max) { dest_parts [0] = scale_128bpp_half (*(accums++), multiplier); dest_parts [1] = scale_128bpp_half (*(accums++), multiplier); apply_subpixel_opacity_128bpp (dest_parts, opacity); dest_parts += 2; } } static int scale_dest_row_box_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index) { uint32_t *precalc_y = scale_ctx->vdim.precalc; uint32_t ofs_y, ofs_y_max; uint32_t w1, w2; uint32_t n, i; unpack_box_precalc (precalc_y [dest_row_index], scale_ctx->vdim.span_step, &ofs_y, &ofs_y_max, &w1, &w2, &n); /* First input row */ scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); copy_weighted_parts_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w1); ofs_y++; /* Add up whole input rows */ for (i = 0; i < n; i++) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_parts (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px * 2); ofs_y++; } /* Last input row */ if (ofs_y < scale_ctx->vdim.src_size_px) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, ofs_y), local_ctx->parts_row [0]); add_weighted_parts_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, w2); } if (dest_row_index == 0 && scale_ctx->vdim.first_opacity < 256) { finalize_vertical_with_opacity_128bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (dest_row_index == scale_ctx->vdim.placement_size_px - 1 && scale_ctx->vdim.last_opacity < 256) { finalize_vertical_with_opacity_128bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { finalize_vertical_128bpp (local_ctx->parts_row [1], scale_ctx->vdim.span_mul, local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px); } return 0; } static int scale_dest_row_one_64bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t row_index) { /* Scale the row and store it */ if (local_ctx->src_ofs != 0) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, 0), local_ctx->parts_row [0]); local_ctx->src_ofs = 0; } if (row_index == 0 && scale_ctx->vdim.first_opacity < 256) { apply_subpixel_opacity_row_copy_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) { apply_subpixel_opacity_row_copy_64bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { memcpy (local_ctx->parts_row [1], local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px * sizeof (uint64_t)); } return 1; } static int scale_dest_row_one_128bpp (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t row_index) { /* Scale the row and store it */ if (local_ctx->src_ofs != 0) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, 0), local_ctx->parts_row [0]); local_ctx->src_ofs = 0; } if (row_index == 0 && scale_ctx->vdim.first_opacity < 256) { apply_subpixel_opacity_row_copy_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.first_opacity); } else if (row_index == (scale_ctx->vdim.placement_size_px - 1) && scale_ctx->vdim.last_opacity < 256) { apply_subpixel_opacity_row_copy_128bpp (local_ctx->parts_row [0], local_ctx->parts_row [1], scale_ctx->hdim.placement_size_px, scale_ctx->vdim.last_opacity); } else { memcpy (local_ctx->parts_row [1], local_ctx->parts_row [0], scale_ctx->hdim.placement_size_px * sizeof (uint64_t) * 2); } return 1; } static int scale_dest_row_copy (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t row_index) { scale_horizontal (scale_ctx, local_ctx, src_row_ofs_to_pointer (scale_ctx, row_index), local_ctx->parts_row [0]); return 0; } /* ----------- * * Compositing * * ----------- */ static void composite_over_color_p8_64bpp (uint64_t * SMOL_RESTRICT srcdest_row, const uint64_t * SMOL_RESTRICT color_pixel, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (srcdest_row, uint64_t *, sizeof (uint64_t)); SMOL_ASSUME_ALIGNED_TO (color_pixel, const uint64_t *, sizeof (uint64_t)); for (i = 0; i < n_pixels; i++) { uint64_t a = srcdest_row [i] & 0xff; srcdest_row [i] += (((*color_pixel) * (0xff - a)) >> 8) & 0x00ff00ff00ff00ff; } } static void composite_over_color_p8l_64bpp (uint64_t * SMOL_RESTRICT srcdest_row, const uint64_t * SMOL_RESTRICT color_pixel, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (srcdest_row, uint64_t *, sizeof (uint64_t)); SMOL_ASSUME_ALIGNED_TO (color_pixel, const uint64_t *, sizeof (uint64_t)); for (i = 0; i < n_pixels; i++) { uint64_t a = (srcdest_row [i] >> 3) & 0xff; srcdest_row [i] += (((*color_pixel) * (0xff - a)) >> 8) & 0x00ff00ff00ff00ff; } } static void composite_over_color_p8_128bpp (uint64_t * SMOL_RESTRICT srcdest_row, const uint64_t * SMOL_RESTRICT color_pixel, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (srcdest_row, uint64_t *, sizeof (uint64_t) * 2); SMOL_ASSUME_ALIGNED_TO (color_pixel, const uint64_t *, sizeof (uint64_t)); for (i = 0; i < n_pixels * 2; i += 2) { uint64_t a = srcdest_row [i + 1] & 0xff; srcdest_row [i] += ((color_pixel [0] * (0xff - a)) >> 8) & 0x00ffffff00ffffff; srcdest_row [i + 1] += ((color_pixel [1] * (0xff - a)) >> 8) & 0x00ffffff00ffffff; } } static void composite_over_color_p8l_128bpp (uint64_t * SMOL_RESTRICT srcdest_row, const uint64_t * SMOL_RESTRICT color_pixel, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (srcdest_row, uint64_t *, sizeof (uint64_t) * 2); SMOL_ASSUME_ALIGNED_TO (color_pixel, const uint64_t *, sizeof (uint64_t)); for (i = 0; i < n_pixels * 2; i += 2) { uint64_t a = (srcdest_row [i + 1] >> 3) & 0xff; srcdest_row [i] += ((color_pixel [0] * (0xff - a)) >> 8) & 0x00ffffff00ffffff; srcdest_row [i + 1] += ((color_pixel [1] * (0xff - a)) >> 8) & 0x00ffffff00ffffff; } } static void composite_over_color_p16_128bpp (uint64_t * SMOL_RESTRICT srcdest_row, const uint64_t * SMOL_RESTRICT color_pixel, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (srcdest_row, uint64_t *, sizeof (uint64_t) * 2); SMOL_ASSUME_ALIGNED_TO (color_pixel, const uint64_t *, sizeof (uint64_t)); for (i = 0; i < n_pixels * 2; i += 2) { uint64_t a = (srcdest_row [i + 1] >> 8) & 0xff; srcdest_row [i] += ((color_pixel [0] * (0xff - a)) >> 8) & 0x00ffffff00ffffff; srcdest_row [i + 1] += ((color_pixel [1] * (0xff - a)) >> 8) & 0x00ffffff00ffffff; } } static void composite_over_dest_64bpp (const uint64_t * SMOL_RESTRICT src_row, uint64_t * SMOL_RESTRICT dest_row, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (src_row, const uint64_t *, sizeof (uint64_t)); SMOL_ASSUME_ALIGNED_TO (dest_row, uint64_t *, sizeof (uint64_t)); for (i = 0; i < n_pixels; i++) { dest_row [i] = ((src_row [i] + dest_row [i]) >> 1) & 0x7fff7fff7fff7fff; } } static void composite_over_dest_128bpp (const uint64_t * SMOL_RESTRICT src_row, uint64_t * SMOL_RESTRICT dest_row, uint32_t n_pixels) { uint32_t i; SMOL_ASSUME_ALIGNED_TO (src_row, const uint64_t *, sizeof (uint64_t) * 2); SMOL_ASSUME_ALIGNED_TO (dest_row, uint64_t *, sizeof (uint64_t) * 2); for (i = 0; i < n_pixels * 2; i += 2) { dest_row [i] = ((src_row [i] + dest_row [i]) >> 1) & 0x7fffffff7fffffff; dest_row [i + 1] = ((src_row [i + 1] + dest_row [i + 1]) >> 1) & 0x7fffffff7fffffff; } } /* -------- * * Clearing * * -------- */ static void clear_24bpp (const void *src_pixel_batch, void *dest_row, uint32_t n_pixels) { const uint8_t *src_pixel_batch_u8 = src_pixel_batch; const uint32_t *src_pixel_batch_u32 = src_pixel_batch; uint8_t *dest_row_u8 = dest_row; uint32_t *dest_row_u32 = dest_row; uint32_t i; SMOL_ASSUME_ALIGNED_TO (src_pixel_batch_u32, const uint32_t *, sizeof (uint32_t)); for (i = 0; n_pixels - i >= 4; i += 4) { *(dest_row_u32++) = src_pixel_batch_u32 [0]; *(dest_row_u32++) = src_pixel_batch_u32 [1]; *(dest_row_u32++) = src_pixel_batch_u32 [2]; } for ( ; i < n_pixels; i++) { dest_row_u8 [i * 3] = src_pixel_batch_u8 [0]; dest_row_u8 [i * 3 + 1] = src_pixel_batch_u8 [1]; dest_row_u8 [i * 3 + 2] = src_pixel_batch_u8 [2]; } } static void clear_32bpp (const void *src_pixel_batch, void *dest_row, uint32_t n_pixels) { const uint32_t *src_pixel_batch_u32 = src_pixel_batch; uint32_t *dest_row_u32 = dest_row; uint32_t i; SMOL_ASSUME_ALIGNED_TO (src_pixel_batch_u32, const uint32_t *, sizeof (uint32_t)); for (i = 0; i < n_pixels; i++) dest_row_u32 [i] = src_pixel_batch_u32 [0]; } /* --------------- * * Function tables * * --------------- */ #define R SMOL_REPACK_META static const SmolRepackMeta repack_meta [] = { R (123, 24, PREMUL8, COMPRESSED, 1324, 64, PREMUL8, COMPRESSED), R (123, 24, PREMUL8, COMPRESSED, 1234, 128, PREMUL8, COMPRESSED), R (123, 24, PREMUL8, COMPRESSED, 1234, 128, PREMUL8, LINEAR), R (1234, 32, PREMUL8, COMPRESSED, 1324, 64, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 2431, 64, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 3241, 64, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 1324, 64, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 2431, 64, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 3241, 64, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 1234, 128, PREMUL8, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 2341, 128, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 1234, 128, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 2341, 128, PREMUL8, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 1234, 128, PREMUL16, COMPRESSED), R (1234, 32, UNASSOCIATED, COMPRESSED, 2341, 128, PREMUL16, COMPRESSED), R (1234, 32, PREMUL8, COMPRESSED, 1234, 128, PREMUL8, LINEAR), R (1234, 32, PREMUL8, COMPRESSED, 2341, 128, PREMUL8, LINEAR), R (1234, 32, UNASSOCIATED, COMPRESSED, 1234, 128, PREMUL8, LINEAR), R (1234, 32, UNASSOCIATED, COMPRESSED, 2341, 128, PREMUL8, LINEAR), R (1234, 32, UNASSOCIATED, COMPRESSED, 1234, 128, PREMUL16, LINEAR), R (1234, 32, UNASSOCIATED, COMPRESSED, 2341, 128, PREMUL16, LINEAR), R (1234, 64, PREMUL8, COMPRESSED, 132, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 231, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 324, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 423, 24, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 132, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 231, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 324, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 423, 24, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1324, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1423, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 2314, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4132, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4231, 32, PREMUL8, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1324, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 1423, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 2314, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4132, 32, UNASSOCIATED, COMPRESSED), R (1234, 64, PREMUL8, COMPRESSED, 4231, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 123, 24, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 321, 24, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 123, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 321, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 123, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 321, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 123, 24, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 321, 24, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 123, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 321, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, LINEAR, 123, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, LINEAR, 321, 24, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 1234, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 3214, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4123, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4321, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 1234, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 3214, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4123, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, COMPRESSED, 4321, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 1234, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 3214, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 4123, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, COMPRESSED, 4321, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 1234, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 3214, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 4123, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 4321, 32, PREMUL8, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 1234, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 3214, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 4123, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL8, LINEAR, 4321, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, LINEAR, 1234, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, LINEAR, 3214, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, LINEAR, 4123, 32, UNASSOCIATED, COMPRESSED), R (1234, 128, PREMUL16, LINEAR, 4321, 32, UNASSOCIATED, COMPRESSED), SMOL_REPACK_META_LAST }; #undef R static const SmolImplementation implementation = { /* Horizontal init */ init_horizontal, /* Vertical init */ init_vertical, { /* Horizontal filters */ { /* 24bpp */ NULL }, { /* 32bpp */ NULL }, { /* 64bpp */ interp_horizontal_copy_64bpp, interp_horizontal_one_64bpp, interp_horizontal_bilinear_0h_64bpp, interp_horizontal_bilinear_1h_64bpp, interp_horizontal_bilinear_2h_64bpp, interp_horizontal_bilinear_3h_64bpp, interp_horizontal_bilinear_4h_64bpp, interp_horizontal_bilinear_5h_64bpp, interp_horizontal_bilinear_6h_64bpp, interp_horizontal_boxes_64bpp }, { /* 128bpp */ interp_horizontal_copy_128bpp, interp_horizontal_one_128bpp, interp_horizontal_bilinear_0h_128bpp, interp_horizontal_bilinear_1h_128bpp, interp_horizontal_bilinear_2h_128bpp, interp_horizontal_bilinear_3h_128bpp, interp_horizontal_bilinear_4h_128bpp, interp_horizontal_bilinear_5h_128bpp, interp_horizontal_bilinear_6h_128bpp, interp_horizontal_boxes_128bpp } }, { /* Vertical filters */ { /* 24bpp */ NULL }, { /* 32bpp */ NULL }, { /* 64bpp */ scale_dest_row_copy, scale_dest_row_one_64bpp, scale_dest_row_bilinear_0h_64bpp, scale_dest_row_bilinear_1h_64bpp, scale_dest_row_bilinear_2h_64bpp, scale_dest_row_bilinear_3h_64bpp, scale_dest_row_bilinear_4h_64bpp, scale_dest_row_bilinear_5h_64bpp, scale_dest_row_bilinear_6h_64bpp, scale_dest_row_box_64bpp }, { /* 128bpp */ scale_dest_row_copy, scale_dest_row_one_128bpp, scale_dest_row_bilinear_0h_128bpp, scale_dest_row_bilinear_1h_128bpp, scale_dest_row_bilinear_2h_128bpp, scale_dest_row_bilinear_3h_128bpp, scale_dest_row_bilinear_4h_128bpp, scale_dest_row_bilinear_5h_128bpp, scale_dest_row_bilinear_6h_128bpp, scale_dest_row_box_128bpp } }, { /* Composite over color */ { { NULL, NULL, NULL }, { NULL, NULL, NULL } }, /* 24bpp - unused */ { { NULL, NULL, NULL }, { NULL, NULL, NULL } }, /* 32bpp - unused */ /* 64bpp */ { /* compressed */ { NULL, /* unassociated - unused */ composite_over_color_p8_64bpp, NULL /* p16 - n/a */ }, /* linear */ { NULL, /* unassociated - unused */ composite_over_color_p8l_64bpp, NULL /* p16 - n/a */ } }, /* 128bpp */ { /* compressed */ { NULL, /* unassociated - unused */ composite_over_color_p8_128bpp, composite_over_color_p16_128bpp }, /* linear */ { NULL, /* unassociated - unused */ composite_over_color_p8l_128bpp, composite_over_color_p16_128bpp } } }, { /* Composite over dest */ NULL, NULL, composite_over_dest_64bpp, composite_over_dest_128bpp }, { /* Clear dest */ clear_24bpp, clear_32bpp, NULL, NULL }, repack_meta }; const SmolImplementation * _smol_get_generic_implementation (void) { return &implementation; } chafa-1.18.2/chafa/internal/smolscale/smolscale-private.h000066400000000000000000000325551517447374300233410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright © 2019-2025 Hans Petter Jansson. See COPYING for details. */ /* If you're just going to use Smolscale in your project, you don't have to * worry about anything in here. The public API and documentation, such as * it is, lives in smolscale.h. * * If, on the other hand, you're here to hack on Smolscale itself, this file * contains all the internal shared declarations. */ #undef SMOL_ENABLE_ASSERTS #include #include #include "smolscale.h" #ifndef _SMOLSCALE_PRIVATE_H_ #define _SMOLSCALE_PRIVATE_H_ #ifdef __cplusplus extern "C" { #endif #ifdef SMOL_ENABLE_ASSERTS # include # define SMOL_ASSERT(x) assert (x) #else # define SMOL_ASSERT(x) #endif /* We'll use at most ~4MB of scratch space. That won't fit on the stack * everywhere, so we default to malloc(). If you know better, you can define * SMOL_USE_ALLOCA. */ #ifdef SMOL_USE_ALLOCA # define _SMOL_ALLOC(n) alloca (n) # define _SMOL_FREE(p) #else # define _SMOL_ALLOC(n) malloc (n) # define _SMOL_FREE(p) free (p) #endif /* Enum switches must handle every value */ #ifdef __GNUC__ # pragma GCC diagnostic error "-Wswitch" #endif /* Compensate for GCC missing intrinsics */ #ifdef __GNUC__ # if __GNUC__ < 8 # define _mm256_set_m128i(h, l) \ _mm256_insertf128_si256 (_mm256_castsi128_si256 (l), (h), 1) # endif #endif #ifndef FALSE # define FALSE (0) #endif #ifndef TRUE # define TRUE (!FALSE) #endif #ifndef MIN # define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX # define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif typedef unsigned int SmolBool; #define SMOL_4X2BIT(a, b, c, d) \ (((a) << 6) | ((b) << 4) | ((c) << 2) | (d)) #define SMOL_8X1BIT(a,b,c,d,e,f,g,h) \ (((a) << 7) | ((b) << 6) | ((c) << 5) | ((d) << 4) \ | ((e) << 3) | ((f) << 2) | ((g) << 1) | ((h) << 0)) #define SMOL_UNUSED(x) (void) ((x)=(x)) #define SMOL_RESTRICT __restrict #define SMOL_INLINE __attribute__((always_inline)) inline #define SMOL_CONST __attribute__((const)) #define SMOL_PURE __attribute__((pure)) #define SMOL_SMALL_MUL 256U #define SMOL_BIG_MUL 65536U #define SMOL_BOXES_MULTIPLIER ((uint64_t) SMOL_BIG_MUL * SMOL_SMALL_MUL) #define SMOL_BILIN_MULTIPLIER ((uint64_t) SMOL_BIG_MUL * SMOL_BIG_MUL) #define SMOL_ALIGNMENT 64 #ifdef SMOL_DISABLE_ASSUME_ALIGNED # define SMOL_ASSIGN_ALIGNED_TO(x, t, n) (t) (x) #else # define SMOL_ASSIGN_ALIGNED_TO(x, t, n) (t) __builtin_assume_aligned ((x), (n)) #endif #define SMOL_ASSIGN_ALIGNED(x, t) SMOL_ASSIGN_ALIGNED_TO ((x), t, SMOL_ALIGNMENT) #define SMOL_ASSUME_ALIGNED_TO(x, t, n) (x) = SMOL_ASSIGN_ALIGNED_TO ((x), t, (n)) #define SMOL_ASSUME_ALIGNED(x, t) SMOL_ASSUME_ALIGNED_TO ((x), t, SMOL_ALIGNMENT) /* Pointer to beginning of storage is stored in *r. This must be passed to smol_free() later. */ #define smol_alloc_aligned_to(s, a, r) \ ({ void *p; *(r) = _SMOL_ALLOC ((s) + (a)); p = (void *) (((uintptr_t) (*(r)) + (a)) & ~((a) - 1)); (p); }) #define smol_alloc_aligned(s, r) smol_alloc_aligned_to ((s), SMOL_ALIGNMENT, (r)) #define smol_free(p) _SMOL_FREE(p) typedef enum { SMOL_STORAGE_24BPP, SMOL_STORAGE_32BPP, SMOL_STORAGE_64BPP, SMOL_STORAGE_128BPP, SMOL_STORAGE_MAX } SmolStorageType; typedef enum { SMOL_FILTER_COPY, SMOL_FILTER_ONE, SMOL_FILTER_BILINEAR_0H, SMOL_FILTER_BILINEAR_1H, SMOL_FILTER_BILINEAR_2H, SMOL_FILTER_BILINEAR_3H, SMOL_FILTER_BILINEAR_4H, SMOL_FILTER_BILINEAR_5H, SMOL_FILTER_BILINEAR_6H, SMOL_FILTER_BOX, SMOL_FILTER_MAX } SmolFilterType; typedef enum { SMOL_REORDER_1234_TO_1234, SMOL_REORDER_1234_TO_2341, SMOL_REORDER_1234_TO_3214, SMOL_REORDER_1234_TO_4123, SMOL_REORDER_1234_TO_4321, SMOL_REORDER_1234_TO_123, SMOL_REORDER_1234_TO_321, SMOL_REORDER_123_TO_1234, SMOL_REORDER_1234_TO_1324, SMOL_REORDER_1234_TO_2314, SMOL_REORDER_1234_TO_2431, SMOL_REORDER_1234_TO_4132, SMOL_REORDER_1234_TO_4231, SMOL_REORDER_1234_TO_132, SMOL_REORDER_1234_TO_231, SMOL_REORDER_123_TO_1324, SMOL_REORDER_1234_TO_324, SMOL_REORDER_1234_TO_423, SMOL_REORDER_1234_TO_1423, SMOL_REORDER_1234_TO_3241, SMOL_REORDER_MAX } SmolReorderType; typedef enum { SMOL_ALPHA_UNASSOCIATED, SMOL_ALPHA_PREMUL8, SMOL_ALPHA_PREMUL16, SMOL_ALPHA_MAX } SmolAlphaType; typedef enum { SMOL_GAMMA_SRGB_COMPRESSED, SMOL_GAMMA_SRGB_LINEAR, SMOL_GAMMA_MAX } SmolGammaType; typedef struct { unsigned char src [4]; unsigned char dest [4]; } SmolReorderMeta; typedef struct { unsigned char storage; unsigned char pixel_stride; unsigned char alpha; unsigned char order [4]; } SmolPixelTypeMeta; /* For reusing rows that have already undergone horizontal scaling */ typedef struct { uint32_t src_ofs; uint64_t *parts_row [4]; uint64_t *row_storage [4]; uint32_t *src_aligned; uint32_t *src_aligned_storage; } SmolLocalCtx; typedef void (SmolInitFunc) (SmolScaleCtx *scale_ctx); typedef void (SmolRepackRowFunc) (const void *src_row, void *dest_row, uint32_t n_pixels); typedef void (SmolHFilterFunc) (const SmolScaleCtx *scale_ctx, const uint64_t *src_row_limbs, uint64_t *dest_row_limbs); typedef int (SmolVFilterFunc) (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index); typedef void (SmolCompositeOverColorFunc) (uint64_t *srcdest_row, const uint64_t *color_pixel, uint32_t n_pixels); typedef void (SmolCompositeOverDestFunc) (const uint64_t *src_row, uint64_t *dest_row, uint32_t n_pixels); typedef void (SmolClearFunc) (const void *src_pixel_batch, void *dest_row, uint32_t n_pixels); #define SMOL_REPACK_SIGNATURE_GET_REORDER(sig) ((sig) >> (2 * (SMOL_GAMMA_BITS + SMOL_ALPHA_BITS + SMOL_STORAGE_BITS))) #define SMOL_REORDER_BITS 6 #define SMOL_STORAGE_BITS 2 #define SMOL_ALPHA_BITS 2 #define SMOL_GAMMA_BITS 1 #define SMOL_MAKE_REPACK_SIGNATURE_ANY_ORDER(src_storage, src_alpha, src_gamma, \ dest_storage, dest_alpha, dest_gamma) \ (((src_storage) << (SMOL_GAMMA_BITS + SMOL_ALPHA_BITS + SMOL_STORAGE_BITS + SMOL_GAMMA_BITS + SMOL_ALPHA_BITS)) \ | ((src_alpha) << (SMOL_GAMMA_BITS + SMOL_ALPHA_BITS + SMOL_STORAGE_BITS + SMOL_GAMMA_BITS)) \ | ((src_gamma) << (SMOL_GAMMA_BITS + SMOL_ALPHA_BITS + SMOL_STORAGE_BITS)) \ | ((dest_storage) << (SMOL_GAMMA_BITS + SMOL_ALPHA_BITS)) \ | ((dest_alpha) << (SMOL_GAMMA_BITS)) \ | ((dest_gamma) << 0)) \ #define MASK_ITEM(m, n_bits) ((m) ? (1 << (n_bits)) - 1 : 0) #define SMOL_REPACK_SIGNATURE_ANY_ORDER_MASK(src_storage, src_alpha, src_gamma, \ dest_storage, dest_alpha, dest_gamma) \ SMOL_MAKE_REPACK_SIGNATURE_ANY_ORDER(MASK_ITEM (src_storage, SMOL_STORAGE_BITS), \ MASK_ITEM (src_alpha, SMOL_ALPHA_BITS), \ MASK_ITEM (src_gamma, SMOL_GAMMA_BITS), \ MASK_ITEM (dest_storage, SMOL_STORAGE_BITS), \ MASK_ITEM (dest_alpha, SMOL_ALPHA_BITS), \ MASK_ITEM (dest_gamma, SMOL_GAMMA_BITS)) #define SMOL_REPACK_META(src_order, src_storage, src_alpha, src_gamma, \ dest_order, dest_storage, dest_alpha, dest_gamma) \ { (((SMOL_REORDER_##src_order##_TO_##dest_order) << 10) \ | ((SMOL_STORAGE_##src_storage##BPP) << 8) | ((SMOL_ALPHA_##src_alpha) << 6) \ | ((SMOL_GAMMA_SRGB_##src_gamma) << 5) \ | ((SMOL_STORAGE_##dest_storage##BPP) << 3) | ((SMOL_ALPHA_##dest_alpha) << 1) \ | ((SMOL_GAMMA_SRGB_##dest_gamma) << 0)), \ (SmolRepackRowFunc *) repack_row_##src_order##_##src_storage##_##src_alpha##_##src_gamma##_to_##dest_order##_##dest_storage##_##dest_alpha##_##dest_gamma } #define SMOL_REPACK_META_LAST { 0xffff, NULL } typedef struct { uint16_t signature; SmolRepackRowFunc *repack_row_func; } SmolRepackMeta; #define SMOL_REPACK_ROW_DEF(src_order, src_storage, src_limb_bits, src_alpha, src_gamma, \ dest_order, dest_storage, dest_limb_bits, dest_alpha, dest_gamma) \ static void repack_row_##src_order##_##src_storage##_##src_alpha##_##src_gamma##_to_##dest_order##_##dest_storage##_##dest_alpha##_##dest_gamma \ (const uint##src_limb_bits##_t * SMOL_RESTRICT src_row, \ uint##dest_limb_bits##_t * SMOL_RESTRICT dest_row, \ uint32_t n_pixels) \ { \ uint##dest_limb_bits##_t *dest_row_max = dest_row + n_pixels * (dest_storage / dest_limb_bits); \ SMOL_ASSUME_ALIGNED_TO (src_row, const uint##src_limb_bits##_t *, src_limb_bits / 8); \ SMOL_ASSUME_ALIGNED_TO (dest_row, uint##dest_limb_bits##_t *, dest_limb_bits / 8); #define SMOL_REPACK_ROW_DEF_END } typedef struct { SmolInitFunc *init_h_func; SmolInitFunc *init_v_func; SmolHFilterFunc *hfilter_funcs [SMOL_STORAGE_MAX] [SMOL_FILTER_MAX]; SmolVFilterFunc *vfilter_funcs [SMOL_STORAGE_MAX] [SMOL_FILTER_MAX]; SmolCompositeOverColorFunc *composite_over_color_funcs [SMOL_STORAGE_MAX] [SMOL_GAMMA_MAX] [SMOL_ALPHA_MAX]; SmolCompositeOverDestFunc *composite_over_dest_funcs [SMOL_STORAGE_MAX]; SmolClearFunc *clear_funcs [SMOL_STORAGE_MAX]; const SmolRepackMeta *repack_meta; } SmolImplementation; typedef struct { void *precalc; SmolFilterType filter_type; uint32_t src_size_px, src_size_spx; uint32_t dest_size_px, dest_size_spx; unsigned int n_halvings; int32_t placement_ofs_px, placement_ofs_spx; uint32_t placement_size_px, placement_size_spx; uint32_t placement_size_prehalving_px, placement_size_prehalving_spx; uint32_t span_step; /* For box filter, in spx */ uint32_t span_mul; /* For box filter */ /* Opacity of first and last column or row. Used for subpixel placement * and applied after each scaling step. */ uint16_t first_opacity, last_opacity; /* Rows or cols to add consisting of unbroken pixel_color. This is done * after scaling but before conversion to output pixel format. */ uint16_t clear_before_px, clear_after_px; uint16_t clip_before_px, clip_after_px; } SmolDim; #define SMOL_CLEAR_BATCH_SIZE 96 struct SmolScaleCtx { /* */ const char *src_pixels; char *dest_pixels; size_t src_rowstride; size_t dest_rowstride; SmolPixelType src_pixel_type, dest_pixel_type; SmolStorageType storage_type; SmolGammaType gamma_type; SmolCompositeOp composite_op; /* Raw flags passed in by user */ SmolFlags flags; SmolRepackRowFunc *src_unpack_row_func; SmolRepackRowFunc *dest_unpack_row_func; SmolRepackRowFunc *pack_row_func; SmolHFilterFunc *hfilter_func; SmolVFilterFunc *vfilter_func; SmolCompositeOverColorFunc *composite_over_color_func; SmolCompositeOverDestFunc *composite_over_dest_func; SmolClearFunc *clear_dest_func; /* User specified, can be NULL */ SmolPostRowFunc *post_row_func; void *user_data; /* Storage for dimensions' precalc arrays. Single allocation. */ void *precalc_storage; /* Specifics for each dimension */ SmolDim hdim, vdim; /* TRUE if input rows can be copied directly to output. */ unsigned int is_noop : 1; /* TRUE if we have a color_pixel to composite on. */ unsigned int have_composite_color : 1; /* Unpacked color to composite on */ uint64_t color_pixel [2]; /* A batch of color pixels in dest storage format. The batch size * is in bytes, and chosen as an even multiple of 3, allowing 32 bytes wide * operations (e.g. AVX2) to be used to clear packed RGB pixels. */ unsigned char color_pixels_clear_batch [SMOL_CLEAR_BATCH_SIZE]; }; /* Number of pixels to convert per batch. For some conversions, we perform * an alpha test per batch to avoid the expensive premul path when the image * data is opaque. * * FIXME: Unimplemented. */ #define PIXEL_BATCH_SIZE 32 #define SRGB_LINEAR_BITS 11 #define SRGB_LINEAR_MAX (1 << (SRGB_LINEAR_BITS)) extern const uint16_t _smol_from_srgb_lut [256]; extern const uint8_t _smol_to_srgb_lut [SRGB_LINEAR_MAX]; #define INVERTED_DIV_SHIFT_P8 (21 - 8) #define INVERTED_DIV_SHIFT_P8L (22 - SRGB_LINEAR_BITS) #define INVERTED_DIV_SHIFT_P16 (24 - 8) #define INVERTED_DIV_SHIFT_P16L (30 - SRGB_LINEAR_BITS) extern const uint32_t _smol_inv_div_p8_lut [256]; extern const uint32_t _smol_inv_div_p8l_lut [256]; extern const uint32_t _smol_inv_div_p16_lut [256]; extern const uint32_t _smol_inv_div_p16l_lut [256]; const SmolImplementation *_smol_get_generic_implementation (void); #ifdef SMOL_WITH_AVX2 const SmolImplementation *_smol_get_avx2_implementation (void); #endif #ifdef __cplusplus } #endif #endif chafa-1.18.2/chafa/internal/smolscale/smolscale.c000066400000000000000000001743661517447374300216730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright © 2019-2025 Hans Petter Jansson. See COPYING for details. */ #include /* assert */ #include /* malloc, free, alloca */ #include /* memset */ #include #include "smolscale-private.h" /* ----------------------- * * Misc. conversion tables * * ----------------------- */ /* Table of channel reorderings. Each entry describes an available shuffle * implementation indexed by its SmolReorderType. Channel indexes are 1-based. * A zero index denotes that the channel is not present (e.g. 3-channel RGB). * * Keep in sync with the private SmolReorderType enum. */ static const SmolReorderMeta reorder_meta [SMOL_REORDER_MAX] = { { { 1, 2, 3, 4 }, { 1, 2, 3, 4 } }, { { 1, 2, 3, 4 }, { 2, 3, 4, 1 } }, { { 1, 2, 3, 4 }, { 3, 2, 1, 4 } }, { { 1, 2, 3, 4 }, { 4, 1, 2, 3 } }, { { 1, 2, 3, 4 }, { 4, 3, 2, 1 } }, { { 1, 2, 3, 4 }, { 1, 2, 3, 0 } }, { { 1, 2, 3, 4 }, { 3, 2, 1, 0 } }, { { 1, 2, 3, 0 }, { 1, 2, 3, 4 } }, { { 1, 2, 3, 4 }, { 1, 3, 2, 4 } }, { { 1, 2, 3, 4 }, { 2, 3, 1, 4 } }, { { 1, 2, 3, 4 }, { 2, 4, 3, 1 } }, { { 1, 2, 3, 4 }, { 4, 1, 3, 2 } }, { { 1, 2, 3, 4 }, { 4, 2, 3, 1 } }, { { 1, 2, 3, 4 }, { 1, 3, 2, 0 } }, { { 1, 2, 3, 4 }, { 2, 3, 1, 0 } }, { { 1, 2, 3, 0 }, { 1, 3, 2, 4 } }, { { 1, 2, 3, 4 }, { 3, 2, 4, 0 } }, { { 1, 2, 3, 4 }, { 4, 2, 3, 0 } }, { { 1, 2, 3, 4 }, { 1, 4, 2, 3 } }, { { 1, 2, 3, 4 }, { 3, 2, 4, 1 } } }; /* Metadata for each pixel type. Storage type, number of channels, alpha type, * channel ordering. Channel indexes are 1-based, and 4 is always alpha. A * zero index denotes that the channel is not present. * * RGBA = 1, 2, 3, 4. * * Keep in sync with the public SmolPixelType enum. */ static const SmolPixelTypeMeta pixel_type_meta [SMOL_PIXEL_MAX] = { { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_PREMUL8, { 1, 2, 3, 4 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_PREMUL8, { 3, 2, 1, 4 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_PREMUL8, { 4, 1, 2, 3 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_PREMUL8, { 4, 3, 2, 1 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_UNASSOCIATED, { 1, 2, 3, 4 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_UNASSOCIATED, { 3, 2, 1, 4 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_UNASSOCIATED, { 4, 1, 2, 3 } }, { SMOL_STORAGE_32BPP, 4, SMOL_ALPHA_UNASSOCIATED, { 4, 3, 2, 1 } }, { SMOL_STORAGE_24BPP, 3, SMOL_ALPHA_PREMUL8, { 1, 2, 3, 0 } }, { SMOL_STORAGE_24BPP, 3, SMOL_ALPHA_PREMUL8, { 3, 2, 1, 0 } } }; /* Channel ordering corrected for little endian. Only applies when fetching * entire pixels as dwords (i.e. u32), so 3-byte variants don't require any * correction. * * Keep in sync with the public SmolPixelType enum. */ static const SmolPixelType pixel_type_u32_le [SMOL_PIXEL_MAX] = { SMOL_PIXEL_ABGR8_PREMULTIPLIED, SMOL_PIXEL_ARGB8_PREMULTIPLIED, SMOL_PIXEL_BGRA8_PREMULTIPLIED, SMOL_PIXEL_RGBA8_PREMULTIPLIED, SMOL_PIXEL_ABGR8_UNASSOCIATED, SMOL_PIXEL_ARGB8_UNASSOCIATED, SMOL_PIXEL_BGRA8_UNASSOCIATED, SMOL_PIXEL_RGBA8_UNASSOCIATED, SMOL_PIXEL_RGB8, SMOL_PIXEL_BGR8 }; /* ----------------------------------- * * sRGB/linear conversion: Shared code * * ----------------------------------- */ /* These tables are manually tweaked to be reversible without information * loss; _smol_to_srgb_lut [_smol_from_srgb_lut [i]] == i. * * As a side effect, the values in the lower range (first 35 indexes) are * off by < 2%. */ const uint16_t _smol_from_srgb_lut [256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 62, 64, 67, 69, 72, 74, 77, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 113, 116, 119, 123, 126, 130, 134, 137, 141, 145, 149, 153, 157, 161, 165, 169, 174, 178, 182, 187, 191, 196, 201, 205, 210, 215, 220, 225, 230, 235, 240, 246, 251, 256, 262, 267, 273, 279, 284, 290, 296, 302, 308, 314, 320, 326, 333, 339, 345, 352, 359, 365, 372, 379, 385, 392, 399, 406, 414, 421, 428, 435, 443, 450, 458, 466, 473, 481, 489, 497, 505, 513, 521, 530, 538, 546, 555, 563, 572, 581, 589, 598, 607, 616, 625, 634, 644, 653, 662, 672, 682, 691, 701, 711, 721, 731, 741, 751, 761, 771, 782, 792, 803, 813, 824, 835, 845, 856, 867, 879, 890, 901, 912, 924, 935, 947, 959, 970, 982, 994, 1006, 1018, 1030, 1043, 1055, 1067, 1080, 1093, 1105, 1118, 1131, 1144, 1157, 1170, 1183, 1197, 1210, 1223, 1237, 1251, 1264, 1278, 1292, 1306, 1320, 1334, 1349, 1363, 1377, 1392, 1407, 1421, 1436, 1451, 1466, 1481, 1496, 1512, 1527, 1542, 1558, 1573, 1589, 1605, 1621, 1637, 1653, 1669, 1685, 1702, 1718, 1735, 1751, 1768, 1785, 1802, 1819, 1836, 1853, 1870, 1887, 1905, 1922, 1940, 1958, 1976, 1994, 2012, 2030, 2047 }; const uint8_t _smol_to_srgb_lut [SRGB_LINEAR_MAX] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 47, 48, 48, 49, 49, 49, 50, 50, 51, 51, 51, 52, 52, 53, 53, 53, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 84, 84, 85, 85, 85, 85, 86, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 107, 108, 108, 108, 108, 108, 108, 109, 109, 109, 109, 109, 109, 110, 110, 110, 110, 110, 110, 110, 111, 111, 111, 111, 111, 111, 112, 112, 112, 112, 112, 112, 113, 113, 113, 113, 113, 113, 113, 114, 114, 114, 114, 114, 114, 115, 115, 115, 115, 115, 115, 115, 116, 116, 116, 116, 116, 116, 117, 117, 117, 117, 117, 117, 117, 118, 118, 118, 118, 118, 118, 118, 119, 119, 119, 119, 119, 119, 120, 120, 120, 120, 120, 120, 120, 121, 121, 121, 121, 121, 121, 121, 122, 122, 122, 122, 122, 122, 122, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 125, 125, 125, 125, 125, 126, 126, 126, 126, 126, 126, 126, 127, 127, 127, 127, 127, 127, 127, 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 129, 129, 129, 129, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, 133, 133, 134, 134, 134, 134, 134, 134, 134, 134, 135, 135, 135, 135, 135, 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, 136, 137, 137, 137, 137, 137, 137, 137, 137, 137, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141, 141, 141, 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, 144, 144, 144, 145, 145, 145, 145, 145, 145, 145, 145, 146, 146, 146, 146, 146, 146, 146, 146, 146, 147, 147, 147, 147, 147, 147, 147, 147, 147, 148, 148, 148, 148, 148, 148, 148, 148, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, 150, 150, 150, 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 153, 153, 153, 153, 153, 153, 153, 153, 153, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 155, 155, 155, 155, 155, 155, 155, 155, 155, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 157, 157, 157, 157, 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; /* ------------------------------ * * Premultiplication: Shared code * * ------------------------------ */ /* These tables are used to divide by an integer [1..255] using only a lookup, * multiplication and a shift. This is faster than plain division on most * architectures. * * The values are tuned to minimize the error and overhead when turning * premultiplied (8-bit, 11-bit, 16-bit, 19-bit) into 8-bit unassociated alpha. */ /* Lossy premultiplication: 8-bit * alpha -> 8-bit. Not perfectly reversible. */ const uint32_t _smol_inv_div_p8_lut [256] = { 0x00000000, 0x00181fff, 0x000e2fff, 0x0009f555, 0x0007a7ff, 0x00063333, 0x00052555, 0x00047999, 0x0003ebff, 0x0003838e, 0x00032333, 0x0002e2e8, 0x0002a2aa, 0x0002713b, 0x00024249, 0x00021ccc, 0x0001f924, 0x0001dd17, 0x0001c1c7, 0x0001ab4b, 0x000195e5, 0x0001830c, 0x000170c3, 0x00016164, 0x0001537a, 0x0001450d, 0x0001390b, 0x00012de9, 0x00012249, 0x00011846, 0x00010eaa, 0x0001069e, 0x0000fd70, 0x0000f6aa, 0x0000eedb, 0x0000e8f5, 0x0000e1c7, 0x0000db8e, 0x0000d638, 0x0000d069, 0x0000cb7c, 0x0000c690, 0x0000c186, 0x0000bd2d, 0x0000b8f9, 0x0000b4f7, 0x0000b0ff, 0x0000ad65, 0x0000a9ac, 0x0000a687, 0x0000a286, 0x00009f33, 0x00009c98, 0x000099b9, 0x000096f1, 0x00009414, 0x00009147, 0x00008efa, 0x00008c59, 0x00008a0a, 0x000087b4, 0x0000856c, 0x00008341, 0x0000818c, 0x00007f55, 0x00007d60, 0x00007b7f, 0x000079b2, 0x000077b9, 0x00007608, 0x0000743c, 0x000072b5, 0x0000711a, 0x00006fac, 0x00006e1a, 0x00006cad, 0x00006b17, 0x000069e1, 0x00006864, 0x00006736, 0x000065db, 0x000064b1, 0x00006357, 0x00006250, 0x000060c5, 0x00006060, 0x00005ec0, 0x00005da5, 0x00005c9b, 0x00005b8b, 0x00005a93, 0x000059ab, 0x00005884, 0x00005799, 0x000056ae, 0x000055d5, 0x000054e2, 0x0000540b, 0x00005343, 0x00005255, 0x0000517c, 0x000050a7, 0x00004fff, 0x00004f2c, 0x00004e5e, 0x00004d9f, 0x00004cec, 0x00004c34, 0x00004b78, 0x00004adc, 0x00004a23, 0x00004981, 0x000048ce, 0x00004836, 0x0000478c, 0x000046eb, 0x00004656, 0x000045b6, 0x00004524, 0x0000449c, 0x000043ff, 0x00004370, 0x000042e2, 0x00004257, 0x000041ce, 0x00004147, 0x000040c3, 0x00004081, 0x00003fff, 0x00003f57, 0x00003ed3, 0x00003e54, 0x00003dd9, 0x00003d60, 0x00003ced, 0x00003c78, 0x00003c07, 0x00003b9a, 0x00003b26, 0x00003abf, 0x00003a4f, 0x000039e1, 0x0000397e, 0x00003917, 0x000038af, 0x00003848, 0x000037ee, 0x00003787, 0x00003726, 0x000036c9, 0x0000366b, 0x0000360d, 0x000035b0, 0x00003567, 0x00003503, 0x000034aa, 0x00003453, 0x000033ff, 0x000033a8, 0x0000335c, 0x00003305, 0x000032b3, 0x00003266, 0x00003213, 0x000031c7, 0x00003178, 0x0000312b, 0x000030df, 0x00003094, 0x00003049, 0x00003018, 0x00002fc0, 0x00002f76, 0x00002f2d, 0x00002ee8, 0x00002ea6, 0x00002e5f, 0x00002e1c, 0x00002dd9, 0x00002d99, 0x00002d59, 0x00002d17, 0x00002cdf, 0x00002c9b, 0x00002c5d, 0x00002c1c, 0x00002be1, 0x00002ba6, 0x00002b6a, 0x00002b2e, 0x00002af3, 0x00002ac7, 0x00002a85, 0x00002a4a, 0x00002a11, 0x000029dc, 0x000029a6, 0x0000296e, 0x00002936, 0x00002904, 0x000028cd, 0x0000289a, 0x00002866, 0x00002833, 0x0000280a, 0x000027d0, 0x0000279e, 0x0000276f, 0x0000273c, 0x0000270d, 0x000026de, 0x000026ad, 0x0000267e, 0x00002652, 0x00002622, 0x000025f5, 0x000025c9, 0x0000259b, 0x0000256f, 0x00002545, 0x00002518, 0x000024ef, 0x000024c3, 0x0000249c, 0x0000246f, 0x00002446, 0x0000241c, 0x000023f4, 0x000023ca, 0x000023a2, 0x0000237b, 0x00002354, 0x0000232e, 0x00002306, 0x000022e0, 0x000022b9, 0x00002294, 0x0000226f, 0x0000224b, 0x00002226, 0x00002202, 0x000021dc, 0x000021b8, 0x00002195, 0x00002172, 0x0000214f, 0x0000212c, 0x0000210a, 0x000020e7, 0x000020c5, 0x000020a4, 0x00002083, 0x00002061, 0x00002041, 0x00002020, 0x00002020 }; /* Lossy premultiplication: 11-bit * alpha -> 11-bit. Not perfectly reversible. */ const uint32_t _smol_inv_div_p8l_lut [256] = { 0x00000000, 0x0007ffff, 0x0003ffff, 0x0002aaaa, 0x0001ffff, 0x00019999, 0x00015555, 0x00012492, 0x0000ffff, 0x0000e38e, 0x0000cccc, 0x0000ba2e, 0x0000aaaa, 0x00009d89, 0x00009249, 0x00008888, 0x00007fff, 0x00007878, 0x000071c7, 0x00006bca, 0x00006666, 0x00006186, 0x00005d17, 0x0000590b, 0x00005555, 0x000051eb, 0x00004ec4, 0x00004bda, 0x00004924, 0x0000469e, 0x00004444, 0x00004210, 0x00003fff, 0x00003e0f, 0x00003c3c, 0x00003a83, 0x000038e3, 0x0000372a, 0x000035b7, 0x00003458, 0x0000330a, 0x000031cc, 0x0000309e, 0x00002f7d, 0x00002e69, 0x00002d62, 0x00002c66, 0x00002b75, 0x00002a8e, 0x000029b0, 0x000028db, 0x0000280f, 0x0000274a, 0x0000268c, 0x000025d6, 0x00002526, 0x0000247d, 0x000023d9, 0x0000233c, 0x000022a3, 0x0000220f, 0x00002181, 0x000020f7, 0x00002071, 0x00001ff0, 0x00001f72, 0x00001ef8, 0x00001e82, 0x00001e0f, 0x00001da0, 0x00001d34, 0x00001ccb, 0x00001c65, 0x00001bf5, 0x00001b95, 0x00001b37, 0x00001adb, 0x00001a82, 0x00001a2c, 0x000019d7, 0x00001985, 0x00001934, 0x000018e6, 0x00001899, 0x0000184f, 0x00001806, 0x000017be, 0x00001779, 0x00001734, 0x000016f2, 0x000016b1, 0x00001671, 0x00001633, 0x000015f6, 0x000015ba, 0x00001580, 0x00001547, 0x0000150f, 0x000014d8, 0x000014a2, 0x0000146d, 0x0000143a, 0x00001407, 0x000013d5, 0x000013a5, 0x00001375, 0x00001346, 0x00001318, 0x000012eb, 0x000012be, 0x0000128e, 0x00001263, 0x00001239, 0x00001210, 0x000011e7, 0x000011c0, 0x00001199, 0x00001172, 0x0000114d, 0x00001127, 0x00001103, 0x000010df, 0x000010bc, 0x00001099, 0x00001077, 0x00001055, 0x00001034, 0x00001014, 0x00000ff4, 0x00000fd4, 0x00000fb5, 0x00000f96, 0x00000f78, 0x00000f5a, 0x00000f3d, 0x00000f20, 0x00000f04, 0x00000ee8, 0x00000ecc, 0x00000eb1, 0x00000e96, 0x00000e7c, 0x00000e62, 0x00000e48, 0x00000e2f, 0x00000e16, 0x00000dfa, 0x00000de2, 0x00000dca, 0x00000db2, 0x00000d9b, 0x00000d84, 0x00000d6d, 0x00000d57, 0x00000d41, 0x00000d2b, 0x00000d16, 0x00000d00, 0x00000ceb, 0x00000cd7, 0x00000cc2, 0x00000cae, 0x00000c9a, 0x00000c86, 0x00000c73, 0x00000c5f, 0x00000c4c, 0x00000c3a, 0x00000c27, 0x00000c15, 0x00000c03, 0x00000bf1, 0x00000bdf, 0x00000bcd, 0x00000bbc, 0x00000bab, 0x00000b9a, 0x00000b89, 0x00000b79, 0x00000b68, 0x00000b58, 0x00000b48, 0x00000b38, 0x00000b27, 0x00000b17, 0x00000b08, 0x00000af9, 0x00000aea, 0x00000adb, 0x00000acc, 0x00000abe, 0x00000ab0, 0x00000aa1, 0x00000a93, 0x00000a85, 0x00000a78, 0x00000a6a, 0x00000a5c, 0x00000a4f, 0x00000a42, 0x00000a35, 0x00000a28, 0x00000a1b, 0x00000a0e, 0x00000a02, 0x000009f5, 0x000009e9, 0x000009dd, 0x000009d1, 0x000009c5, 0x000009b9, 0x000009ad, 0x000009a1, 0x00000996, 0x0000098a, 0x0000097f, 0x00000974, 0x00000969, 0x0000095e, 0x00000951, 0x00000947, 0x0000093c, 0x00000931, 0x00000927, 0x0000091c, 0x00000912, 0x00000908, 0x000008fe, 0x000008f3, 0x000008e9, 0x000008e0, 0x000008d6, 0x000008cc, 0x000008c2, 0x000008b9, 0x000008af, 0x000008a6, 0x0000089d, 0x00000893, 0x0000088a, 0x00000881, 0x00000878, 0x0000086f, 0x00000866, 0x0000085e, 0x00000855, 0x0000084c, 0x00000844, 0x0000083b, 0x00000833, 0x0000082a, 0x00000822, 0x0000081a, 0x00000812, 0x0000080a, 0x00000801 }; /* Lossless premultiplication: 8-bit * alpha -> 16-bit. Reversible with this table. */ const uint32_t _smol_inv_div_p16_lut [256] = { 0x00000000, 0x00005556, 0x00004000, 0x00003334, 0x00002aab, 0x00002493, 0x00002000, 0x00001c72, 0x0000199a, 0x00001746, 0x00001556, 0x000013b2, 0x0000124a, 0x00001112, 0x00001000, 0x00000f10, 0x00000e39, 0x00000d7a, 0x00000ccd, 0x00000c31, 0x00000ba3, 0x00000b22, 0x00000aab, 0x00000a3e, 0x000009d9, 0x0000097c, 0x00000925, 0x000008d4, 0x00000889, 0x00000843, 0x00000800, 0x000007c2, 0x00000788, 0x00000751, 0x0000071d, 0x000006ec, 0x000006bd, 0x00000691, 0x00000667, 0x0000063f, 0x00000619, 0x000005f5, 0x000005d2, 0x000005b1, 0x00000591, 0x00000573, 0x00000556, 0x0000053a, 0x0000051f, 0x00000506, 0x000004ed, 0x000004d5, 0x000004be, 0x000004a8, 0x00000493, 0x0000047e, 0x0000046a, 0x00000457, 0x00000445, 0x00000433, 0x00000422, 0x00000411, 0x00000400, 0x000003f1, 0x000003e1, 0x000003d3, 0x000003c4, 0x000003b6, 0x000003a9, 0x0000039c, 0x0000038f, 0x00000382, 0x00000376, 0x0000036a, 0x0000035f, 0x00000354, 0x00000349, 0x0000033e, 0x00000334, 0x0000032a, 0x00000320, 0x00000316, 0x0000030d, 0x00000304, 0x000002fb, 0x000002f2, 0x000002e9, 0x000002e1, 0x000002d9, 0x000002d1, 0x000002c9, 0x000002c1, 0x000002ba, 0x000002b2, 0x000002ab, 0x000002a4, 0x0000029d, 0x00000296, 0x00000290, 0x00000289, 0x00000283, 0x0000027d, 0x00000277, 0x00000271, 0x0000026b, 0x00000265, 0x0000025f, 0x0000025a, 0x00000254, 0x0000024f, 0x0000024a, 0x00000244, 0x0000023f, 0x0000023a, 0x00000235, 0x00000231, 0x0000022c, 0x00000227, 0x00000223, 0x0000021e, 0x0000021a, 0x00000215, 0x00000211, 0x0000020d, 0x00000209, 0x00000205, 0x00000200, 0x000001fd, 0x000001f9, 0x000001f5, 0x000001f1, 0x000001ed, 0x000001ea, 0x000001e6, 0x000001e2, 0x000001df, 0x000001db, 0x000001d8, 0x000001d5, 0x000001d1, 0x000001ce, 0x000001cb, 0x000001c8, 0x000001c4, 0x000001c1, 0x000001be, 0x000001bb, 0x000001b8, 0x000001b5, 0x000001b3, 0x000001b0, 0x000001ad, 0x000001aa, 0x000001a7, 0x000001a5, 0x000001a2, 0x0000019f, 0x0000019d, 0x0000019a, 0x00000198, 0x00000195, 0x00000193, 0x00000190, 0x0000018e, 0x0000018b, 0x00000189, 0x00000187, 0x00000184, 0x00000182, 0x00000180, 0x0000017e, 0x0000017b, 0x00000179, 0x00000177, 0x00000175, 0x00000173, 0x00000171, 0x0000016f, 0x0000016d, 0x0000016b, 0x00000169, 0x00000167, 0x00000165, 0x00000163, 0x00000161, 0x0000015f, 0x0000015d, 0x0000015b, 0x00000159, 0x00000158, 0x00000156, 0x00000154, 0x00000152, 0x00000151, 0x0000014f, 0x0000014d, 0x0000014b, 0x0000014a, 0x00000148, 0x00000147, 0x00000145, 0x00000143, 0x00000142, 0x00000140, 0x0000013f, 0x0000013d, 0x0000013c, 0x0000013a, 0x00000139, 0x00000137, 0x00000136, 0x00000134, 0x00000133, 0x00000131, 0x00000130, 0x0000012f, 0x0000012d, 0x0000012c, 0x0000012a, 0x00000129, 0x00000128, 0x00000126, 0x00000125, 0x00000124, 0x00000122, 0x00000121, 0x00000120, 0x0000011f, 0x0000011d, 0x0000011c, 0x0000011b, 0x0000011a, 0x00000119, 0x00000117, 0x00000116, 0x00000115, 0x00000114, 0x00000113, 0x00000112, 0x00000110, 0x0000010f, 0x0000010e, 0x0000010d, 0x0000010c, 0x0000010b, 0x0000010a, 0x00000109, 0x00000108, 0x00000107, 0x00000106, 0x00000105, 0x00000104, 0x00000103, 0x00000102, 0x00000100, 0x00000100 }; /* Lossless premultiplication: 11-bit * alpha -> 19-bit. Reversible with this table. */ const uint32_t _smol_inv_div_p16l_lut [256] = { 0x00000000, 0x0002aaab, 0x00020000, 0x0001999a, 0x00015556, 0x00012493, 0x00010000, 0x0000e38f, 0x0000cccd, 0x0000ba2f, 0x0000aaab, 0x00009d8a, 0x0000924a, 0x00008889, 0x00008000, 0x00007879, 0x000071c8, 0x00006bcb, 0x00006667, 0x00006187, 0x00005d18, 0x0000590c, 0x00005556, 0x000051ec, 0x00004ec5, 0x00004bdb, 0x00004925, 0x0000469f, 0x00004445, 0x00004211, 0x00004000, 0x00003e10, 0x00003c3d, 0x00003a84, 0x000038e4, 0x0000375a, 0x000035e6, 0x00003484, 0x00003334, 0x000031f4, 0x000030c4, 0x00002fa1, 0x00002e8c, 0x00002d83, 0x00002c86, 0x00002b94, 0x00002aab, 0x000029cc, 0x000028f6, 0x00002829, 0x00002763, 0x000026a5, 0x000025ee, 0x0000253d, 0x00002493, 0x000023ef, 0x00002350, 0x000022b7, 0x00002223, 0x00002193, 0x00002109, 0x00002083, 0x00002000, 0x00001f82, 0x00001f08, 0x00001e92, 0x00001e1f, 0x00001daf, 0x00001d42, 0x00001cd9, 0x00001c72, 0x00001c0f, 0x00001bad, 0x00001b4f, 0x00001af3, 0x00001a99, 0x00001a42, 0x000019ed, 0x0000199a, 0x00001949, 0x000018fa, 0x000018ad, 0x00001862, 0x00001819, 0x000017d1, 0x0000178b, 0x00001746, 0x00001703, 0x000016c2, 0x00001682, 0x00001643, 0x00001606, 0x000015ca, 0x0000158f, 0x00001556, 0x0000151e, 0x000014e6, 0x000014b0, 0x0000147b, 0x00001447, 0x00001415, 0x000013e3, 0x000013b2, 0x00001382, 0x00001353, 0x00001324, 0x000012f7, 0x000012ca, 0x0000129f, 0x00001274, 0x0000124a, 0x00001220, 0x000011f8, 0x000011d0, 0x000011a8, 0x00001182, 0x0000115c, 0x00001136, 0x00001112, 0x000010ed, 0x000010ca, 0x000010a7, 0x00001085, 0x00001063, 0x00001042, 0x00001021, 0x00001000, 0x00000fe1, 0x00000fc1, 0x00000fa3, 0x00000f84, 0x00000f67, 0x00000f49, 0x00000f2c, 0x00000f10, 0x00000ef3, 0x00000ed8, 0x00000ebc, 0x00000ea1, 0x00000e87, 0x00000e6d, 0x00000e53, 0x00000e39, 0x00000e20, 0x00000e08, 0x00000def, 0x00000dd7, 0x00000dbf, 0x00000da8, 0x00000d91, 0x00000d7a, 0x00000d63, 0x00000d4d, 0x00000d37, 0x00000d21, 0x00000d0c, 0x00000cf7, 0x00000ce2, 0x00000ccd, 0x00000cb9, 0x00000ca5, 0x00000c91, 0x00000c7d, 0x00000c6a, 0x00000c57, 0x00000c44, 0x00000c31, 0x00000c1f, 0x00000c0d, 0x00000bfb, 0x00000be9, 0x00000bd7, 0x00000bc6, 0x00000bb4, 0x00000ba3, 0x00000b93, 0x00000b82, 0x00000b71, 0x00000b61, 0x00000b51, 0x00000b41, 0x00000b31, 0x00000b22, 0x00000b12, 0x00000b03, 0x00000af4, 0x00000ae5, 0x00000ad7, 0x00000ac8, 0x00000ab9, 0x00000aab, 0x00000a9d, 0x00000a8f, 0x00000a81, 0x00000a73, 0x00000a66, 0x00000a58, 0x00000a4b, 0x00000a3e, 0x00000a31, 0x00000a24, 0x00000a17, 0x00000a0b, 0x000009fe, 0x000009f2, 0x000009e5, 0x000009d9, 0x000009cd, 0x000009c1, 0x000009b5, 0x000009aa, 0x0000099e, 0x00000992, 0x00000987, 0x0000097c, 0x00000971, 0x00000965, 0x0000095b, 0x00000950, 0x00000945, 0x0000093a, 0x00000930, 0x00000925, 0x0000091b, 0x00000910, 0x00000906, 0x000008fc, 0x000008f2, 0x000008e8, 0x000008de, 0x000008d4, 0x000008cb, 0x000008c1, 0x000008b8, 0x000008ae, 0x000008a5, 0x0000089b, 0x00000892, 0x00000889, 0x00000880, 0x00000877, 0x0000086e, 0x00000865, 0x0000085c, 0x00000854, 0x0000084b, 0x00000843, 0x0000083a, 0x00000832, 0x00000829, 0x00000821, 0x00000819, 0x00000811, 0x00000809, 0x00000800, 0x000007f9 }; /* ------- * * Helpers * * ------- */ static SMOL_INLINE int check_row_range (const SmolScaleCtx *scale_ctx, int32_t *first_dest_row, int32_t *n_dest_rows) { if (*first_dest_row < 0) { *n_dest_rows += *first_dest_row; *first_dest_row = 0; } else if (*first_dest_row >= (int32_t) scale_ctx->vdim.dest_size_px) { return 0; } if (*n_dest_rows < 0 || *first_dest_row + *n_dest_rows > (int32_t) scale_ctx->vdim.dest_size_px) { *n_dest_rows = scale_ctx->vdim.dest_size_px - *first_dest_row; } else if (*n_dest_rows == 0) { return 0; } return 1; } /* ------------------- * * Scaling: Outer loop * * ------------------- */ static SMOL_INLINE const char * src_row_ofs_to_pointer (const SmolScaleCtx *scale_ctx, uint32_t src_row_ofs) { return scale_ctx->src_pixels + scale_ctx->src_rowstride * src_row_ofs; } static SMOL_INLINE char * dest_row_ofs_to_pointer (const SmolScaleCtx *scale_ctx, uint32_t dest_row_ofs) { return scale_ctx->dest_pixels + scale_ctx->dest_rowstride * dest_row_ofs; } static SMOL_INLINE void * dest_hofs_to_pointer (const SmolScaleCtx *scale_ctx, void *dest_row_ptr, uint32_t dest_hofs) { uint8_t *dest_row_ptr_u8 = dest_row_ptr; return dest_row_ptr_u8 + dest_hofs * pixel_type_meta [scale_ctx->dest_pixel_type].pixel_stride; } static void copy_row (const SmolScaleCtx *scale_ctx, uint32_t dest_row_index, uint32_t *row_out) { memcpy (row_out, src_row_ofs_to_pointer (scale_ctx, dest_row_index), scale_ctx->hdim.dest_size_px * pixel_type_meta [scale_ctx->dest_pixel_type].pixel_stride); } static void scale_dest_row (const SmolScaleCtx *scale_ctx, SmolLocalCtx *local_ctx, uint32_t dest_row_index, void *row_out) { if (dest_row_index < scale_ctx->vdim.clear_before_px || dest_row_index >= scale_ctx->vdim.dest_size_px - scale_ctx->vdim.clear_after_px) { /* Row doesn't intersect placement */ if (scale_ctx->composite_op == SMOL_COMPOSITE_SRC_CLEAR_DEST) { /* Clear entire row */ scale_ctx->clear_dest_func (scale_ctx->color_pixels_clear_batch, row_out, scale_ctx->hdim.dest_size_px); } } else { if (scale_ctx->composite_op == SMOL_COMPOSITE_SRC_CLEAR_DEST) { /* Clear left */ scale_ctx->clear_dest_func (scale_ctx->color_pixels_clear_batch, row_out, scale_ctx->hdim.clear_before_px); } if (scale_ctx->is_noop) { copy_row (scale_ctx, dest_row_index, row_out); } else { int scaled_row_index; scaled_row_index = scale_ctx->vfilter_func (scale_ctx, local_ctx, dest_row_index - scale_ctx->vdim.clear_before_px); if ((scale_ctx->composite_op == SMOL_COMPOSITE_SRC || scale_ctx->composite_op == SMOL_COMPOSITE_SRC_CLEAR_DEST) && scale_ctx->have_composite_color) { scale_ctx->composite_over_color_func (local_ctx->parts_row [scaled_row_index], scale_ctx->color_pixel, scale_ctx->hdim.placement_size_px); } scale_ctx->pack_row_func (local_ctx->parts_row [scaled_row_index], dest_hofs_to_pointer (scale_ctx, row_out, scale_ctx->hdim.placement_ofs_px), scale_ctx->hdim.placement_size_px); } if (scale_ctx->composite_op == SMOL_COMPOSITE_SRC_CLEAR_DEST) { /* Clear right */ scale_ctx->clear_dest_func (scale_ctx->color_pixels_clear_batch, dest_hofs_to_pointer (scale_ctx, row_out, scale_ctx->hdim.placement_ofs_px + scale_ctx->hdim.placement_size_px), scale_ctx->hdim.clear_after_px); } } if (scale_ctx->post_row_func) scale_ctx->post_row_func (row_out, scale_ctx->hdim.dest_size_px, scale_ctx->user_data); } static void do_rows (const SmolScaleCtx *scale_ctx, void *dest, uint32_t row_dest_index, uint32_t n_rows) { SmolLocalCtx local_ctx = { 0 }; uint32_t n_parts_per_pixel = 1; uint32_t n_stored_rows = 4; uint32_t i; if (scale_ctx->storage_type == SMOL_STORAGE_128BPP) n_parts_per_pixel = 2; /* Must be one less, or this test in update_local_ctx() will wrap around: * if (new_src_ofs == local_ctx->src_ofs + 1) { ... } */ local_ctx.src_ofs = UINT_MAX - 1; for (i = 0; i < n_stored_rows; i++) { /* Allocate space for an extra pixel at the rightmost edge. This pixel * allows bilinear horizontal sampling to exceed the input width and * produce transparency when the output is smaller than its whole-pixel * count. This is especially noticeable with halving, which can * produce 2^n such samples (the extra pixel is sampled repeatedly in * those cases). * * FIXME: This is no longer true, and the extra storage is probably not * needed. The edge transparency is now handled by applying a precalculated * opacity directly. We should verify that the extra storage can be * eliminated without overruns. */ local_ctx.parts_row [i] = smol_alloc_aligned (MAX (scale_ctx->hdim.src_size_px + 1, scale_ctx->hdim.placement_size_px) * n_parts_per_pixel * sizeof (uint64_t), &local_ctx.row_storage [i]); local_ctx.parts_row [i] [scale_ctx->hdim.src_size_px * n_parts_per_pixel] = 0; if (n_parts_per_pixel == 2) local_ctx.parts_row [i] [scale_ctx->hdim.src_size_px * n_parts_per_pixel + 1] = 0; } for (i = row_dest_index; i < row_dest_index + n_rows; i++) { scale_dest_row (scale_ctx, &local_ctx, i, dest); dest = (char *) dest + scale_ctx->dest_rowstride; } for (i = 0; i < n_stored_rows; i++) { smol_free (local_ctx.row_storage [i]); } /* Used to align row data if needed. May be allocated in scale_horizontal(). */ if (local_ctx.src_aligned) smol_free (local_ctx.src_aligned_storage); } /* -------------------- * * Architecture support * * -------------------- */ #ifdef SMOL_WITH_AVX2 static SmolBool have_avx2 (void) { __builtin_cpu_init (); if (__builtin_cpu_supports ("avx2")) return TRUE; return FALSE; } #endif static SmolBool host_is_little_endian (void) { static const union { uint8_t u8 [4]; uint32_t u32; } host_bytes = { { 0, 1, 2, 3 } }; if (host_bytes.u32 == 0x03020100UL) return TRUE; return FALSE; } /* The generic unpack/pack functions fetch and store pixels as u32. * This means the byte order will be reversed on little endian, with * consequences for the alpha channel and reordering logic. We deal * with this by using the apparent byte order internally. */ static SmolPixelType get_host_pixel_type (SmolPixelType pixel_type) { if (host_is_little_endian ()) return pixel_type_u32_le [pixel_type]; return pixel_type; } /* ---------------------- * * Context initialization * * ---------------------- */ static void pick_filter_params (uint32_t src_dim, uint32_t src_dim_spx, int32_t dest_ofs_spx, uint32_t dest_dim, uint32_t dest_dim_spx, uint32_t *dest_halvings, uint32_t *dest_dim_prehalving, uint32_t *dest_dim_prehalving_spx, SmolFilterType *dest_filter, SmolStorageType *dest_storage, uint16_t *first_opacity, uint16_t *last_opacity, SmolFlags flags) { *dest_dim_prehalving = dest_dim; *dest_storage = (flags & SMOL_DISABLE_SRGB_LINEARIZATION) ? SMOL_STORAGE_64BPP : SMOL_STORAGE_128BPP; *first_opacity = SMOL_SUBPIXEL_MOD (-dest_ofs_spx - 1) + 1; *last_opacity = SMOL_SUBPIXEL_MOD (dest_ofs_spx + dest_dim_spx - 1) + 1; /* Special handling when the output is a single pixel */ if (dest_dim == 1) { *first_opacity = dest_dim_spx; *last_opacity = 256; } /* The box algorithms are only sufficiently precise when * src_dim > dest_dim * 5. box_64bpp typically starts outperforming * bilinear+halving at src_dim > dest_dim * 8. */ if (src_dim > dest_dim * 255) { *dest_storage = SMOL_STORAGE_128BPP; *dest_filter = SMOL_FILTER_BOX; } else if (src_dim > dest_dim * 8) { *dest_filter = SMOL_FILTER_BOX; } else if (src_dim <= 1) { *dest_filter = SMOL_FILTER_ONE; *last_opacity = ((dest_ofs_spx + dest_dim_spx - 1) % SMOL_SUBPIXEL_MUL) + 1; } else if ((dest_ofs_spx & 0xff) == 0 && src_dim_spx == dest_dim_spx) { *dest_filter = SMOL_FILTER_COPY; *first_opacity = 256; *last_opacity = 256; } else { uint32_t n_halvings = 0; uint32_t d = dest_dim_spx; for (;;) { d *= 2; if (d >= src_dim_spx) break; n_halvings++; } *dest_dim_prehalving = dest_dim << n_halvings; *dest_dim_prehalving_spx = dest_dim_spx << n_halvings; *dest_filter = SMOL_FILTER_BILINEAR_0H + n_halvings; *dest_halvings = n_halvings; } } static const SmolRepackMeta * find_repack_match (const SmolRepackMeta *meta, uint16_t sig, uint16_t mask) { sig &= mask; for (;; meta++) { if (!meta->repack_row_func) { meta = NULL; break; } if (sig == (meta->signature & mask)) break; } return meta; } static void do_reorder (const uint8_t *order_in, uint8_t *order_out, const uint8_t *reorder) { int i; for (i = 0; i < 4; i++) { uint8_t r = reorder [i]; uint8_t o; if (r == 0) { o = 0; } else { o = order_in [r - 1]; if (o == 0) o = i + 1; } order_out [i] = o; } } static void find_repacks (const SmolImplementation **implementations, SmolStorageType src_storage, SmolStorageType mid_storage, SmolStorageType dest_storage, SmolAlphaType src_alpha, SmolAlphaType mid_alpha, SmolAlphaType dest_alpha, SmolGammaType src_gamma, SmolGammaType mid_gamma, SmolGammaType dest_gamma, const SmolPixelTypeMeta *src_pmeta, const SmolPixelTypeMeta *dest_pmeta, const SmolRepackMeta **src_repack, const SmolRepackMeta **dest_repack) { int src_impl, dest_impl; const SmolRepackMeta *src_meta = NULL, *dest_meta = NULL; uint16_t src_to_mid_sig, mid_to_dest_sig; uint16_t sig_mask; int reorder_dest_alpha_ch; sig_mask = SMOL_REPACK_SIGNATURE_ANY_ORDER_MASK (1, 1, 1, 1, 1, 1); src_to_mid_sig = SMOL_MAKE_REPACK_SIGNATURE_ANY_ORDER (src_storage, src_alpha, src_gamma, mid_storage, mid_alpha, mid_gamma); mid_to_dest_sig = SMOL_MAKE_REPACK_SIGNATURE_ANY_ORDER (mid_storage, mid_alpha, mid_gamma, dest_storage, dest_alpha, dest_gamma); /* The initial conversion must always leave alpha in position #4, so further * processing knows where to find it. The order of the other channels * doesn't matter, as long as there's a repack chain that ultimately * produces the desired result. */ reorder_dest_alpha_ch = src_pmeta->order [0] == 4 ? 1 : 4; for (src_impl = 0; implementations [src_impl]; src_impl++) { src_meta = &implementations [src_impl]->repack_meta [0]; for (;; src_meta++) { uint8_t mid_order [4]; src_meta = find_repack_match (src_meta, src_to_mid_sig, sig_mask); if (!src_meta) break; if (reorder_meta [SMOL_REPACK_SIGNATURE_GET_REORDER (src_meta->signature)].dest [3] != reorder_dest_alpha_ch) continue; do_reorder (src_pmeta->order, mid_order, reorder_meta [SMOL_REPACK_SIGNATURE_GET_REORDER (src_meta->signature)].dest); for (dest_impl = 0; implementations [dest_impl]; dest_impl++) { dest_meta = &implementations [dest_impl]->repack_meta [0]; for (;; dest_meta++) { uint8_t dest_order [4]; dest_meta = find_repack_match (dest_meta, mid_to_dest_sig, sig_mask); if (!dest_meta) break; do_reorder (mid_order, dest_order, reorder_meta [SMOL_REPACK_SIGNATURE_GET_REORDER (dest_meta->signature)].dest); if (!memcmp (&dest_order, &dest_pmeta->order, sizeof (dest_order))) { /* Success */ goto out; } } } } } out: if (src_repack) *src_repack = src_meta; if (dest_repack) *dest_repack = dest_meta; } static void populate_clear_batch (SmolScaleCtx *scale_ctx) { uint8_t dest_color [16]; int pixel_stride; int i; scale_ctx->pack_row_func (scale_ctx->color_pixel, dest_color, 1); pixel_stride = pixel_type_meta [scale_ctx->dest_pixel_type].pixel_stride; for (i = 0; i != SMOL_CLEAR_BATCH_SIZE; i += pixel_stride) { /* Must be an exact fit */ SMOL_ASSERT (i + pixel_stride <= SMOL_CLEAR_BATCH_SIZE); memcpy (scale_ctx->color_pixels_clear_batch + i, dest_color, pixel_stride); } } #define IMPLEMENTATION_MAX 8 /* scale_ctx->storage_type must be initialized first by pick_filter_params() */ static void get_implementations (SmolScaleCtx *scale_ctx, const void *color_pixel, SmolPixelType color_pixel_type) { SmolPixelType src_ptype, dest_ptype; const SmolPixelTypeMeta *src_pmeta, *dest_pmeta; const SmolRepackMeta *src_rmeta, *dest_rmeta; SmolAlphaType internal_alpha = SMOL_ALPHA_PREMUL8; const SmolImplementation *implementations [IMPLEMENTATION_MAX]; uint64_t color_pixel_internal [2]; uint64_t color_pixel_as_src [2]; int i = 0; if (color_pixel) scale_ctx->have_composite_color = TRUE; /* Check for noop (direct copy) */ if (scale_ctx->hdim.src_size_spx == scale_ctx->hdim.dest_size_spx && scale_ctx->vdim.src_size_spx == scale_ctx->vdim.dest_size_spx && scale_ctx->src_pixel_type == scale_ctx->dest_pixel_type && scale_ctx->composite_op != SMOL_COMPOSITE_SRC_OVER_DEST) { /* The scaling and packing is a no-op, but we may still need to * clear dest, so allow the rest of the function to run so we get * the clear functions etc. */ scale_ctx->is_noop = TRUE; } /* Enumerate implementations, preferred first */ if (!(scale_ctx->flags & SMOL_DISABLE_ACCELERATION)) { #ifdef SMOL_WITH_AVX2 if (have_avx2 ()) implementations [i++] = _smol_get_avx2_implementation (); #endif } implementations [i++] = _smol_get_generic_implementation (); implementations [i] = NULL; /* Install repackers */ src_ptype = get_host_pixel_type (scale_ctx->src_pixel_type); dest_ptype = get_host_pixel_type (scale_ctx->dest_pixel_type); src_pmeta = &pixel_type_meta [src_ptype]; dest_pmeta = &pixel_type_meta [dest_ptype]; if (src_pmeta->alpha == SMOL_ALPHA_UNASSOCIATED && dest_pmeta->alpha == SMOL_ALPHA_UNASSOCIATED) { /* In order to preserve the color range in transparent pixels when going * from unassociated to unassociated, we use 16 bits per channel internally. */ internal_alpha = SMOL_ALPHA_PREMUL16; scale_ctx->storage_type = SMOL_STORAGE_128BPP; } if (scale_ctx->hdim.src_size_px > scale_ctx->hdim.dest_size_px * 8191 || scale_ctx->vdim.src_size_px > scale_ctx->vdim.dest_size_px * 8191) { /* Even with 128bpp, there's only enough bits to store 11-bit linearized * times 13 bits of summed pixels plus 8 bits of scratch space for * multiplying with an 8-bit weight -> 32 bits total per channel. * * For now, just turn off sRGB linearization if the input is bigger * than the output by a factor of 2^13 or more. */ scale_ctx->gamma_type = SMOL_GAMMA_SRGB_COMPRESSED; } find_repacks (implementations, src_pmeta->storage, scale_ctx->storage_type, dest_pmeta->storage, src_pmeta->alpha, internal_alpha, dest_pmeta->alpha, SMOL_GAMMA_SRGB_COMPRESSED, scale_ctx->gamma_type, SMOL_GAMMA_SRGB_COMPRESSED, src_pmeta, dest_pmeta, &src_rmeta, &dest_rmeta); SMOL_ASSERT (src_rmeta != NULL); SMOL_ASSERT (dest_rmeta != NULL); scale_ctx->src_unpack_row_func = src_rmeta->repack_row_func; scale_ctx->pack_row_func = dest_rmeta->repack_row_func; if (scale_ctx->composite_op == SMOL_COMPOSITE_SRC_OVER_DEST) { const SmolRepackMeta *dest_unpack_rmeta; /* Need to unpack destination rows and composite on them */ find_repacks (implementations, dest_pmeta->storage, scale_ctx->storage_type, dest_pmeta->storage, dest_pmeta->alpha, internal_alpha, dest_pmeta->alpha, SMOL_GAMMA_SRGB_COMPRESSED, scale_ctx->gamma_type, SMOL_GAMMA_SRGB_COMPRESSED, dest_pmeta, dest_pmeta, &dest_unpack_rmeta, NULL); SMOL_ASSERT (dest_unpack_rmeta != NULL); scale_ctx->dest_unpack_row_func = dest_unpack_rmeta->repack_row_func; } else { /* Compositing on solid color */ if (color_pixel) { SmolPixelType color_ptype; const SmolPixelTypeMeta *color_pmeta; const SmolRepackMeta *color_in_rmeta, *color_out_rmeta; color_ptype = get_host_pixel_type (color_pixel_type); color_pmeta = &pixel_type_meta [color_ptype]; find_repacks (implementations, color_pmeta->storage, scale_ctx->storage_type, src_pmeta->storage, color_pmeta->alpha, internal_alpha, src_pmeta->alpha, SMOL_GAMMA_SRGB_COMPRESSED, scale_ctx->gamma_type, SMOL_GAMMA_SRGB_COMPRESSED, color_pmeta, src_pmeta, &color_in_rmeta, &color_out_rmeta); SMOL_ASSERT (color_in_rmeta != NULL); SMOL_ASSERT (color_out_rmeta != NULL); /* We need the fill color to have the same internal byte order as * src. Currently, the simplest way to achieve this is to unpack the color, * repack it to the same format as src, then unpacking it to internal again. */ color_in_rmeta->repack_row_func (color_pixel, color_pixel_internal, 1); color_out_rmeta->repack_row_func (color_pixel_internal, color_pixel_as_src, 1); src_rmeta->repack_row_func (color_pixel_as_src, scale_ctx->color_pixel, 1); } else { /* No color provided; use fully transparent black */ memset (scale_ctx->color_pixel, 0, sizeof (scale_ctx->color_pixel)); } populate_clear_batch (scale_ctx); } /* Install filters and compositors */ scale_ctx->hfilter_func = NULL; scale_ctx->vfilter_func = NULL; scale_ctx->composite_over_color_func = NULL; scale_ctx->composite_over_dest_func = NULL; scale_ctx->clear_dest_func = NULL; for (i = 0; implementations [i]; i++) { SmolHFilterFunc *hfilter_func = implementations [i]->hfilter_funcs [scale_ctx->storage_type] [scale_ctx->hdim.filter_type]; SmolVFilterFunc *vfilter_func = implementations [i]->vfilter_funcs [scale_ctx->storage_type] [scale_ctx->vdim.filter_type]; SmolCompositeOverColorFunc *composite_over_color_func = implementations [i]->composite_over_color_funcs [scale_ctx->storage_type] [scale_ctx->gamma_type] [internal_alpha]; SmolCompositeOverDestFunc *composite_over_dest_func = implementations [i]->composite_over_dest_funcs [scale_ctx->storage_type]; SmolClearFunc *clear_dest_func = implementations [i]->clear_funcs [dest_pmeta->storage]; if (!scale_ctx->hfilter_func && hfilter_func) { scale_ctx->hfilter_func = hfilter_func; if (implementations [i]->init_h_func) implementations [i]->init_h_func (scale_ctx); } if (!scale_ctx->vfilter_func && vfilter_func) { scale_ctx->vfilter_func = vfilter_func; if (implementations [i]->init_v_func) implementations [i]->init_v_func (scale_ctx); } if (!scale_ctx->composite_over_color_func && composite_over_color_func) scale_ctx->composite_over_color_func = composite_over_color_func; if (!scale_ctx->composite_over_dest_func && composite_over_dest_func) scale_ctx->composite_over_dest_func = composite_over_dest_func; if (!scale_ctx->clear_dest_func && clear_dest_func) scale_ctx->clear_dest_func = clear_dest_func; } SMOL_ASSERT (scale_ctx->hfilter_func != NULL); SMOL_ASSERT (scale_ctx->vfilter_func != NULL); } static void init_dim (SmolDim *dim, uint32_t src_size_spx, uint32_t dest_size_spx, int32_t placement_ofs_spx, int32_t placement_size_spx, SmolFlags flags, SmolStorageType *storage_type_out) { dim->src_size_spx = src_size_spx; dim->src_size_px = SMOL_SPX_TO_PX (src_size_spx); dim->dest_size_spx = dest_size_spx; dim->dest_size_px = SMOL_SPX_TO_PX (dest_size_spx); dim->placement_ofs_spx = placement_ofs_spx; if (placement_ofs_spx < 0) dim->placement_ofs_px = (placement_ofs_spx - 255) / SMOL_SUBPIXEL_MUL; else dim->placement_ofs_px = placement_ofs_spx / SMOL_SUBPIXEL_MUL; dim->placement_size_spx = placement_size_spx; dim->placement_size_px = SMOL_SPX_TO_PX (placement_size_spx + SMOL_SUBPIXEL_MOD (placement_ofs_spx)); pick_filter_params (dim->src_size_px, dim->src_size_spx, dim->placement_ofs_spx, dim->placement_size_px, dim->placement_size_spx, &dim->n_halvings, &dim->placement_size_prehalving_px, &dim->placement_size_prehalving_spx, &dim->filter_type, storage_type_out, &dim->first_opacity, &dim->last_opacity, flags); /* Calculate clip and clear intervals */ if (dim->placement_ofs_px > 0) { dim->clear_before_px = dim->placement_ofs_px; dim->clip_before_px = 0; } else if (dim->placement_ofs_px < 0) { dim->clear_before_px = 0; dim->clip_before_px = -dim->placement_ofs_px; dim->first_opacity = 256; } if (dim->placement_ofs_px + dim->placement_size_px < dim->dest_size_px) { dim->clear_after_px = dim->dest_size_px - dim->placement_ofs_px - dim->placement_size_px; dim->clip_after_px = 0; } else if (dim->placement_ofs_px + dim->placement_size_px > dim->dest_size_px) { dim->clear_after_px = 0; dim->clip_after_px = dim->placement_ofs_px + dim->placement_size_px - dim->dest_size_px; dim->last_opacity = 256; } /* Clamp placement */ if (dim->placement_ofs_px < 0) { dim->placement_size_px += dim->placement_ofs_px; dim->placement_ofs_px = 0; } if (dim->placement_ofs_px + dim->placement_size_px > dim->dest_size_px) { dim->placement_size_px = dim->dest_size_px - dim->placement_ofs_px; } } static void smol_scale_init (SmolScaleCtx *scale_ctx, const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width_spx, uint32_t src_height_spx, uint32_t src_rowstride, const void *color_pixel, SmolPixelType color_pixel_type, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width_spx, uint32_t dest_height_spx, uint32_t dest_rowstride, int32_t placement_x_spx, int32_t placement_y_spx, int32_t placement_width_spx, int32_t placement_height_spx, SmolCompositeOp composite_op, SmolFlags flags, SmolPostRowFunc post_row_func, void *user_data) { SmolStorageType storage_type [2]; if (placement_width_spx <= 0 || placement_height_spx <= 0) { placement_width_spx = 0; placement_height_spx = 0; placement_x_spx = 0; placement_y_spx = 0; } scale_ctx->src_pixels = src_pixels; scale_ctx->src_pixel_type = src_pixel_type; scale_ctx->src_rowstride = src_rowstride; scale_ctx->dest_pixels = dest_pixels; scale_ctx->dest_pixel_type = dest_pixel_type; scale_ctx->dest_rowstride = dest_rowstride; scale_ctx->composite_op = composite_op; scale_ctx->flags = flags; scale_ctx->gamma_type = (flags & SMOL_DISABLE_SRGB_LINEARIZATION) ? SMOL_GAMMA_SRGB_COMPRESSED : SMOL_GAMMA_SRGB_LINEAR; scale_ctx->post_row_func = post_row_func; scale_ctx->user_data = user_data; init_dim (&scale_ctx->hdim, src_width_spx, dest_width_spx, placement_x_spx, placement_width_spx, flags, &storage_type [0]); init_dim (&scale_ctx->vdim, src_height_spx, dest_height_spx, placement_y_spx, placement_height_spx, flags, &storage_type [1]); scale_ctx->storage_type = MAX (storage_type [0], storage_type [1]); scale_ctx->hdim.precalc = smol_alloc_aligned (((scale_ctx->hdim.placement_size_prehalving_px + 1) * 2 + (scale_ctx->vdim.placement_size_prehalving_px + 1) * 2) * sizeof (uint16_t), &scale_ctx->precalc_storage); scale_ctx->vdim.precalc = ((uint16_t *) scale_ctx->hdim.precalc) + (scale_ctx->hdim.placement_size_prehalving_px + 1) * 2; get_implementations (scale_ctx, color_pixel, color_pixel_type); } static void smol_scale_finalize (SmolScaleCtx *scale_ctx) { free (scale_ctx->precalc_storage); } /* ---------- * * Public API * * ---------- */ SmolScaleCtx * smol_scale_new_simple (const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width, uint32_t src_height, uint32_t src_rowstride, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width, uint32_t dest_height, uint32_t dest_rowstride, SmolFlags flags) { SmolScaleCtx *scale_ctx; scale_ctx = calloc (1,sizeof (SmolScaleCtx)); smol_scale_init (scale_ctx, src_pixels, src_pixel_type, SMOL_PX_TO_SPX (src_width), SMOL_PX_TO_SPX (src_height), src_rowstride, NULL, 0, dest_pixels, dest_pixel_type, SMOL_PX_TO_SPX (dest_width), SMOL_PX_TO_SPX (dest_height), dest_rowstride, 0, 0, SMOL_PX_TO_SPX (dest_width), SMOL_PX_TO_SPX (dest_height), SMOL_COMPOSITE_SRC, flags, NULL, NULL); return scale_ctx; } void smol_scale_simple (const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width, uint32_t src_height, uint32_t src_rowstride, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width, uint32_t dest_height, uint32_t dest_rowstride, SmolFlags flags) { SmolScaleCtx scale_ctx = { 0 }; int first_row, n_rows; smol_scale_init (&scale_ctx, src_pixels, src_pixel_type, SMOL_PX_TO_SPX (src_width), SMOL_PX_TO_SPX (src_height), src_rowstride, NULL, 0, dest_pixels, dest_pixel_type, SMOL_PX_TO_SPX (dest_width), SMOL_PX_TO_SPX (dest_height), dest_rowstride, 0, 0, SMOL_PX_TO_SPX (dest_width), SMOL_PX_TO_SPX (dest_height), SMOL_COMPOSITE_SRC, flags, NULL, NULL); first_row = 0; n_rows = scale_ctx.vdim.dest_size_px; if (check_row_range (&scale_ctx, &first_row, &n_rows)) { do_rows (&scale_ctx, dest_row_ofs_to_pointer (&scale_ctx, 0), first_row, n_rows); } smol_scale_finalize (&scale_ctx); } SmolScaleCtx * smol_scale_new_full (const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width, uint32_t src_height, uint32_t src_rowstride, const void *color_pixel, SmolPixelType color_pixel_type, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width, uint32_t dest_height, uint32_t dest_rowstride, int32_t placement_x, int32_t placement_y, uint32_t placement_width, uint32_t placement_height, SmolCompositeOp composite_op, SmolFlags flags, SmolPostRowFunc post_row_func, void *user_data) { SmolScaleCtx *scale_ctx; scale_ctx = calloc (1, sizeof (SmolScaleCtx)); smol_scale_init (scale_ctx, src_pixels, src_pixel_type, SMOL_PX_TO_SPX (src_width), SMOL_PX_TO_SPX (src_height), src_rowstride, color_pixel, color_pixel_type, dest_pixels, dest_pixel_type, SMOL_PX_TO_SPX (dest_width), SMOL_PX_TO_SPX (dest_height), dest_rowstride, placement_x, placement_y, placement_width, placement_height, composite_op, flags, post_row_func, user_data); return scale_ctx; } void smol_scale_destroy (SmolScaleCtx *scale_ctx) { smol_scale_finalize (scale_ctx); free (scale_ctx); } void smol_scale_batch (const SmolScaleCtx *scale_ctx, int32_t first_dest_row, int32_t n_dest_rows) { if (!check_row_range (scale_ctx, &first_dest_row, &n_dest_rows)) return; do_rows (scale_ctx, dest_row_ofs_to_pointer (scale_ctx, first_dest_row), first_dest_row, n_dest_rows); } void smol_scale_batch_full (const SmolScaleCtx *scale_ctx, void *dest, int32_t first_dest_row, int32_t n_dest_rows) { if (!check_row_range (scale_ctx, &first_dest_row, &n_dest_rows)) return; do_rows (scale_ctx, dest, first_dest_row, n_dest_rows); } chafa-1.18.2/chafa/internal/smolscale/smolscale.h000066400000000000000000000117011517447374300216570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright © 2019-2025 Hans Petter Jansson. See COPYING for details. */ #include #ifndef _SMOLSCALE_H_ #define _SMOLSCALE_H_ #ifdef __cplusplus extern "C" { #endif #define SMOL_SUBPIXEL_SHIFT 8 #define SMOL_SUBPIXEL_MUL (1 << (SMOL_SUBPIXEL_SHIFT)) /* Applies modulo twice, yielding a positive fraction for negative offsets */ #define SMOL_SUBPIXEL_MOD(n) ((((n) % SMOL_SUBPIXEL_MUL) + SMOL_SUBPIXEL_MUL) % SMOL_SUBPIXEL_MUL) #define SMOL_PX_TO_SPX(px) ((px) * (SMOL_SUBPIXEL_MUL)) #define SMOL_SPX_TO_PX(spx) (((spx) + (SMOL_SUBPIXEL_MUL) - 1) / (SMOL_SUBPIXEL_MUL)) typedef enum { SMOL_NO_FLAGS = 0, SMOL_DISABLE_ACCELERATION = (1 << 0), SMOL_DISABLE_SRGB_LINEARIZATION = (1 << 1) } SmolFlags; typedef enum { /* 32 bits per pixel */ SMOL_PIXEL_RGBA8_PREMULTIPLIED, SMOL_PIXEL_BGRA8_PREMULTIPLIED, SMOL_PIXEL_ARGB8_PREMULTIPLIED, SMOL_PIXEL_ABGR8_PREMULTIPLIED, SMOL_PIXEL_RGBA8_UNASSOCIATED, SMOL_PIXEL_BGRA8_UNASSOCIATED, SMOL_PIXEL_ARGB8_UNASSOCIATED, SMOL_PIXEL_ABGR8_UNASSOCIATED, /* 24 bits per pixel */ SMOL_PIXEL_RGB8, SMOL_PIXEL_BGR8, SMOL_PIXEL_MAX } SmolPixelType; typedef enum { SMOL_COMPOSITE_SRC, SMOL_COMPOSITE_SRC_CLEAR_DEST, SMOL_COMPOSITE_SRC_OVER_DEST } SmolCompositeOp; typedef void (SmolPostRowFunc) (void *row_inout, int width, void *user_data); typedef struct SmolScaleCtx SmolScaleCtx; /* Simple API: Scales an entire image in one shot. You must provide pointers to * the source memory and an existing allocation to receive the output data. * This interface can only be used from a single thread. */ void smol_scale_simple (const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width, uint32_t src_height, uint32_t src_rowstride, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width, uint32_t dest_height, uint32_t dest_rowstride, SmolFlags flags); /* Batch API: Allows scaling a few rows at a time. Suitable for multithreading. */ SmolScaleCtx *smol_scale_new_simple (const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width, uint32_t src_height, uint32_t src_rowstride, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width, uint32_t dest_height, uint32_t dest_rowstride, SmolFlags flags); SmolScaleCtx *smol_scale_new_full (const void *src_pixels, SmolPixelType src_pixel_type, uint32_t src_width, uint32_t src_height, uint32_t src_rowstride, const void *color_pixel, SmolPixelType color_pixel_type, void *dest_pixels, SmolPixelType dest_pixel_type, uint32_t dest_width, uint32_t dest_height, uint32_t dest_rowstride, int32_t placement_x, int32_t placement_y, uint32_t placement_width, uint32_t placement_height, SmolCompositeOp composite_op, SmolFlags flags, SmolPostRowFunc post_row_func, void *user_data); void smol_scale_destroy (SmolScaleCtx *scale_ctx); /* It's ok to call smol_scale_batch() without locking from multiple concurrent * threads, as long as the outrows do not overlap. Make sure all workers are * finished before you call smol_scale_destroy(). */ void smol_scale_batch (const SmolScaleCtx *scale_ctx, int32_t first_outrow, int32_t n_outrows); /* Like smol_scale_batch(), but will write the output rows to outrows_dest * instead of relative to pixels_out address handed to smol_scale_new(). The * other parameters from init (size, rowstride, etc) will still be used. */ void smol_scale_batch_full (const SmolScaleCtx *scale_ctx, void *outrows_dest, int32_t first_outrow, int32_t n_outrows); #ifdef __cplusplus } #endif #endif chafa-1.18.2/configure.ac000066400000000000000000000573651517447374300151720ustar00rootroot00000000000000dnl ---------------------------- dnl Automake/autoconf input file dnl ---------------------------- dnl --- Package configuration --- m4_define([chafa_major_version], [1]) m4_define([chafa_minor_version], [18]) m4_define([chafa_micro_version], [2]) m4_define([chafa_version], [chafa_major_version.chafa_minor_version.chafa_micro_version]) AC_PREREQ([2.69]) AC_INIT([chafa],[chafa_version],[hpj@hpjansson.org]) AM_INIT_AUTOMAKE([1.9 foreign dist-xz no-dist-gzip -Wall]) AC_CONFIG_SRCDIR([chafa.pc.in]) AC_CONFIG_MACRO_DIRS([m4]) AC_CONFIG_HEADERS(config.h) CHAFA_MAJOR_VERSION=chafa_major_version CHAFA_MINOR_VERSION=chafa_minor_version CHAFA_MICRO_VERSION=chafa_micro_version CHAFA_VERSION=chafa_version AC_SUBST(CHAFA_MAJOR_VERSION) AC_SUBST(CHAFA_MINOR_VERSION) AC_SUBST(CHAFA_MICRO_VERSION) AC_SUBST(CHAFA_VERSION) AC_DEFINE(CHAFA_MAJOR_VERSION, [chafa_major_version], [Chafa major version]) AC_DEFINE(CHAFA_MINOR_VERSION, [chafa_minor_version], [Chafa minor version]) AC_DEFINE(CHAFA_MICRO_VERSION, [chafa_micro_version], [Chafa micro version]) AC_DEFINE_UNQUOTED(CHAFA_VERSION, "$CHAFA_VERSION", [Package version string]) dnl --- Standard setup --- BASE_CFLAGS="-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_58 \ -Wall -Wextra \ -Wcast-qual \ -Wdisabled-optimization \ -Wmissing-prototypes \ -Wpointer-arith \ -Wshadow \ -Wstrict-overflow=2 \ -Wundef \ -Wunused-macros \ -Wwrite-strings \ -Werror=format-security" # More potential warnings: # # -Wconversion # -Wsign-conversion # This can cause the build to stop, but there may be local modifications # like distro patches etc. that are useful but not strictly conformant. Let's # be nice and spare any innocent bystanders. if test "x$CHAFA_MAINTAINER" != "x"; then BASE_CFLAGS="-std=c99 $BASE_CFLAGS" fi AC_USE_SYSTEM_EXTENSIONS AM_SANITY_CHECK AM_MAINTAINER_MODE AC_C_CONST AC_PROG_CC AC_PROG_CPP AC_PROG_INSTALL AM_PROG_AR # We keep this obsolete macro around to allow configuration on older systems # that require -std=c99, cf. CentOS 7. See github#113. AC_PROG_CC_STDC LT_INIT([win32-dll]) dnl --- Check for extra compiler warnings --- AX_CHECK_COMPILE_FLAG([-Wc11-c2x-compat],[BASE_CFLAGS="$BASE_CFLAGS -Wc11-c2x-compat"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wc99-c11-compat],[BASE_CFLAGS="$BASE_CFLAGS -Wc99-c11-compat"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wfor-loop-analysis],[BASE_CFLAGS="$BASE_CFLAGS -Wfor-loop-analysis"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wlogical-op],[BASE_CFLAGS="$BASE_CFLAGS -Wlogical-op"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wlogical-op-parentheses],[BASE_CFLAGS="$BASE_CFLAGS -Wlogical-op-parentheses"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wstack-usage=131072],[BASE_CFLAGS="$BASE_CFLAGS -Wstack-usage=131072"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wtrampolines],[BASE_CFLAGS="$BASE_CFLAGS -Wtrampolines"],,[-Werror]) AX_CHECK_COMPILE_FLAG([-Wdouble-promotion],[BASE_CFLAGS="$BASE_CFLAGS -Wdouble-promotion"],,[-Werror]) dnl --- Required standards --- dnl POSIX.1-2008 is required to get SA_RESETHAND. We should get this by default dnl on most systems, but keep the check around just in case. dnl AC_MSG_CHECKING(for POSIX.1-2008) dnl AC_EGREP_CPP(posix_200809L_supported, dnl [#define _POSIX_C_SOURCE 200809L dnl #include dnl #ifdef _POSIX_VERSION dnl # if _POSIX_VERSION == 200809L dnl posix_200809L_supported dnl # endif dnl #endif dnl ], dnl [AC_MSG_RESULT(yes)], dnl [AC_MSG_RESULT(no) dnl AC_MSG_FAILURE([Implementation must conform to the POSIX.1-2008 standard.])] dnl ) dnl dnl AC_DEFINE([_POSIX_C_SOURCE], [200809L], [Minimum POSIX standard we need]) dnl --- Dependency check --- PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.58) AC_ARG_WITH(tools, [AS_HELP_STRING([--without-tools], [don't build command-line tools [default=on]])], , with_tools=yes) AS_IF([test "$with_tools" != no], [ dnl FreeType (required) PKG_CHECK_MODULES(FREETYPE, [freetype2 >= 2.0.0],, [AC_MSG_ERROR([You need freetype2-devel (or libfreetype6-dev on Debian) to build command-line tools, or pass --without-tools to build without.])]) dnl libavif (optional) AC_ARG_WITH(avif, [AS_HELP_STRING([--without-avif], [don't build AVIF loader [default=on]])], , with_avif=yes) AS_IF([test "$with_avif" != no], [ PKG_CHECK_MODULES(AVIF, [libavif],, missing_rpms="$missing_rpms libavif-devel" missing_debs="$missing_debs libavif-dev" with_avif=no)]) AS_IF([test "$with_avif" != no], [AC_DEFINE([HAVE_AVIF], [1], [Define if we have AVIF support.])]) dnl libheif (optional) AC_ARG_WITH(heif, [AS_HELP_STRING([--without-heif], [don't build HEIF loader [default=on]])], , with_heif=yes) AS_IF([test "$with_heif" != no], [ PKG_CHECK_MODULES(HEIF, [libheif],, missing_rpms="$missing_rpms libheif-devel" missing_debs="$missing_debs libheif-dev" with_heif=no)]) AS_IF([test "$with_heif" != no], [AC_DEFINE([HAVE_HEIF], [1], [Define if we have HEIF support.])]) dnl libjpeg (optional) AC_ARG_WITH(jpeg, [AS_HELP_STRING([--without-jpeg], [don't build JPEG loader [default=on]])], , with_jpeg=yes) AS_IF([test "$with_jpeg" != no], [PKG_CHECK_MODULES(JPEG, [libjpeg],, missing_rpms="$missing_rpms libjpeg-devel" missing_debs="$missing_debs libjpeg-dev" with_jpeg=no)]) AS_IF([test "$with_jpeg" != no], [AC_DEFINE([HAVE_JPEG], [1], [Define if we have JPEG support.])]) dnl librsvg (optional) AC_ARG_WITH(svg, [AS_HELP_STRING([--without-svg], [don't build SVG loader [default=on]])], , with_svg=yes) AS_IF([test "$with_svg" != no], [PKG_CHECK_MODULES(SVG, [librsvg-2.0],, missing_rpms="$missing_rpms librsvg-devel" missing_debs="$missing_debs librsvg2-dev" with_svg=no)]) AS_IF([test "$with_svg" != no], [AC_DEFINE([HAVE_SVG], [1], [Define if we have SVG support.])]) dnl libtiff (optional) AC_ARG_WITH(tiff, [AS_HELP_STRING([--without-tiff], [don't build TIFF loader [default=on]])], , with_tiff=yes) AS_IF([test "$with_tiff" != no], [PKG_CHECK_MODULES(TIFF, [libtiff-4],, missing_rpms="$missing_rpms libtiff-devel" missing_debs="$missing_debs libtiff-dev" with_tiff=no)]) AS_IF([test "$with_tiff" != no], [AC_DEFINE([HAVE_TIFF], [1], [Define if we have TIFF support.])]) dnl libwebp (optional) AC_ARG_WITH(webp, [AS_HELP_STRING([--without-webp], [don't build WebP loader [default=on]])], , with_webp=yes) AS_IF([test "$with_webp" != no], [ PKG_CHECK_MODULES(WEBP, [libwebp libwebpdemux],, missing_rpms="$missing_rpms libwebp-devel" missing_debs="$missing_debs libwebp-dev" with_webp=no)]) AS_IF([test "$with_webp" != no], [AC_DEFINE([HAVE_WEBP], [1], [Define if we have WebP support.])]) dnl libjxl (optional) AC_ARG_WITH(jxl, [AS_HELP_STRING([--without-jxl], [don't build JXL loader [default=on]])], , with_jxl=yes) AS_IF([test "$with_jxl" != no], [ PKG_CHECK_MODULES(JXL, [libjxl libjxl_threads],, missing_rpms="$missing_rpms libjxl-devel" missing_debs="$missing_debs libjxl-dev" with_jxl=no)]) AS_IF([test "$with_jxl" != no], [AC_DEFINE([HAVE_JXL], [1], [Define if we have JXL support.])]) dnl coregraphics (auto, only macos) AC_ARG_WITH(coregraphics, [AS_HELP_STRING([--without-coregraphics], [don't build CoreGraphics loader [default=auto]])], [], [with_coregraphics=auto]) dnl CoreGraphics detection have_coregraphics=no COREGRAPHICS_LIBS="" case "${host_os}" in darwin*) AS_IF([test "$with_coregraphics" != no], [ AC_CHECK_HEADER([CoreGraphics/CoreGraphics.h], [have_coregraphics=yes], [have_coregraphics=no]) AS_IF([test "$have_coregraphics" = yes], [ AC_CHECK_HEADER([ImageIO/ImageIO.h], [], [have_coregraphics=no]) ]) ]) AS_IF([test "$have_coregraphics" = yes], [ COREGRAPHICS_LIBS="-framework CoreGraphics -framework ImageIO -framework CoreFoundation" AC_DEFINE([HAVE_COREGRAPHICS], [1], [Define if we have CoreGraphics support.]) with_coregraphics=yes ], [ AS_IF([test "$with_coregraphics" = yes], [ AC_MSG_ERROR([CoreGraphics headers not found. Install Xcode Command Line Tools.]) ]) with_coregraphics=no ]) ;; *) if test "$with_coregraphics" = "yes"; then AC_MSG_ERROR([CoreGraphics is available on macOS]) fi ;; esac ]) AC_SUBST(COREGRAPHICS_LIBS) AM_CONDITIONAL([WANT_TOOLS], [test "$with_tools" != no]) AM_CONDITIONAL([HAVE_JPEG], [test "$with_tools" != no -a "$with_jpeg" != no]) AM_CONDITIONAL([HAVE_SVG], [test "$with_tools" != no -a "$with_svg" != no]) AM_CONDITIONAL([HAVE_TIFF], [test "$with_tools" != no -a "$with_tiff" != no]) AM_CONDITIONAL([HAVE_WEBP], [test "$with_tools" != no -a "$with_webp" != no]) AM_CONDITIONAL([HAVE_AVIF], [test "$with_tools" != no -a "$with_avif" != no]) AM_CONDITIONAL([HAVE_HEIF], [test "$with_tools" != no -a "$with_heif" != no]) AM_CONDITIONAL([HAVE_JXL], [test "$with_tools" != no -a "$with_jxl" != no]) AM_CONDITIONAL([HAVE_COREGRAPHICS], [test "$with_tools" != no -a "$have_coregraphics" = yes]) # Used by gtk-doc's fixxref. GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`" AC_SUBST(GLIB_PREFIX) dnl --- Documentation --- # gtkdocize greps for ^GTK_DOC_CHECK and parses it, so you need to have # it on its own line. m4_ifdef([GTK_DOC_CHECK], [ GTK_DOC_CHECK([1.20], [--flavour no-tmpl]) ],[ AM_CONDITIONAL([ENABLE_GTK_DOC],[false]) ]) AC_ARG_ENABLE(man, [AS_HELP_STRING([--enable-man], [generate man pages [default=auto]])],, enable_man=maybe) AS_IF([test "$enable_man" != no], [ AC_PATH_PROG([XSLTPROC], [xsltproc]) AS_IF([test -z "$XSLTPROC"], [ AS_IF([test "$enable_man" = yes], [ AC_MSG_ERROR([xsltproc is required for --enable-man]) ]) enable_man=no ]) ]) AS_IF([ test "$enable_man" != no ], [ dnl check for DocBook DTD in the local catalog JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN], [DocBook XML DTD V4.1.2], [have_docbook_dtd=yes], [have_docbook_dtd=no]) AS_IF([test "$have_docbook_dtd" != yes], [ AS_IF([test "$enable_man" = yes ], [ AC_MSG_ERROR([DocBook DTD is required for --enable-man]) ]) enable_man=no ]) ]) AS_IF([test "$enable_man" != no], [ dnl check for DocBook XSL stylesheets in the local catalog JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl], [DocBook XSL Stylesheets], [have_docbook_style=yes],[have_docbook_style=no]) AS_IF([ test "$have_docbook_style" != yes ], [ AS_IF([ test "$enable_man" = yes ], [ AC_MSG_ERROR([DocBook XSL Stylesheets are required for --enable-man]) ]) enable_man=no ]) ]) AM_CONDITIONAL(ENABLE_MAN, test "$enable_man" != no) AC_MSG_CHECKING([whether to generate man pages]) AS_IF([ test "$enable_man" != no ], [ enable_man=yes AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) dnl --- Specific checks --- AC_CHECK_FUNCS(ctermid getrandom mmap sigaction setitimer) AC_CHECK_HEADERS(sys/time.h sys/ioctl.h termios.h windows.h) dnl dnl Define IS_WIN32_BUILD if we're building for Microsoft Windows. In order to dnl get UTF-8 support in command-line arguments and environment vars, we need dnl to build a resource file with windres and link it in. dnl is_windows_build=no case "${host_os}" in cygwin*|mingw*) is_windows_build=yes ;; esac AM_CONDITIONAL([IS_WIN32_BUILD], [test "x$is_windows_build" = "xyes"]) AC_CHECK_TOOL([WINDRES], [windres], [:]) dnl dnl Check for -Bsymbolic-functions linker flag used to avoid dnl intra-library PLT jumps, if available. dnl AC_ARG_ENABLE(Bsymbolic, [AS_HELP_STRING([--disable-Bsymbolic], [avoid linking with -Bsymbolic])],, [SAVED_LDFLAGS="${LDFLAGS}" SAVED_LIBS="${LIBS}" AC_MSG_CHECKING([for -Bsymbolic linker flag]) LDFLAGS=-Wl,-Bsymbolic LIBS= AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[return 0]])],[AC_MSG_RESULT(yes) enable_Bsymbolic=yes],[AC_MSG_RESULT(no) enable_Bsymbolic=no]) LDFLAGS="${SAVED_LDFLAGS}" LIBS="${SAVED_LIBS}"]) if test "x${enable_Bsymbolic}" = "xyes"; then CHAFA_BDYNAMIC_FLAGS=-Wl,-Bsymbolic fi dnl dnl Check for runtime gcc x86 instruction set detection. Used in 'chafa-features.c'. dnl AC_CACHE_CHECK([for gcc __builtin_cpu_init function], [ax_cv_gcc_check_x86_cpu_init], [AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [__builtin_cpu_init ();])], [ax_cv_gcc_check_x86_cpu_init=yes], [ax_cv_gcc_check_x86_cpu_init=no])]) AC_CACHE_CHECK([for gcc __builtin_cpu_supports function], [ax_cv_gcc_check_x86_cpu_supports], [AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [__builtin_cpu_supports ("mmx");])], [ax_cv_gcc_check_x86_cpu_supports=yes], [ax_cv_gcc_check_x86_cpu_supports=no])]) dnl AM_CONDITIONAL([HAVE_GCC_X86_FEATURE_BUILTINS], [test "$ac_cv_gcc_check_x86_cpu_init" = "yes" && test "$ac_cv_gcc_check_x86_cpu_supports" = "yes"]) AS_IF([test "$ax_cv_gcc_check_x86_cpu_init" = "yes" && test "$ax_cv_gcc_check_x86_cpu_supports" = "yes"], [ AC_DEFINE([HAVE_GCC_X86_FEATURE_BUILTINS], [1], [Define if gcc x86 feature builtins work.]) ]) dnl dnl Check for other builtins dnl dnl __builtin_assume_aligned is not available in older GCC releases. This is dnl used by Smolscale. AC_CACHE_CHECK([for gcc __builtin_assume_aligned function], [ax_cv_gcc_check_builtin_assume_aligned], [AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include ], [int *x; x = __builtin_assume_aligned (x, 4);])], [ax_cv_gcc_check_builtin_assume_aligned=yes], [ax_cv_gcc_check_builtin_assume_aligned=no])]) AM_CONDITIONAL([HAVE_BUILTIN_ASSUME_ALIGNED], [test "$ax_cv_gcc_check_builtin_assume_aligned" = "yes"]) dnl Check for working MMX intrinsics AC_MSG_CHECKING(for working MMX intrinsics) SAVED_CFLAGS="${CFLAGS}" CFLAGS="-mmmx ${CFLAGS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[__m64 t [2] = { 0 }; t [0] = _mm_setzero_si64 ();]])], [AC_DEFINE([HAVE_MMX_INTRINSICS], [1], [Define if MMX intrinsics work.]) ac_cv_mmx_intrinsics=yes], [ac_cv_mmx_intrinsics=no]) CFLAGS="${SAVED_CFLAGS}" AC_MSG_RESULT(${ac_cv_mmx_intrinsics}) AM_CONDITIONAL([HAVE_MMX_INTRINSICS], [test "$ac_cv_mmx_intrinsics" = "yes"]) dnl Check for working SSE intrinsics AC_MSG_CHECKING(for working SSE 4.1 intrinsics) SAVED_CFLAGS="${CFLAGS}" CFLAGS="-msse4.1 ${CFLAGS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[__m128i t = { 0 }; int r = _mm_test_all_ones (t);]])], [AC_DEFINE([HAVE_SSE41_INTRINSICS], [1], [Define if SSE 4.1 intrinsics work.]) ac_cv_sse41_intrinsics=yes], [ac_cv_sse41_intrinsics=no]) CFLAGS="${SAVED_CFLAGS}" AC_MSG_RESULT(${ac_cv_sse41_intrinsics}) AM_CONDITIONAL([HAVE_SSE41_INTRINSICS], [test "$ac_cv_sse41_intrinsics" = "yes"]) dnl Check for working AVX2 intrinsics AC_MSG_CHECKING(for working AVX2 intrinsics) SAVED_CFLAGS="${CFLAGS}" CFLAGS="-mavx2 ${CFLAGS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include ]], [[__m256i t = { 0 }; __m256i r = _mm256_abs_epi32 (t);]])], [AC_DEFINE([HAVE_AVX2_INTRINSICS], [1], [Define if AVX2 intrinsics work.]) ac_cv_avx2_intrinsics=yes], [ac_cv_avx2_intrinsics=no]) CFLAGS="${SAVED_CFLAGS}" AC_MSG_RESULT(${ac_cv_avx2_intrinsics}) AM_CONDITIONAL([HAVE_AVX2_INTRINSICS], [test "$ac_cv_avx2_intrinsics" = "yes"]) dnl Check for working 64bit popcnt intrinsics AC_MSG_CHECKING(for working 64bit popcnt intrinsics) SAVED_CFLAGS="${CFLAGS}" CFLAGS="-mpopcnt ${CFLAGS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include #include ]], [[uint64_t t = 0; t = _mm_popcnt_u64 (t);]])], [AC_DEFINE([HAVE_POPCNT64_INTRINSICS], [1], [Define if 64bit popcnt intrinsics work.]) ac_cv_popcnt64_intrinsics=yes], [ac_cv_popcnt64_intrinsics=no]) CFLAGS="${SAVED_CFLAGS}" AC_MSG_RESULT(${ac_cv_popcnt64_intrinsics}) dnl Check for working 32bit popcnt intrinsics AC_MSG_CHECKING(for working 32bit popcnt intrinsics) SAVED_CFLAGS="${CFLAGS}" CFLAGS="-mpopcnt ${CFLAGS}" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include #include ]], [[uint32_t t = 0; t = _mm_popcnt_u32 (t);]])], [AC_DEFINE([HAVE_POPCNT32_INTRINSICS], [1], [Define if 32bit popcnt intrinsics work.]) ac_cv_popcnt32_intrinsics=yes], [ac_cv_popcnt32_intrinsics=no]) CFLAGS="${SAVED_CFLAGS}" AC_MSG_RESULT(${ac_cv_popcnt32_intrinsics}) AM_CONDITIONAL([HAVE_POPCNT_INTRINSICS], [test "$ac_cv_popcnt64_intrinsics" = "yes" -o "$ac_cv_popcnt32_intrinsics" = "yes"]) dnl dnl Check for -fvisibility=hidden to determine if we can do GNU-style dnl visibility attributes for symbol export control dnl CHAFA_VISIBILITY_CFLAGS="" case "$host" in *-*-mingw*) dnl On mingw32 we do -fvisibility=hidden and __declspec(dllexport) AC_DEFINE([_CHAFA_EXTERN], [__attribute__((visibility("default"))) __declspec(dllexport) extern], [Defines how to decorate public symbols while building]) CHAFA_VISIBILITY_CFLAGS="-fvisibility=hidden" ;; *) dnl On other compilers, check if we can do -fvisibility=hidden SAVED_CFLAGS="${CFLAGS}" CFLAGS="-fvisibility=hidden" AC_MSG_CHECKING([for -fvisibility=hidden compiler flag]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[return 0]])],[AC_MSG_RESULT(yes) enable_fvisibility_hidden=yes],[AC_MSG_RESULT(no) enable_fvisibility_hidden=no]) CFLAGS="${SAVED_CFLAGS}" AS_IF([test "${enable_fvisibility_hidden}" = "yes"], [ AC_DEFINE([_CHAFA_EXTERN], [__attribute__((visibility("default"))) extern], [Defines how to decorate public symbols while building]) CHAFA_VISIBILITY_CFLAGS="-fvisibility=hidden" ]) ;; esac dnl dnl We're not picky about floating point behavior, and this makes e.g. dnl lrintf() a lot faster. dnl AX_CHECK_COMPILE_FLAG([-ffast-math], [BASE_CFLAGS="$BASE_CFLAGS -ffast-math"], , [-Werror]) dnl --- Set compiler flags --- dnl Disable some LodePNG features. In particular, the CRC feature, which would dnl sometimes cause valid images to not load because of issues in the dnl encoding software. LODEPNG_FEATURES="\ -DLODEPNG_NO_COMPILE_ENCODER \ -DLODEPNG_NO_COMPILE_DISK \ -DLODEPNG_NO_COMPILE_CPP \ -DLODEPNG_NO_COMPILE_CRC" LODEPNG_CFLAGS="$BASE_CFLAGS $LODEPNG_FEATURES" LODEPNG_LDFLAGS="$CHAFA_BDYNAMIC_FLAGS" LIBNSGIF_CFLAGS="$BASE_CFLAGS" LIBNSGIF_LDFLAGS="$CHAFA_BDYNAMIC_FLAGS" LIBCHAFA_CFLAGS="$BASE_CFLAGS $CHAFA_VISIBILITY_CFLAGS" LIBCHAFA_LDFLAGS="$CHAFA_BDYNAMIC_FLAGS" CHAFA_CFLAGS="$BASE_CFLAGS $CHAFA_VISIBILITY_CFLAGS $LODEPNG_FEATURES" CHAFA_LDFLAGS="$CHAFA_BDYNAMIC_FLAGS" AC_SUBST(LODEPNG_CFLAGS) AC_SUBST(LODEPNG_LDFLAGS) AC_SUBST(LIBNSGIF_CFLAGS) AC_SUBST(LIBNSGIF_LDFLAGS) AC_SUBST(LIBCHAFA_CFLAGS) AC_SUBST(LIBCHAFA_LDFLAGS) AC_SUBST(CHAFA_CFLAGS) AC_SUBST(CHAFA_LDFLAGS) AC_ARG_ENABLE(rpath, [AS_HELP_STRING([--enable-rpath], [use rpath [default=no]])]) AM_CONDITIONAL(ENABLE_RPATH, test "$enable_rpath" = yes) dnl --- Output --- AC_CONFIG_FILES([Makefile chafa/Makefile chafa/chafaconfig.h chafa/internal/Makefile chafa/internal/smolscale/Makefile libnsgif/Makefile lodepng/Makefile chafa.pc docs/Makefile docs/version.xml examples/Makefile tests/Makefile tests/data/Makefile tests/data/bad/Makefile tests/data/good/Makefile tools/Makefile tools/chafa/Makefile tools/completions/Makefile tools/fontgen/Makefile]) AC_OUTPUT dnl --- Print a neatly colorized summary --- colorize_vars=" enable_man ac_cv_mmx_intrinsics ac_cv_sse41_intrinsics ac_cv_avx2_intrinsics ac_cv_popcnt32_intrinsics ac_cv_popcnt64_intrinsics with_tools with_jpeg with_svg with_tiff with_webp with_jxl with_avif with_heif have_coregraphics " dnl Only use colors if the terminal supports the aixterm-style bright ones (16 total). cols=$(tput colors 2>/dev/null) if test ${cols:--1} -ge 16; then normal=$(tput sgr0) red=$(tput setaf 9) green=$(tput setaf 10) yellow=$(tput setaf 11) blue=$(tput setaf 12) pyes=${green}yes${normal} pno=${red}no${normal} pyno=${yellow}no${normal} else normal= red= green= yellow= blue= pyes=yes pno=no pyno=no fi dnl Gross. At least make sure eval arguments are sanitized. for i in $colorize_vars; do eval state=\$$i if test x$state != xno; then state=yes; fi eval p$i=\$p$state done dnl gtk-doc needs special handling; since docs come pregenerated in the tarball, "no" dnl here is less critical, so use a different color. Also, enable_gtk_doc can be empty. if test x$enable_gtk_doc = xyes; then penable_gtk_doc=$pyes else penable_gtk_doc=$pyno fi echo >&AS_MESSAGE_FD $normal echo >&AS_MESSAGE_FD "Build man page .............. $penable_man" echo >&AS_MESSAGE_FD "Rebuild API documentation ... $penable_gtk_doc (--enable-gtk-doc)" echo >&AS_MESSAGE_FD "Support MMX ................. $pac_cv_mmx_intrinsics" echo >&AS_MESSAGE_FD "Support SSE 4.1 ............. $pac_cv_sse41_intrinsics" echo >&AS_MESSAGE_FD "Support AVX2 ................ $pac_cv_avx2_intrinsics" echo >&AS_MESSAGE_FD "Support popcount32 .......... $pac_cv_popcnt32_intrinsics" echo >&AS_MESSAGE_FD "Support popcount64 .......... $pac_cv_popcnt64_intrinsics" echo >&AS_MESSAGE_FD echo >&AS_MESSAGE_FD "Build command-line tool ..... $pwith_tools" if test "x$with_tools" != xno; then echo >&AS_MESSAGE_FD "With AVIF loader ............ $pwith_avif" echo >&AS_MESSAGE_FD "With GIF loader ............. $pyes (internal)" echo >&AS_MESSAGE_FD "With HEIF loader ............ $pwith_heif" echo >&AS_MESSAGE_FD "With JPEG loader ............ $pwith_jpeg" echo >&AS_MESSAGE_FD "With PNG loader ............. $pyes (internal)" echo >&AS_MESSAGE_FD "With QOI loader ............. $pyes (internal)" echo >&AS_MESSAGE_FD "With SVG loader ............. $pwith_svg" echo >&AS_MESSAGE_FD "With TIFF loader ............ $pwith_tiff" echo >&AS_MESSAGE_FD "With WebP loader ............ $pwith_webp" echo >&AS_MESSAGE_FD "With JXL loader ............. $pwith_jxl" echo >&AS_MESSAGE_FD "With XWD loader ............. $pyes (internal)" echo >&AS_MESSAGE_FD "With CoreGraphics loader .... $phave_coregraphics" fi echo >&AS_MESSAGE_FD echo >&AS_MESSAGE_FD "Install prefix .............. $blue$prefix$normal" echo >&AS_MESSAGE_FD echo >&AS_MESSAGE_FD "You can now type ${blue}gmake${normal} or ${blue}make${normal} to build the project." dnl --- Warn about missing dependencies --- dnl Remove leading spaces. missing_rpms=$(echo $missing_rpms | sed 's/^ *//') missing_debs=$(echo $missing_debs | sed 's/^ *//') if test "x$missing_rpms" != x; then echo >&AS_MESSAGE_FD echo >&AS_MESSAGE_FD "Some optional libraries were not found. You may want to install these and" echo >&AS_MESSAGE_FD "run configure again (package names may be different on your system)." echo >&AS_MESSAGE_FD echo >&AS_MESSAGE_FD "On Fedora, openSUSE or similar:" echo >&AS_MESSAGE_FD "${blue}${missing_rpms}${normal}" echo >&AS_MESSAGE_FD echo >&AS_MESSAGE_FD "On Debian, Ubuntu or similar:" echo >&AS_MESSAGE_FD "${blue}${missing_debs}${normal}" echo >&AS_MESSAGE_FD fi chafa-1.18.2/docs/000077500000000000000000000000001517447374300136145ustar00rootroot00000000000000chafa-1.18.2/docs/.gitignore000066400000000000000000000004601517447374300156040ustar00rootroot00000000000000/chafa-decl-list.txt /chafa-decl.txt /chafa-overrides.txt /chafa-undeclared.txt /chafa-undocumented.txt /chafa-unused.txt /chafa.1 /chafa.actions /chafa.args /chafa.hierarchy /chafa.html /chafa.interfaces /chafa.prerequisites /chafa.proc /chafa.signals /docbook.xsl /html /refentry.xsl /version.xml /xml chafa-1.18.2/docs/Makefile.am000066400000000000000000000050511517447374300156510ustar00rootroot00000000000000## Process this file with automake to produce Makefile.in AUTOMAKE_OPTIONS = 1.6 # The name of the module. DOC_MODULE=chafa # The top-level SGML file. DOC_MAIN_SGML_FILE=chafa-docs.xml content_files = \ building.xml \ using.xml # The directory containing the source code. Relative to $(srcdir) DOC_SOURCE_DIR = $(top_srcdir)/chafa # Extra options to supply to gtkdoc-scan SCAN_OPTIONS=--deprecated-guards="G_DISABLE_DEPRECATED" --ignore-decorators="GLIB_VAR|G_GNUC_WARN_UNUSED_RESULT" # Used for dependencies HFILE_GLOB = $(top_srcdir)/chafa/chafa-*.h CFILE_GLOB = $(top_srcdir)/chafa/chafa-*.c # Ignore some private headers IGNORE_HFILES = \ chafa.h \ chafa-private.h \ chafa-term-seq-doc-in.h \ named-colors.h # Extra options to supply to gtkdoc-mkdb MKDB_OPTIONS=--output-format=xml --name-space=chafa FIXXREF_OPTIONS=--extra-dir=$(GLIB_PREFIX)/share/gtk-doc/html/glib # Images to copy into HTML directory HTML_IMAGES = # include common portion ... include $(top_srcdir)/gtk-doc.make # Other files to distribute EXTRA_DIST += \ version.xml.in \ style.css ######################################################################## man_MANS = manhtml = if ENABLE_MAN man_MANS += \ chafa.1 manhtml += chafa.html all-local: $(manhtml) XSLTPROC_FLAGS = \ --nonet \ --stringparam man.output.quietly 1 \ --stringparam funcsynopsis.style ansi \ --stringparam man.th.extra1.suppress 1 \ --stringparam man.authors.section.enabled 0 \ --stringparam man.copyright.section.enabled 0 \ --stringparam root.filename chafa \ --stringparam html.stylesheet manpage.css .xml.1: $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $< chafa.html: $(srcdir)/chafa.xml $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/html/onechunk.xsl $< dist-local-check-mans-enabled: if grep "Man generation disabled" $(man_MANS) >/dev/null; then $(RM) $(man_MANS); fi else $(man_MANS) chafa.html: echo Man generation disabled. Creating dummy $@. Configure with --enable-man to enable it. echo Man generation disabled. Remove this file, configure with --enable-man, and rebuild > $@ dist-local-check-mans-enabled: echo "*** --enable-man must be used in order to make dist" false endif CLEANFILES ?= CLEANFILES += $(man_MANS) $(manhtml) EXTRA_DIST += chafa.xml $(man_MANS) $(manhtml) manpage.css dist-hook-local: dist-local-check-mans-enabled all-local chafa-docs-clean: clean cd $(srcdir) && rm -rf xml html chafa-1.18.2/docs/building.xml000066400000000000000000000111311517447374300161300ustar00rootroot00000000000000 Compiling the Chafa package 3 Chafa Library Compiling the Chafa Package How to compile Chafa itself Building from the Git repository When building from a clean Git repository, the build files must be prepared before anything else happens. The repository includes a shell script for this: ./autogen.sh Afterwards the build can proceed like it would from a source package. Building from a source package Chafa uses a typical build system provided by autoconf, automake and libtool. You can build and install Chafa like this: ./configure make make install The standard options provided by GNU autoconf may be passed to the configure script. Please see the autoconf documentation or run ./configure --help for information about the standard options. Dependencies Chafa depends on the GLib library. If you want to build the chafa command-line tool in addition to the libchafa library, you will also need the FreeType library and its development files. chafa has built-in support for the GIF, PNG, QOI and XWD formats, and can be built with optional support for many others, including AVIF, JPEG, SVG, TIFF and WebP. ./configure will summarize the build features. Extra Configuration Options In addition to the normal options, the configure script supports these additional arguments: <systemitem>--disable-Bsymbolic</systemitem> and <systemitem>--enable-Bsymbolic</systemitem> By default, Chafa uses the -Bsymbolic-functions linker flag to avoid intra-library PLT jumps. A side-effect of this is that it is no longer possible to override internal uses of Chafa functions with LD_PRELOAD. Therefore, it may make sense to turn this feature off in some situations. The option allows you to do that. <systemitem>--disable-gtk-doc</systemitem> and <systemitem>--enable-gtk-doc</systemitem> By default the configure script will try to auto-detect whether the gtk-doc package is installed. If it is, then it will use it to extract and build the documentation for the Chafa library. These options can be used to explicitly control whether gtk-doc should be used or not. If it is not used, the distributed, pre-generated HTML files will be installed instead of building them on your machine. <systemitem>--disable-man</systemitem> and <systemitem>--enable-man</systemitem> By default the configure script will try to auto-detect whether xsltproc and the necessary Docbook stylesheets are installed. If they are, then it will use them to rebuild the included man pages from the XML sources. These options can be used to explicitly control whether man pages should be rebuilt or not. The distribution includes pre-generated man pages. chafa-1.18.2/docs/chafa-docs.xml000066400000000000000000000063171517447374300163350ustar00rootroot00000000000000 %gtkdocentities; ]> Chafa Reference Manual For Chafa version &version;. The latest version of this documentation can be found online at https://hpjansson.org/&package_name;/ref/. Overview Chafa C API API Index Index of new API in version 1.2 Index of new API in version 1.4 Index of new API in version 1.6 Index of new API in version 1.8 Index of new API in version 1.10 Index of new API in version 1.12 Index of new API in version 1.14 Index of new API in version 1.16 Index of new API in version 1.18 Index of deprecated API chafa-1.18.2/docs/chafa-logo.gif000066400000000000000000037150611517447374300163200ustar00rootroot00000000000000GIF89aè6÷úüùéééTwÞDq³æêö KpoÙßø™ªñ#±3My“ñCiÞŒB_áJûúñô÷㥴ë!0oöøÕ,@r” LXàHiÖ4L0Y}ÐGo0,+«5OMqŒ¿öùü1Ò à4<Ú:V)&6òómóô˜Ñðò�NwøºJo>”°ÒKxç¾ÍïæôçAyßDrPFn.0äO|Ùm–Ü3Hy.'ÌÊôGq�Y„ÉÁÏÞ‡ÒFq¤ÍÑÌõöÃóô°WmøññLÆÑ¦¸��?pÕ#*n9M­A]óãê,O8L‘PbÅ6pgv‹•@GÍ@Nôöø ô3g]f‹ª;qÃBb¶1GÛGmÌ)/�ÏÒŒ5¡‚Š…KZÏÒÕyy”'N0Ò#P]NÍÒ¨¬²¬PoX9UÃ;RvKoÆMj’;�ž§|u{êüò÷ž¬¹+1Md¬exØoqq'Q‹ai�4I¿DPe `bž¤’´.+S(T¤,?&Z·;EFéùöôâõÒó÷Žõø$ ¼÷øúßå=”ŸC!?Ök†ïÂÈò¦´A´Ê‡ÒãL«ßMDsg?^K³µkÕ×|]‘ LhÈ|Š#'Áš¥‡[{@‘ÌWñö8ÓÖ9½ãqÐ.s|KÓãô�§ñp}´z´:ƒÙŽÞ4÷øô²ÞÐu¼I‹wÖ¦Í÷™Ý±0Nw_«7ì^�F-ZB¯Vn÷ÊéöÕò·uÕóNnô9Nè\‘ïl²õ{ÔÔûö%à|äæ©æ�S¤Þ˜ïñÌö_˜‚øÀùõ’øS0[¤o. ?V p$rïMôönøsì¤{ïÐÉôÜPõ‚®ò¼>ð`xî‹,_ÙSâ§ ž3ß0ïZËLóÓEó±ô|ó§ôÛ¦ièQîÁÊgÔ2¥_~1¤ðö´ÃtN5W jLò›8£€ å§Tëÿÿÿ!ÿ NETSCAPE2.0!ù,è6ÿ<à§ Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç� CJ8Ð$Rª\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳ§ÏŸ@ƒ }‰¤¨Ñ£H“*]Ê´©Ó§P‘ÀAã§$œ¡X³jÝʵ«×¯`Ã�J¶¬Ù³Q© D#¶­Û·pãÊ�K7%Ú»xóBECeÝ¿€ LX«ÞÈõê)X¸±ãÇ�#Ë…“¸²å¨ŒU¢Ĺ³çÏŸÙJMº´éº”/«^}4sJAGW˜= ÏJ£‚NëÞÍ»÷ÏÔ¬ƒ[vM6‚ãÈ“+GŽ$·ïçУC.¼º^âÆh` ÿ ±§üñæÒÓ«_ÿ˜ºõêpâ�ï)v$T!€sœ„ ð|Gžyè±g`V‚ø‘“wúV_RS¡ñ jhThá…NM…„„EiÈáRÄ‘€Ÿx{ð÷Ýý�ˆ"H�Ð`tåÅcP” €“w&¼¸Û„FM•҇¡AÛ�œÔT|6Jèãò�¨ J""G{üWž袎¾Yè�…6Æ…#—§ñ([³$kB9›‘L-©&šjò"~Éy7`–汸%™¼å‘‡wµ Úœ!$ˆæ� {¤ä�ˆÂÁ¨ˆŽnùh$\E~´ÑÆ“Œ (i<.I[�Ay¡�pÆI'Išÿy'2*©'Ÿ(¶8ªo¢@€”ê&ÙX^AÇúAl¥9‹ƒÅ«lÌî:Z«HÑ™f’©¶Ê*T¦¢ÚÔ¬2bz%®¹þiíi¢Â±,ËZ[¨$[ï ‚ØÛl½�—c|›V©ïº‘)IßÁ'©ùæ¦ìðÃG ‡øq0ÅKŒ0¬±j<1¨¾â£€˜’<`ºë&ê³2æÛë˜0“°ï̾îa#'ËLoŽ);ÖðÃR\q…Ó·PÑW|±ÒE¿Ú±ÄäŽìéwSËègϦµK,}H˜ð²Î1Ó<&y6’_ØX7ö3ÄBgŒtÒDº­1Æ1­1�ÂZ'Ô Gÿ¹ÇÔN5•W§=š¨-îQa¦;«„öã:“]3Uh>ØÚûQæP»)wçnÚ±„£9ß+ùýwÉ‚“à©––KÖ+§mòä×bƒ­{Ž’ãl»ëÇçô¶Ñ !ÝPÓ§Ó'!ñ§ŽçrÔ3§®ð� À³JC¦¤½l<køä§dB˜œ¯}˜âc_ôÇÇ/ÿükÃ'Z×»¯ÿþ€Íïÿÿœ_ˆVEÀ.ŽLà\6À:ð�Ø‘‘'(A�)ð‚ìJ“ÞÃÁ²'B aÂ2HÂE*fê  �B¼˜ð…0ì ô°Â2…81Ì¡¿òÀúðm8Ü¡ÿ‡˜Ã ñˆHT`f¶ÃÄ&:ñ‰PŒ¢§HÅ*ZñŠXÌ¢·ÈÅ.zñ‹` £ÇHÆ2š‘‹)Yâ×ÈÆ6ºñ�pŒ£çHÇ:Ú1�OÊ⬸GôÑŽ€ÄâIH;²�ˆL¤"™ˆÇ”øñЇÜ&©�=Z²‰‘ä#3)È'rÒ‰³éâ!9I&h²Š¡”b&?‰IVFÑ•ÛIå#)ËEÚò–nl$ùESƲ’ ä"'a9ÅU¢²Œ‘ô%‰ÉLOS˜Ï#1qIÍjjQ—~¤M%µÉÄZ2Q™ª¦8¹iÉTöq�çüe6ÿ8¤nÆÒœÜ\ç;ÙéÍn’�Þg+ÏÿÏ~Ê2žâ”ç:éIÐy¾žÿLhA7yO{NÓš�è±ÉN^Z4 MÔç&zI`z³£ê¬¨H7jQ�ŽR�˜t&GSšQ’>²¢îÄ(Jy9R™Â”¥85iNUºS›Jô§@­"EyS™Jr™D}iR[‰S¥^t›èœiI¡ZÔvs¥1ý¦K±jÕ‹vµ¨SèL»šU®öÓ¡ÆÄªTƒÊV¶Õ£Rå¤F¯ªT�Òò¤KýäMñêÔ°ú5«`MæV§ºW”°~=lS kØÆÒ5°m�l[ßÚW¾¶4œIµk0ÁšX–F® í¬ZkÔ¹26´ŠMgck*Ú§®”µ©uì_]+ÙÚÿR“²å¬§\)9Xª6¦¿+BkÎ�žužU½ç(ûXʃþ–ŸÿD«M‹;ÎãR•¡Ï½.F¿*]�Õ¶à]$6éÒð"ò¡æU$zÓËÞ;@�‹Ýf{ëÐùR³¾öÍo!ÇËÖ_Ðâ¿Æ„€œ”:øÀ©H°‚ÃÀàëáÁn„„ic‚ [8Î06ÌáoX qFLâ]˜øÄ�H±ŠÁâCáÅ0¶‚Œg¬ˆÛX8Î1$vÌcNøøÇ|²�Aä"oàÈH�’—¬ß&;YŠü ªüß)F°‚Ü`CøÁn…-\á kØÃh±ˆI<â£XÿÅ)n±‹aüâÓØÆ5αŽy¼ãYÈA.²‘‘|ä%úɈN4¢ Ô)SÙÊ.p–ë°e.w9 _ó„gCæ2›9hN³šÅÀæ6»yp޳œAç:ÛÙ xγžÀç>û™€´ AèBZÉŠ¶~ýÓ_ãØÈƲ��‰¤<âÙЮt*.�éL‡yÌdþ4¨·j1ÌáÛs u©O½‹U'"èNw«¡`…X¸;°^…¼W¡xáÞ^À¯UÁï~Kâßïw¿{½�_[Øg/±%jìe3{ÙÍF ´£]im êây¸6§;­mp;Íàw©û@ns§[Ý­ÿn÷»ã=ïzã;ßû¸*p™ÜàâI¸Îûðˆ6â@GvQ&þli[ãß´ö8þi�+¸Û!7›K¾ê“£{Ý*w7Ëåír|ëÛÐ2Ÿ9Í%ö›ã|çh—lÏ!úódýØC'ºÑ?�ô<¸©Ó&èøÇ=ìmpK½Ä§6¹Õ±þnx+bÞô¶·×c.ð±“]æi�|~×nͶ[Ùn:ˆþFxþóGÇøÝ™nf§'ê~9Õålõ~å‡o¹âïýõ%‡Ýña—¼îþÞ<¶Õò̆´³‰þyÐÓé£ÏvÓCÝáQÿÝÔnüɱþêX×{ÖŒ÷÷Øs¿ûîÛ–òÕ>ÿ¤#~Îß󡿸›.ÁþöƒÍ­w¾!æOÿÕ·¸õæ~5¬c=ëÚ+ùöÛyÞ7€“Õ{Žô{|V6|w~Œ�~‚²~íÇ~ïçañ7jôG¶°�(}é–ÕÇØv2‡{H€((QàGMâ'|G|ç�vG$H�ŸV'hØ�Ugu hgÖ×ÙÇo&(p)˜„µ‚p¿ð„°…Tö_x‡wnRwâ0!÷mú‡«æu8Vk�P dX†¹Æú÷r´7kJ؆‰Æ„Öä„P(…SX…�v…H—…³…sÐz^(g`HkµV†f˜ki¨†n˜ˆÁ‡Õ$‡¿ÿ…°0…´`‡d†‡§‡ôÁ‡~„_¸†‚Èg„H†gxˆ/§ˆ¦ødŒHMމ’H‰f‰—»¶š¸‰؉ù†cNv£øj¿vŠÀ8y¸K¶µŠtHe®Xa°h(H1‹µh‹9`n�¸‹%8v8ÇdÁ˜�镊¸dŒ‘X‡É¸Œy ‹»öŒ¶(�žH��g�טsÚøŽß7Œéõ„ôèh† ø˜�VH$u—j�0‹Ð¸‰;hý§ŽÚGsíèŽð¸�n%�æU�O(‰ù˜�¹P‘) ™‘‰‘þ�inY�M€™� y’@Å�á‘9‘¸`‘¹‘2Ù‘»�Ѹj!ÿɆ#Y�%ÙŽ(ù“Kè�á‘¿pkœà’/ “¹ “3™j � ¹ƒ"ÉD$ p @™•¸¤’,‘F‰”J¹”L©‘4)h6•8•ÛQ•ÿv•Zù–ŠÄ•¸D”_é’a9–dé”5ù‘8)•:I•+¹mº »±q¹Œ›¹Ž�›»Ÿ‹’¼{¯ŽG@û8$I‘iz`Žè–¶5ƺO´Ø›½ýg}nÙDº+^‡ÿûºr´¼«Ò¼´ñ¼™&½9@½Š`½N”½Ú;kÜ;˜Lô½iê{â«Hä{!æ;èûeê˾îÛDð‹½ÛkÝ[¿Ç;žá›¿oäxÉ÷ŠD’úÀJ[½ðE¼Œg ¼öË¡ ìÀmÁDÒ¿@Á¯fÁ>‹Á…{½ÜÁ6¶ 4\Ã…çnÔˆ”¼ôjÂC‚Â*lg,ü².Ì R´Á2\c5lÃ7œÃ \€®KÂpÄc¤PÅVœ|FA@þØ…›Øb/‹™ELEH,¿±¶Ä4|ñàÄ Åø+ÅuDÅV\ÅX¼9«²Å¯vŽ,öÅ—ÆS´ÁœÇyf¼ h¬Æ�QìÆmÇqÿ<ÇRÇ©ÆÅ~èÅ. Æí[È0 ¿Lt�<È—¦Ã*zȈ¼FŠ|Å'\aYìÈpɨÇUÀÇG\À™þãˆ}º;ÐhlnËÙJÆ�@Þi-¡Íp…aÖd†~†Þê;™Ký±9–ËÆ­ãPÄãÇöãKžw&äC@ä7lnD°ælŽäâ¡ä>ŽwMŽÊ*åa6åXåç}å’™åzÆå9îåSæÀ æqîi‘ÿ`æh^xjÎækîæç“ ç,áäu QŽçfå[Èœ~¾åÓè‚E„n蓎èŠ>iE¾j޾æëök’Né+aé)fç¦ézN |Ø›­åºêþ=ê[Tê†äW«¹‹þnœ×êD°ntðìÐëL^ét^ë˜~çFå‘Àé!çé½þçÀ^×ÂÞEÄ.æÆþ È®ê7¼ì­îìÐþìÒNfsÌ©fëRžíy¾í{Þé´ýé¿®Î]>îÚAèËvèdžèr›ìîÆîŽîîïnêøÎón!þh︮ï”P¶ßægè†åßþÝàÍáïEå>æ&·Ÿ0ÐÈðlîðÐñöy-ÿÁ‡ïþì�ïÝÞïÿïª-î#ŸE%oð'Ÿð“¶òDÇì.ÿì0o2Ï4_ó7óùÎíàæíVp™àð¢ôÏo=^ì¨.·ˆô§ô­VótÐôŸ—nÿöQÿîSïôU¯óWÏóYïëèÁîõT4ô§~ð(_öçÇò®žö5Ïöž÷öp¿…j?÷Únõ߆õZê\ß÷~/E€îXKøÅgøÍŽø/ötÏŒïöqí�_÷ºÎïÐÍëy¿õ?ßámêÉÂv•Ȧ~7]auWw-af”Œ `nâa�¡¾Œ™‘“(ÕКKdÓ—r2fcFüÓ]ß ¶l¸ÿlºÕÖûH÷ûü·6üÿUüÆ�üœ¡ü‹Éü1žØžý‹0ýtvgíî´�¦Û$XÐàA„ .dx0ÀCˆ£˜ÇâŒMlähÑãG�DŽÔS²ÎIN)U`IËeÆŒŽdÎ,©GÐÍ99uæàÙ“eQAiqÜÉèQOI‡,]´¨g(Q¥Z¡ªÈj€†Yµn(Ò�‘\ÅŽ%[ÖìÙ³±¢eÛÖíBµj)ó#Ñ� õæIÒ$J•)º¤ewÀLš%o Ò¹óiŽŸAE %z©R¦N{J�Zõê[н‚%ÚôiÔ©ªUÝÚµÁ¸çÖµ‹×Äÿ^�}EÖJ4‘0Âb"NC¼ ;(zâcFÉšШOr¤î@Íx’ê ¹cC… $òH$’(I& ª©¦ Aê>�@±òJñ$OD±0ŒöcQ�,a”‘Æ'»1’?Ù1³ë¢ò!?kR4¾ïN>%´°Ï#Ÿ,)Ê�¦$J¯+±tÿqË:º,ñK0[±EÍäiF>ÒT³2u|Aå ²Î›4PTÉS+V[MUBAõ ”6˜<¬2QP²dÔÑ> U±1ËÄîÌLÓt®¨NÝü´G¨D¥“T@O}uZ³ÔòâZl眳UW©K-Â× 6Ê57ÖY݃évÛ%å]xqÍuÑ-yõ5ÌIɬtØKѬñXŽjóÍê˜ýqT!KeRZoÎP"l³ÕönYux+pÅ —\sËEW7íj×]xß•W×z½WR`) ÑÒ0Õ`�=ÝÔf¡˜³Îî¢Í“´‹ƒVeh¢÷0úhJ’V:•TŽpúy®8�$°ÿúê²Öú裫ðúk›²ËþúkX`fía>T÷×™0[ê7Nš²{ÉÐ{ï+1ñ;�5ÛL:Dªâä,âkçò“<ìªù"—\¹U*×® �@•á ©%ºh®÷Pz馟†±rÔW™ºê«­ÖzëÐÏöZì±Ë&›ÜsO›í¶Ý6l?¹‡ ûî¦òÞ[ï¾ÿ<ÇÁ+<ÁÃWüoÇ“•|òÇP¿<óÍÞ³sÏ?W%tÑG§„é§¡Æ.õÊWG²u×__€|Ù« =lÛoÏ÷ÝÙv»ñá'xÃ#žñŽ—<Æ-ïÍ»ÉóB½ˆM�qÕcSŽ®9ÊYŽ*˜ÓX÷ôÿ!ð…ïsä#úL·>ö¹ïHðC€üæ:ÝÏù#Âþø§6ÿù.€ˆào”c@¾Yiq€ãTH ÂYÁpRAœ$ÀŒ<î‚Èà*¶×AŸ}0„ÞŸ*FÆ®–Îi§KaÅX×:î‡@�`cihC:ôomÿû�§C1äQ�?ÄÎñ�'DåQpHtž¡ÇDéQdˆlÓ«xÅqeh[œV¿x‰0¦�Œ©S!‘X˜F⬱�l|£ 娻Õ‘‡w\Š÷ø þCT áÀœ!2‚ФL§ì=E{äž$¿GI@Yò‹™õÖO þ³˜õ Ú'ƒ¶ ¡GPèŒMVMC,”(bD9J‹ÖД8œ£F7ʸŽÊDœš g9I“2�‚d^Jo¹ÒœµôZô…=ejÄ)ò“'þèÆŒéÓŸÞ)¨`„Ž ZÔ£ZÁ¡ sS¡sMËdóQí&UQé‘«bÿŠå*HEúU(B³›=)Y�˜DÃ©Õ luk­wA¹æ€®;åÓ@óJ¡Ì @³¥í%‡ZT>v°êX¹lÓÔ™<µ�Œ�*ï4Ypjõ£;ºìc´£�ÍrV¬ìD–߉Öxº´­0…"F¤ˆÚ›Î5§uÕÜ]_‹¤ØÒ¶¶Ë쫉 Xö54©MOoÛðÛÃN4±Í7‹Ë¶ã^5¹ŽØjW]©œçR%ºšíl;­kVx:K»¥õîi¯—ÚÕb‘§Z™Q&Á”{ReµhyË~ër“攌ٹežñ™Ñ¼5‘Í‹qóOâ\¹9/ɼxγžù̵ú‘XŽ‚%¡9aèC'š° ‘q£+1H¿MÒ”Ö„¥ç€éL³dÓFN2®?íd(KÙœ³~nªU- .cÄË`V–ðb�;2?×Ѹµ¹×Üf1¼ù׫vÿ�‡Ml®è9ÇFšù”mb» Ø>Ðv±×`Œšj7ÛTÒ±¤'Mioƒ;ÜãÞE¹MðiP?BÔ¤65OP-‘wÛÕòvõÀævo:ä[;ûî÷Éño^Ü×P�óµè|ñ;¹áp16ük>J<<ÐôÄÛƒC#ÚâŠÆ¸øæ³ñCIÉãïqÈõîŸ�Üä(G÷¨Õ=RvkÇݪŽ÷æýêz‹ßq§ Ïû�ë6íú&½fÉÀ ŽtSõté ozëžîð?/›êͶ:z’õDH»5]üú£9ÙºóäNòÙÑ^µwÚÜwWyºK½n*'xî«ÆD«—Loêè=ç|·‚ßoÿ ø6\àD¶Ñ…½á;/¾! gáãG·7\DŸwk³}•¦’Þ(§ÅØúÓi8ßy[%ã'ÿF)¸Uêèäi§×´‘ cW·^Ô¬h.ÖY,ßÌÝû7ÌÝm>8Ò9ª;4¾¾¡+:/8:®K:ÅS¾¬P8½p>¥�>雾êc£ëK‰ì{Œí»–î3�K¿‘@Ô8CTCdÃ6”´7Ô„8œƒ9”Á#{?¼ˆ?=¬¿üÃ$Ä 4Äz#§Pľè9RA=“3ZHHGuDEðSE4`E74 <:¬Ã]°Å4»Aù5]ôCÁš¯ˆÐ²A,Äü?8"b‰KÚÇ$LÆ%\ÆH4E„Æhˆÿi4Ÿj¼Fëƒ<2ØÆOôÆŽ¤ì GG2,Ç:é$„PÇuü"4LCU„GW”G8|A9ŒA:¬Å¼E~ÌÅ´¿DðÁ@†‚üŃ<ÄýQÈO›�†ô´‡TFÃ{BÄ[˜¼H� ¨#Cáˆj„:»ÙÆFK²$é�ŽÒ#©² hK·¤¡XˆK¹¬žQ ò‹4Œ˜�š Ž*ó’HEóQ±«ÛÑÒUú?êH§ìºqùÇ|ÌWˆLÉ$K²T,Å"Û˜�’y—AÄÍ$‚Ñ ©PÑºŠª¤�JT>­4Û;od2°l ±¤ÌF°�³LŠ´\Ës˷̹”Ë0Nÿá¬K‰¸Km½, ¾L0¿4È‘üÂÔ"L ÁÃÜ!Ä\ Å”0Æ µ�ÌɤMfk#ÌÄ ÍÜÌÎÜ¿Ï ÍœÍÇ(M´J‹¼ÈÕ�ÖtM”‹ÍE˜MÊ´ÍÛÌMÙMÞܸüÍXÎá$•â?¼DNÝØË¥èËGÉÀÁ´<ž�Nyº–êÔ™¸Î!ÈN�™Îí€îôÎW ÍFO6O¢(Ï’9OKHÏ7ͨ M]À÷L’Ô\<òé¹�pM»û4üÔO²äϳôOΨ2Ðß4Ðà$Έ0ÎîÊËUÎeÎýK‘ÔÀÀ,´ÁÔ›ÂL“ô™Äô£Åôq)QïDÑÿ®üÑ÷hQÝøL•Ñ¡ÑiÏ5Mg¼�]ºõQ ½Oó ËèCQ#EËKÓÝ|.à’ ÅrÒ0€»TÐãLN=XÎçjN¤|Τ©ÐžÀPl QÕ1­·2=ž3MS‰xÌÇdÓ7åˆ65…—*£ÓXdϧpO(<’>E¸?í¹@ÒA•ÍB¥ÍCÅÍDUËÿdÔüBŒGuRIMÐPXPKÅTíÐT˜ˆ?¨óÔ ÓURµN2ÅN3ÕN4åÎUeÕ_pÕZÁ‹X�Õw©ÕÍTÏ9ÀÕžÐÕÓœ�^%¶£AõQVÖSâY„\8Ø"]Dm A¬£Ø�g5P�T)5 ÿ¿¸Ô7ÑŽž°—ü`;.%I/µÐ\ýVp W8Y¸éP›AR]*ňP×_� ²ŒÕw�Óͬ²pƒ˜¹×<ÍQJ¼J¬ì×Tû<·�-؃ͅ„-¢…µS©pX£€Øl‚Ô‰uÒŠµ‹‹%�å Ž��õÂN YÍP/(Y“EY|AŒÿcÙ¨h"µ€Y™Kš}Õ�˜�,ÁÙLÓY~Y²ÕÓI”�}Å3¡E€XmM¤EرįAV†Å¨�©%ªÅŠ¥Ô)ePú°ÒÙÚèZÛ;\�}¶«ãY²5Û“u…”u„µMVqÛteÕ¸MQº ØÚµ[ÁÛáÓÛÅÓ¾õYÿ^Zù4%\¢»¯%XâIÚ¥u°¦]OÈÕ¯‡%ŽˆΪ5Ы…‰¬ÍXÝ×äGè,]ž-ÔE[–™‰Öý6EÅØ}Yu�ݹmW¢pÇ»M°œåÝÞåÛ9^" \d²¶J\€e×Ð_Ä]^Å­M…u\�Ø�È�Ü6ª\θÜiµbtÐÎí^•éX£ÛÑM-Ó Õ’MÝÕMß½y]ÄyÛ÷ Š™­]ø$úÍ]ûÍ[ü…ÌÃ×=EMá]:`%àïýƾæ]Üö䘖ި¥Þ©…V˵Z̽`ÎÅÔ�Ý`¯íàðÙ¾–òUÝ´Eß•u]öMáØ}Løuaÿ‘ù¢N¢çº_ü½ážÝÕþÝἂÙRÈcjÕ�â-ÞÛ(”«‰$ö’ýl§S@HdE&€è9½°�™h£¤H"^é—ð;Šþ8«çÊ7òs�p°ÿ Y‘Ý›Ëñp�̺‹?ÉŒãùT½Y;1u¬[¾å¤MÚÈÒ”<îåRHbÌSŽtJ'‘ª²úÉW>µãŸÂc=®T>îc$øãÅ ä’ä-dd9ä¤QdE¶Ge¼ˆd6šäBªdÂÀäêÒdÅP©Nf·Oç€I–Ü#Ý/%ƒS®‚T~…UæÇV.˜WîV{öŒž9uà\>Ø]N_Îc`Î:aæã)æ;æÿÆÿ½f.…=î hŽæ4‰,jÖk¶dlŽgm¦nNdälä[{äpvÔqöJîZtŽgËØä*óäñå�eXûç0å BåQUå™ Ò”ëç¦j¡ÞŽY.ˆ‚¶¶ƒÎ…„®‘…þeäæÇ€èˆ.'c–dÖáø|­ŒÞè‘èhiö›�i—(i£8锄Û`i4si¢çG g•2çKöæt6 œN0�ž®éÇ™g¦Žå¡Æç¢Öç£fe¹YêèTl§hZNGN§ª–Œ«Nâ�h®–èç¢è¿ëä;¯²væ¾Hâ´Æ„µFBnÞ·¶1¥ydäì7»æ¼Öë³âkÿZ0lèØdåìÂök›ez.eÊþš|Þ礎ìEH쀮ìi‹êFK§‡FÕ½=¤ü…e®&ÑÖبèdë;V×^6k‘`í�¾ª×nŒØ6âl¦í¤qéÆiixÖm˜Îk™.gš6nîáŽ=+xçž®.ä–î{nîÇægèVp�®n̶6ìÞêrå ÌÊîÐöêïÒÖWe&¨ÇŒ�Œ˜ÏOñ$†£È"ñ‘Žožï+»æ·ºÎï�ØíþÞk¿ÔGçåí›p¡Ôn#BìÉžnænlçŒiV’ìz–eË†ê ¿n?ÒðõÅpXZVèZ0—LG‘*Ãë°Ç�ÿ?ñGñ·¡q�ñk–íH¨q»ñ�€=ßs…äýæmªèHa\éÈ"ßÅßix>웃ð"jQ�Ì'çï(�î%§r ‡„ÌÎr ×n._¢ìH°+ sH�S?u2�B¼"kÇ$qŒ0ñIXs6G¿*8�sØÞ`·®s;Ïm~Ûs>?O?wIîñÞþñždZ!„CÈ#pynôK_ì|žt¥¶ô)�ð–¼r«ð§Q{} Îx®QóSGuŠL•‹v˜3ß‹4�uYoóýá•['9'i:·s‡ç•v=ïó—&ö˜žé,òê*tiö¡¤Šgg'F·7GoòÿHkði§îm×t çôo¿ðpÏ¥P'w07÷s—„To­G¦v™€uYÏyÏz¿õ{oë|ïõü€<ðw8€QX‡u'xKFB_v…7rE?ðãþé‹—ø`�ôM…rqô!!hnŸ1o÷îÞnqù/�.R/y“Ow;“ÂóþWoy5_ó˜Ç�™‡óš§…]×÷ÜFNž÷ùŸŸ„ ÷ï‚Oö 7ö!pDoxŸÎ»äöîwò¨§ô©¿øª¿l�Çr Öú-ÿøEýúÍ û’?ùŠ<í-"uòÓ¼èhÉ1—Íú -ï $ò+±IðI/³XÝ8A�Ø, ä�},vO`ÿ"# Úý•b-q\øÊV¯Ùšñ�øJó™‘7›˜Ó�øW€uàÿØÆÈ#.Îá†8dô¨—¤Á–¾j:ééÇ�ŽFþ(PŒ2-s„é³J•b(kölÙ_jׯŒ‰õ-Ü·Açòi›’ ^Cö¢íë÷/àÀ‚öK€€?‡ ÿ3nìØ1¤È’CQþ˜³!’Ìš9pnã/Ñ­9 ’&WŒhѰV³žt"lF?®M n«xI#\ÈÐ!Ä‘=]Ĩ‘ãìR…{:‰R¥è—‰bÎTdóæež=ú J´èQ£I½, ÖôÕÓIQEJ¬j«Ö–]Ã| ;vðZ¶vOŸ¦Ô®y´—�x ‚�–Øb :ø `’MV™G—™ Ùf�}FPh[•fÐi©mÅZk—%wⶆºtPB åÜDWGF·lDKG³-W£s)¥&u4]§ N9I%wÝ EQJ9^y祷ÞTíùdÕðm5_}c‘åÿ˜$ešÉ_\þÕe—€zñ!œq¶ bÈyg‚FFY(–]†afœqàY  %Ú‡¦Å%bK$®æZN(&§âm¹ ô"½É\D5wcŽ;öˆ%sAB·‘)Uw$’—-R“”x¥”QRÉ”SP�ÄÞ#î]•Õ—^¥–˜�™i¦ž�ôç€bŠE žÑÆIgƒÒZ;X²|ú™ HJ¨¡ úaˆŒ®ä(,�:$él”²è¢!¼Å¨ÐŒ�’d#—¡"ç#¯%�$dt0©jäuI:ôª#±Î:T­¶*…+zº*Ç«¯]+Ÿ°V{™ÇJ’ì²t5ë,´×šüµvž¼2Z’‰òÿò‰Õ¦Ù5*èw‡n5Þxåš‹®º ±+UEÍ¥@‰jJ/§Ì}šïq<&÷㽦)°L_²µÁ !¼�¬O2Üð­æåªÞ®Yöºå{³æ°ö‰e¬ÇÉz,‰*yëí,ßc²ü÷`)þ·Ë0''óa4ÛìÎ9K'ÏIÙ29å¢-r9æ@›()ÑF�ôJÏû[C4Þû´UúJͯÚþš0ªX¯ZÓÖ—tmÂ×;%v CQ¶•S]±—Ów±k·ÇzïÝwòƒKß—àÓ›\¸(174sf5q3g9ðøK‘{Ayå[až¹£A›0tHžŽ´è¾Õë´EVáÿõ¨i—úï©Z’ª¬Y‡v\sÕ«À¶°Þ‘íaf‹Ú&¦6â¹m%pÓ˜ÜüƘ»1ïXÎËô¢g=ëUo„ÒžöLÀ=$x|ùa>ôM®6¼áú.§¹Hq.~ò]ý6U:{ 'ÙŸŽöE* ðjÓXuQ»Ûåî»ûŽï€w¶%®�\*ÞÛ2¶±¹)YzºÛUBŽ™pz%lã�Px¸í%®{‹kCã¾ÃÒð†8Ì! má>ø9B~Y⇖Fº‡_GT]ÿ$ø¿×�%œ�¨¤êÎIXl y v%ÿiÉ‹m‹O�‡A†ƒglÞ×HF8îÿ�´„“gƒ8(î{Œ ŸãÈÇGôùц9\D ÙÃBþ�~‰Ýý£z2[Jµ0ûœ\?)óO€‚® ¤9hB«€-=9¢EE—dQ�‚.£ÿí(8™Ò‘"Ĥ(mˆJ#ÁRJ¼¦2�)M‘ÂuMê0G'âØM.L—™íˆK‡9ÓCÙ´ŒÍlíš…š·Ûî6·¿çp‹›äòsÐ]+u¯›ínØ»-ïyïzäöV—¥óm•}ûÑ'ŽtŠ•½b÷6[Ï&M´1m…×øÚúÍvqoK6'ª8)Îsž�š›’—€:îñ¹»ÖLžåÈqMï ŸÜÓÂÖw‰[Þï—#[0gqÊm^ph\Ú §ñ½Ð,jm_fè¦.ºÑ).n¥7…éuv5K|õ޼V!�wÖ½uîvßV6–Åîo¬\æ^Öe‹ îÿ1#œ¾ÔöôÂEŠí¹½îv—Þ!rôŠóý~§DOcø† ~Ý…—ÒáËžø /»”«Ý‰º¥€á[Eö+!'Ï6 ü8%Ëyxþó-T„é{Ï*¤ €‰‰»ö¨ÃW€õaDR\àxÍ„� ô¡âI t�%üãßç•Äð˜‰ò …™my÷OîýuýÞÖ |_ñÁò�‡òmóé‰ó¥ŸôQ_Í„ß:­DöÑÐöaEyñ%�ø‘Tù‘Ú‰¤ßó­_ûAÞPÄŸüÑš’=Žý}þÓãŒGÉøŸ¼`f à% † @_$`R,`JÈB_Aõy`æÿÀ¢OnK÷•†Î"DæTr�`˜`Å1Z¨ üÍŸK�Ï –F ê‘þyA Ú`®á eé jF¡zâ’’`.¡6áRNVH¢q ø1áøaaùi!ú‘ Šš‹ˆÔ_Ý_Ãäß îß›¸á–œ¼Éar_Î�‚’.Ÿ!^Æô)á2!öÙ…öq_H"&"ù-âæ4bú­'ü"0F¢$n“tÜ�%Ö &6n"'V(Ά(")" )!*BHó­bN´¢^ßVâä âl’-"b"fá.~ú"0þ¢0c £Ç£”$ÿ㟵a3þŸ'Ú(ücíŸG@Ÿf¼ ÎÄÄ)2`E†%<äF^©”7¾âú7!” Ö-:Â9þ!.ª#‚±# –‚Ižä;þbvˆ<¾…ù# 6Ì1µ �èã>vØ3VU@`(f†ArÉr)$62¤œl#²¢Æ"UÁ,jàjBâ\Έäù}ÄËd¥(œ$J¦äJêLKbÅKÖ�žøÎL HM2ãMâd?æÚNî`O"ÁOZEP¦ÄBâ‰Q"!Rº¢RÂb8Æ�Sb`G~$U~‡U×lhåËp¥I¦$'|¥¸Èc¸d丒„˜eÑdZ®¥âµ%®½%Îÿ¥@Ô¥ÜeCªâQvcR.å_6åSJa-Rá(&Qô�mÞ&º@$D*æV2¦cB¦dN¦XV&YJH �e^¤e�p¦“å¤T�f\Šæ�¦i妦CTd_^dkj¤`BelJål„øÜ&n:Šn>$o2f)üæ%æLpR&ÏX¦dgf¢åf2'[2¯¹åN†¦¥å�E‰Pâa6¡dDdô¡E‚cKÔG`Bá`Ê&5ÒæP˜§mæfz®§ozå{~G|ç|g}Òrâ…rêç~âÓ“ýã(ÜTláóµbÑXÍ6‰"Ì�…rî��þhu©�â…é`ÙQH% FâÿèXðIžÈ@‚”b£@f'\)–Ó0žÆ1€˜Ï„©˜öE1”ž¨hâ9g¹(ŒÊhÐhØh…ᨎbX�þ¨� ©ž*‘)÷!©÷()ýÉÎL4)eè¹:ËMœ”Ñ"m)m”ˆOÓ:m\SÔ:OÉR­½Zíà`í³¶,%9©ÚiZŠ­J‘mΞm‘¦-!b°­_º-ñMÜFÒ¬kÝÿ(22mÞ '\ðmß‚Á.² .àn¿BkHëáÞèÀ*nØ2®ãš-äJn9:ÄÚ®æå²“ÂmMô×Ü.êúØ-àíè’î[˜îéþ­ê¢)ëþ�ëôîs ní^«r2n$ä®·B®ð.·T.ðr'æÖ*ñ"‰Ü&*Æ"oÒŸL~.¤ˆfÖäé¢îÔNïMV/Ë\oöj­ËFlâŽEÍøÎùš¯ï¢/_¶­ð¾­˜l.ÒyîúøN›h©$ª þâ§þî¯ôú/sðʰ¿Æ.ÀÎ.µÂ¬³$ðãîÍ>îî•ÚJð7S²ïïIepüjì7LÛ/£€ÿ0›ˆ0�쯥® Ÿ°gb×Rˆ ÎDäU¾Å�I^ðÍ. ¡Š…PÊEU£¾/[�’‡D˜°‘‹&ÊlÍî‘& @ 9¦c¶‰‹ºhE1!Î_W_ñGd±Jm1VtñK|±³„±ò�±g”±ŠœqL¨±"r.lœ±ÅT iÌñ,Õñ‡Ü±FåñÚ¤§$ ò( r!ϲarf%rúµ±�"·x1A€1%[r`²mhrJpr.z²“·Ä(#ÿ££²*gâ2.çY´ò;¾r Ë2-‡3ÊÚ²eá2ôér#óò#û20‚0‡q�sm ÿsÅ33#€2­D4¯Ò4�‚¬§g3™î¯84Ê�se™óó¡s$82j°s$ó$Sr<_†¿1+³ñ&Ç'kt(Ç1�²ß˜ri¼ë@Û¤#4K _ Có+#?´:Gtàµó;/àEçDF;óFÛs'ŸÈGûtHC³Ks)S3ÄBjJ«¥¯tKGõœ(tUÅ´CC4$'‚$‹ %oÀNïRm€á=­>WÐhµ?Ëì 9¨@“OŠ¢ÅJKµ\£ÅK[‹U/2#ì25öòMO´;;K+¶âW7‹H§øŒ5ü>ž:‰4I÷ÅZóð¯æ¯JCõ\Wv]KË]{ÄLcµDkÿ5E‹I`Oß`›@aèÊå bçªÊíóY�4Ríc7á0J¶SÇueÏõeGKfÀf×tVoõX„vŒvi· @j«ëj›u?‹œYÄö0ª mk³‡QömKunãÉn÷ö^¯s_{¶!³pX··Xwò[~]Q³Ds#@÷ûÇtôé^7nSµTmw^§swÛôñµ³x‡6yŠy÷=§÷r‹2Z;wYÀ·¹H7×¶uÛ7K ΉP8†gøA[xrh¸‡¸ÿrøl€8‰—øê–Ü…›¸Š¯x3ŠøG°8ŒÇøÈ¹¸Gȸ�ßøŠ.FŠã8�÷xTÑøø¸�¹ 9‘œ9’¯Œ‘'9“7yvñ'츓O9•7Æ’W9–gù_d·–w¹ŠÓ PŠ˜�9™—¹™Ÿ9š§¹š¯9›·¹›¿9œÇ¹œÏ9�×¹�ß9žç¹žÏLb A˜ï9 º :¡º¡:¢'º¢ë¹\úÁ$¤Gº¤O:¥Wº¥_:¦gº¦o:§wº§:¨‡º¨�:©—º©Ÿ:ª§ºª¯ú¨@@!ù,@*tüÿ  «ƒ©*ŒÄ°!£‡óHœ8©¢Å3jÄ8q¢¨� ;‰)¦dŽ“PRª´Â²åÉ—9Tª„‰R&”–- é,` ÏŸ@7º§¨Qž<�*]Ê´©Ó§P£J�JµªÕ«Xyd¥paC†#vÌc¢¬Ù�hŒÍ2äH‘%ż´y§š1mâ¥k׊NCI± L¸°áÈÖŠ°kª¯`Ã2ZkölZ�kÛ~| ×dM™}÷ê¥É×îßÀŠS«^ͺµk«Œ¹:†Iò䱕Ë^Æv¢nB9ä‘H&)—qLŠáä�Pª7%•1Z¨å�xæ)—;zÙc˜�*hn&ø7€™g¢)ˆšk"—Š ê´¢QF¹¸ÊœRꨣ•zvê)…|ò˜_˜§:hn¶ êªˆ’¢è¢jšÿ©_’HiQ–bzˆ¦rúé¯ÀJªŸ£jê#„¦ºªª­¾Ê¨¬MFª¢­·æŠ)¯Uøì¶Ü:çÅ·àþá"©ä†ùɹè îºs´ënKt©Äè"ôÖ;S|b«£üöÛí¿{ î·â*XîÁ§ ›îºêºû.Kñ>ªf½ö ••�g¬qk<.Âä*|.à ;<¼ÏKñ"÷^¥íÆ0Ç<˜Œ[ªÈ ‹L²&Ÿ qʯÜ2lËlôÑSÑl³‚;óáôÓGD-õÎ=£¯Ê½eÑHwí5PJ/�^ÓO;-µÔ=WýóÕAgm±Ë\-w×a‹MvÙgGݳ‰·ÿ×ËD#5÷àt[XóÒwC�÷Þlö½"à[ Nøä1×�8Ée›�÷Î|GüxÜ�£Fùè[ns⚟Íyã)­Ìò��S;é´{jº¥¨ó‘÷«;*“ëŸK.Øìµçí.æ¾{ïKª<ì G.ºñÔo;”ØbÓEÆöÜëÚ—ëýú[ýøä t=ö6kÏýöÞ×)|ùð“>ú.ª¿~û8ÿþ“ÏOÿz6Yû0>~é�üÚP (úÙ¯{,àHA£-°€  uÅÀ Vðƒ1c`e‚ˆš��ŒWh4bÐEØ2á ]Ø/²ð†Ü¢a¿,C"B‡T!ÿ‡ø/ `E=”¡mHÄ&æÉˆHä•D&:ñŠX‚â�’8CZ‹` £ÇHÆ2šñŒhL£×ÈÆ6ºñ�pŒ£çHÇ:ÚñŽxÌ£÷ÈÇ>úñ�€ ¤ IÈBò�ˆL¤"ÉÈF:ò‘�Œ¤$'IÉJZò’˜Ì¤&7ÉÉNzò“  ¥(GIÊRšò”¨L¥*WÉÊVºò•°ŒeÆ AËZJâ–¸¬e-yÁË^Ê’�º¤%.sÌ^úò—j &$†yKe“—ÈLf0™) g>3šiT&5­iLl¢Q›Ìäæ1½YFpSœÐ$g9ƒ©Œvº�¼ø…<ç©N,*Ó�ï,æ3çIÿÏz:± (>Ûy‹‚ô™ñäç/üÉÂP8ô¡è@ jP_Xô¢ ý5ŠÀ‡B4¢½¨2(ZЋbT¡åèÜd4Å[íÁ"0­HjAÓš’ôq©„N3ZK•NŽ¥>$Z,2ÓšÒ/9Ý©B{êÓÁU†BÝQ?bÔ£Ò$©•à)-›êT M1ª™ª(ªZ ¤–D§Y]êV¹*7 YA «L©ZU³Š­Z…[Ûj¡·‚5#b%«]ñªV½îÕk<¡„býWÀÎu¬u½ªšû ¦i‰]ì±þб–H²I¢¬e/k´ÌR‚±ý‘êc? F‰v­¤-mA{ÚÍÿ6¶³«åŒ]±:ÏÑ&&£ÀUhlYcZԆȱ“pË[v{V¥V¶„ ®t�‹Ðᦸ¶M­\“»Ý‚–·òô­`¦KÞyV׺Vém±sªÊÄt­ê™®^½ét˜O‘‘2uÁßþ&ã¿¶…€œQ´RÖ¼×DïSÔ«XöŠPï�¯Éæ{’úJ뾸̯…öÛ_þÀ´±ˆ�Aâع�Â`J8®î�©„FáX˜V†Àð-5ŒwøÃÿñˆKLâ§•Ÿç]1SZübËQòÅ}·gßJà×)ú f‡= d!‡˜ÈE>qF“¬d¥0ù:í5‹+ÖÌfà0ÿ/6¦ò…­œa,[hL&r2¼L 0;ÃÈcNp™Í̯õ¢ùÁ¹as›9óf¼Üø/:–�y‚g=óÙÏ€V(™í“3Ï¢½Qôš�#@2À¹ÂrÆq¤']<£åÒ`¾i Ê NwºÐ >4ŒC-jR ðÔq&C•¯ÜMûخެ‰|Ó?8ûÙ´N§­àiPKDÔ®ðõú€ýh�¬Ú)ÇF6�´›‘e—¸ÙÏvv´k=mjãÚź6 ¯­mîq;Õ�¦óŽâÒp;Ù17‰Ñ�îu·ÛÝ0ô§m‚y/ú-¥¾·°çLì�ôÛß/·—ýLðg›Ô¢ã´uµîðQs&â§ÿîvŽõ-i~ßÊßšÈ8F;ûã¾9§ø%Ú`âç@÷¨CKÝ—¿üÅu2ZQ–Îtã–…6´YÕ%¦Nuª#ãêXI\8ÁõËSäì9d€t¡Ý4F7Ò-¤t¦/ÏP‡ŒÔ«^u¬gý$[ï:Š¿¾ó°oÈçdÇ„ÐCqvå¤}íHi»Ûá÷†Ì�îS·ûÕµ^®sÂë å´'6Ïù/’G†£Xô´+3é"ã‰Çãõ°ïƒìgOy1X­)4ç;¿¡Ï‡~ôë+½ÑOo!R©~Üfa=C\û×Ïžöx¯¼ÞY¾oÝïÞ ÁŽï%ü§è/ÄGŠÿñs³úÆ3¿ùÏ—}íoéê—ùúØw„#´øßÓ¤ðß×Iø�2þʬ¥€´¥pާ*T×|Η~ë7}¹÷~× òGdg0�Ò~ÁÄü&Ç×(€o³P€p€˜~}°€—×~-g}»çyõÇ}÷Gzh7|Xè#8€!(‚$h‚è§€Ñg{ ÈL¶08�2°ð„PzigûWý'ocу¥ðƒØ„S‡€Æ€‚*ˆ{H¨y×·„@G�/…Q(yÅð†pX…{p…eñ=È…×á…—†bX„ìG}-è€/Ø{1hwxÁ†Ozp‡79ÿè!;(Zˆ‡#¸|ø…'H„9�w+ˆœæˆE� ¢ø%óR½€ˆ°ðy¹°Š¬èg/Q/Õ ²8‹ïyƒç:Øá!Ë¢*¦xSµW/”UgeŠ{ Ѝ@Š×¶f¦H(„Š­f¯H/³8‹òW�Žð^–��Ú˜9| Þø�¹Ø!»H½HR¿H/Áè~+FŒÆˆŒyÀfËÈŒ•ጫèŠ'Q/Ó(‹Ö(ب�ÙÈ�ߎ"Ž»XŽuŽ‹�Ž�¸ŽFÑŽRŠ %�óH�ö˜ø˜�ûx�1å�ÿ˜9é�áx ãh�…� ù‰ 9Š™Œ®�iô˜ y‘Ó˜‘ýè�ÿù‘!9’ å‹EŒÎ%ŒJÆŽ*™Q/Y19“Òˆ‘ûx“Ûè‘:9�"Y�=iŽ?‰ŽA©Ž F”Ǹ’�IÙpñŒD†ùØ 6Y@Ç‘–�“ù%ºx‰—P°W’4”GÖOØ’_i”c!–I9¬¨…hé”ÖhmÉ‘p)�ÅR•%8uvùzx z™Q(ŠE‰k!˜/I˜«h˜4‘–k9 ‹‰“R—™T7™ÆP™Ñ˜�{—y}©™¨@�¹c š¹ š0AšOÉ–?ç–� ’«ùx® ›÷¨•{ÉwµYŒ¢ˆ›�©›ƒY–¡Ùƒ‡Y“ÁišÃɘ©é˜;I—ÉÿYPxq™Â5h^)�aI�Ÿi�½‰�£‰˜Õ¨˜Ý‰šeó‘± —™u PwIžyÉœ˜02R  CMz%º  º S´"z E0¡º�·kñ º¡oú¡»#2Ÿp$Z¢Øöy¥Æyîâl0A*Ÿ†„£2Ú³3 Z @� ç© 7Ú£ :E_ò%"J¡:�zdµ¡z,"º;¥V¢&*jŸ÷%*Ú.,ú–†Ì°¥\ ^ú¥å¥s¥ã£Ó:ÊOYB¦jêU>¤2¤DZJwHZUJª¡oÕ¤yó¤Pz'xTºy+ú0‘¥È¥]ú¥^¦Òÿ–1k:#q¦åÅ—ññ¨� ¤nŠpJ¤sZw’—¤wš§"ã¤Ô§~*¥€º!U:Wz†Ú|ˆº¥Šº¨ä%¦ÿò¨9ÊL“º£•j© so•©š*2qZ`zujT¤"¤£º§¤gØF�ê ƒZ¨.¢¥±:«ÀÀ¨ì¦1¸ú’º«ôá«¿êoÁ*¬³°©z¬Èjwdµ¬o*2î"5¥­¢&­ª*¨VJ¨Xz­‡š­³Ê­6j!aP° 8±Ê ˰°»ú ¶Ú亠Àz,蚮ħìÚ®W÷®a¬ 3\G¯Ï d`ˆ¯ù±ª­š¯ { «­»1³2›nÎ ÿ»°Ëаûk k*+¢`˜±˱>â±è²œ ²ë£g% ÓZ­ýª ØŠ¨.[«�02»µa@³`³±Š³:›µÏѳú³‚´"3´¨±Xg´‚´çBªMK²h²Ø�²üêªþ ««¨/Ë-ðǵ3K³Úz³ »«;ë2b)[Ë(¾�¶�¢¶ öÍç¶ðšzz6õj·Í‡·×¡·ÖJµÿjµ‹µÝÚ)n·tƒK¸뵇¶‰;©‹›4C³Ž+³�«’û”‹.– {˜‹ pÛ!rû tË=N{·P›¯Ôº¯¥«U›¨€«º¿Òºmðº°Ûµ†;«ˆÿ›³ŠK¶«‘»é¶»1Û»mñ»Á{.ÃûzÅ{¼§�¼Ë»=ͺÏ{²úʪ{«²}˲ ¦Ø!7Ê@[±ÓÊy–‚ ÐÀÍðÀ-›º K›RaD.uÀQ±Õág1Ù©TG¤’´í2x(èg"¥…³˜©«ÚtzÇðÂ0L¡q;*û;ôÓ_Ü á;ÁÎ9® jÀœÀ›·À4ÑÀ �Ã|½\|+Ì ìL�ÿ"Âs°ÅÏ×ÅøôÅ­Æk<Æ2QÆfŒÆó«ÆÓƺÀÇ\*¶<,!ìw yü{ ÁL«r<ML)‹†?7ÅÎXÅ— ÈÂÈ¥VÂ`vÂ=˜ÂnºÂvÑÂ’gÆg<¡3œ‹5ìÉ ¼¥¢üÊ>Ì <‡®ð‡rzìÀ¬ÜÇ,ÍQaD³Œ®ŸgˬˆËºÜ!¼,@¾LdÀü�¤«j)t‘Ã9ŒÌÇ É=ÒÌèƒÃÛʵûÇsLͦLÉœ‡Íª¬Í:ÜÊÛ:ÊTÎᜩãlÈTŒÈUwÎ9ó îÒË\üË^Ì`<Ìû+Ï6AÏlÏøÌÉîâÌý Íÿ,®½ Õ,¬ZˆÍPÿHÒ ­° ÛÍ�^ýÐbÛ‡ %“¦{Ì!œÅ&£Ñ} N †6€»ª)]?)P6 ë²¹¢Ï ¢g6½Ã !�ë"”ˆã8Ó¿v5MÒþ¼ :íÒ<>>í¦@]ˆCM�EýzG I�ÑK­Î²çÔÐÕ$-ÕÖ\ÃllÕP€Õ$­ÕªÂÕ`âÕêÖn Ǿ‹j½ml=Ú—�Ý ^^ ~ þÐÞxMb+^á´íרë3{ºÍÞ‡íÞ‰ âù @òÝ ô} ö}´ø=+Þâ+ýâcM7ŠÀnj hžæxA lÞæ»Qve"•°ÖË­½Ô€¡LÆè�ºç¢(5 ñæ?§…tQ†.RîÿÔæm~0Ðèî’æÆlw×ý¥~þ—_B[^»µ¡7ŽQ�úé#¾!R%†u6�³~ÚrMæ jæAšæjNŠÎæ‚.xB'çE粊êÔõLxzîç[é€Î³Nè6aè€èíëÄÀèŽÞ.�NÆ’7é^Z陊é4«é’Çéáé«é!¡>P£~u¥nêÙ ã…Qæ|æ®n kë³>x¶Þ ¸Î =®i¼^†>ñë{ì~>ì‘Pì=X臮ìÌîìðèh餾ã”ìnŠíé¦ívÇíàí� îš!ê$Öðôlîç>æ3³êëÞêíþyÌïµÎ&sŽë÷Ždù^qyÿLÖŽ®O ðÿ�Ÿìë¯ð¦ÀðäîðÕñA*ñÏFñXgñ’ßï ŸÃ ÿòÒu]Ré¬þ%ín (ï—ç5ïõnõò„P½Îï|ž©75�öƒ>ðÇ^ðˆ~ðåÒè í /í’NôÀPóG¯X™.³›¾‹�Î�ïSáŽO㎠ånêf\X�Z_ò\ò�—òpOëqÎò·îòº>kw®ï¡ö›é¦moŸ@gì2�ìÊ® vO.xôBïø~ø—.øÙNøÛnøÝŽø‰/V õSÿÀUúä5ù<¡ûáÔX'b»a‹BG„MØ kÏ¢ÏKiÿOóFÏö¼;Ò €î¢ÈŽìåN¡'b“æ=Ó7«|ÓÖû¥ W±[[sIC“$XPà+„ ‘-tÖ°ÏCˆË$NVñ×EŒ5n„ÔÀG�!EŽdUÒ$*”)g­dÙÒ%KL1e.¤‰ŒÖÍ9uê¼ÔÓg( A¡ % ÍèQfI•cÚt#/¨Q%M¥:q¢R¥)UºüÔÕ«I“GÄŽ½IkçÙHiK­�Ó–h¸qoÍUV·æÂ²§ôîÝkÊo[Àsˆ Êp3ÄX“Vd ŒÒã—‘W†¡\9ÕeÌ{ l>;Ààç‚ 2tñ¡/Ô©odݺ#¤‘±eƒ-©¥ÿdܳdμ[¶3OŸ=ƒ %|©â¦N5F•JuªU‰Š™ÙFõÒëWÚcÉâü= m¤µ¥¿� wî­ºÊîÚ¼É×½_S�Ý&jâfÒW|L)·ËÊ,Ãì2Í8; 4' !šrÆ´ÓRCmµÖ*Äè5Ù2 ‰6V¨û/²ÝbZÏ·î‚n¸Pè3Î(é’cŠ cÌaFí³ºe¤CbG­»îµ‹Äß¾ o¼¡Ê3�.»zkϽ¾þ’�¾úKL±ýƒìCÉ$P¯Íè,AÐ|¥ÁÒL“pB‹,´C 5äÐC.[ “¹ûÍÄKPL±¸[t1FiœÑFÃpÔÿ‘Ç}¼.H!‰ìÌH¶æƒBÉÎK/OZ Œ2¾)©„Â>üôÛ¯¿:#ó2•Å<�LƒÌDóA×ô…B7]ó(Î ç´-U˜Bä´»øôSÅ@‘”P2 =QEc´Q®~„T;IÑR«RÁ’TRÓ&kÊËÓSà“¯[*I½«,Q¶¥U[ÖМÂ>lÅ5WŽv�-€Þc`‚ß�ì;� êea†sqøa"–8Ì0-±øbøàÃ÷N‰¿ƒÒ�CNo二1?ü.9+L¯‚gŸiZècˆfÊèS�ÖKiÀ˜vêUئZ±«�ÉÚ–­÷fÉk°¿»¦²ÍF\íµÛvî·å~“nØDºà¼õ~¥¾=+ðÀÏ…ð GÜÅMaü,Ç#�<òÉÓ«üòf2×ióO:w9ffCŸdt›åÌe;kKÏœµºZ m)¯ÛÑÑX’´Ç,­i¸ËÝÔR5¥ôîwÁÛñŠwÿ<š$�lçc^Úœ÷<èI¯BÔ«žÝ®—½=l�{iIØ÷À'¾ñ‘Ïp8_úñC 6.bsOä$?eÌïröË þôç‰s9ÈAþ #è ÎÁ€?ƒQÐغv²;íÚb; ê“c6(΃a³×ØDx>úœzÑS!kX8’ë ŽUìÞßgD�Ï;ì¡â€Dö ñqîqE%-‰Ä$šŒOLþøG()6„мb·¨º.²Îubl`ì8»Ön‚¸S#20˜ j Ž2¤Î¹@¸&ÃY9È£ó*qLdö‘5¼ ä XHÒˆŠd$â|øÈGÿÑDä‹%/‰ÄÊmre›ñÊ'cJgŒrtW”Ï)g„@&¥h­$£ç€FZZЖl\†uy„8öR>¿DF0‡Y̶!3™ÊÔ3¯çÌÑÍ‹ àë"¡Tͳ]ó‘Úäæ^¼YIš`Rœš#gWÌ #tª“t§ðê˜Ê/®rŒ¯,c,Ï8K¨Õò–ÌÈ%ðvÙAÛœ‹C%*¦0uPœP¡ÇdhCãÔLVQ¢¡¨E݃QŒ9›�d7?R$Žô~%ýÄIÉ�ÒºÔŒ”¥Û_`Ü™x‚Qž D‚WAJHðv9ÕçN{:–aL �!jQ�Z¤F©KmjFz7ˆÞlÿª©ª/j>kju£‘ÜfW=úÕ…ˆ”Oã$@9?Ç,´*C­ëd+OWÀÔ½¦ñdÆ<ëêÊ»Â2¯²ÜkÔúÊOúô�}×`SØ¡±ÎB(Û–Z‰Æb„WOüÐÏ%Õ³ˆB»ÛýCw½kU¾ìã%ïK°™MÎ~§ŠuXã'Ö&’Õ¬©¹X:À×j1¶p�­\kKW»Î¯zMão­ÖF¬ýs˜ýqWK8ÔGX¨ÈUn\K”=râ¹Ì�J®0êþǺòÁîN¶Ë]ïv¼{ùÑ'È[^—œ—«‘X/h‘!Z‘Ö´�‘}b_Ó¹”‹dð"mmàó¶ÀbÿØÝ�û™`á.˜Á”àЃ# á ¶Âp¹ðP2¼a{ø©× qnF˜ëäÄÚM±Š-ëž¿x¼æÝjzÓRcoºwrðí¤|O ÊPúÈø2*‰¬Ê0Î4·5ÝíM{[A&¯ÑÉÁ¬³¦Lå*ƒåÊX–rù°åt _^*‡y!f @Õ ÆÍMRXw7y8äS'l}ëEäšF±à5nZñk`CÉQaÊC±�m‰&¤%Däwº§™„ÇÓ¦6¯cQ l¯§ra²¯Ò¨=íaV†&‚:FGõl¥ ‰>•Q"Êp´Q ¦ÍóþC€(C Bú„û–š­L휩Œà—ÿ¯T-VKÆÕ%�ud]6Z›èÖ¸ÖõŒ¬ík`ÿZØÕú±�]ld¿JAY óšíìHt&Úkùö´­�íbhÛdÜ&WºûípSfÜÊ*·gÏýkÚigÝ”i7~Þ­‘x…Þm¶wð½d~ïÛß8¯¬.’ƒ'<2 gEÃN¶ˆgâ¶Îõ"vÝkÉd\ãîöf>ò‚$!°X¶ÚNîl•ÇDÚ-y¶ï²íÍtû1˜Î�%î…�Ûܧ@÷cN't°ûd—;zF’>”¥§¸éOÏgÔ¥¾¦üê£@Ö·dfý½:Ö˜µø&7öN”ýì±ÀxÆ7Þ¯„‰½!ßÉ@ÿB÷ºÃ‚Ã'>ÊS~–•—¢åè{Ìÿ>óÀ×|ð8µs†�¯rñ�§Äé¨/–¡‡¡èˆ© s¼Ç¿È#ºÉs7èØù“?úH?¨Y¿l¿Áx?ç™Áø£?У:ÑÃ?ƒ[µÓkµþëºÿƒ8×#Ø#À¸¸´S;\ $$¹{…´)9á£@"0¾ ÌÀjã5˜ã@„$¼ê3€ÿë˾0BÁVè��ù¾ð¿f(¿‹ðAC¨Aõ³Á§©7{ã<¾j>B =ç Â"D¸#T8ýi8“øºdÀ!œ¸a²6)l ¬ÂYh1öb˜�˜¬IèºÃ0´@ä ‘ ÔD^ãÀÊ‘ ûš6tC rk (AÀ±Ð¢#¿Ê =ü>ôÃÄUÄ!ħ9—C\ªúkŽEdÄT3ÂýC½Î‘Ä’ DK$DÊDW|‰Nd;ŽóŠP\˜Q¹�P›’CÅ»Àä+CM„E“‘Er¡6-²ECiºð9ƒàÅ�aÁÁh:aŒA�àC[AF D$Š|sFDÄÔPDª ÆÿjtÄkDÂl„µId=& @o4"pÔDq¤BrĽ9Ç^HÇÞ+v\6wüxÔ;–s9W¤Gc°GO¡6¼¾ÊèǵøÇ€T;íÐ"`¤Œƒ´ ôÁ…̼îzÈ¡ˆHùxF…ŠF¨¸?ŒŒ ý«®HôÈmI°k‘ùFgqEÚs‰qä G1Ç�E� Eæ‘I0|ÇUÜ�VtE8ØK¾¬œXŒ‰YÄÇü ~J¢,�Ȳ+»¦£¨aTÈ5�ʨD÷£ ‰œAŠD ‹ ¸­äJk$BmdJd¯É1KCAËó“úÅ·DǸTG�˜ËR˜É븓;ÉKMä˾ôË�Ì{ôÉs™ƒÿÂìÇÃ$ˆÄ<‚?˜ƒÅ̵ÆöºèŒNÈ”Éüƒ@ $/ÈNí¼Ìù[*¦ùÎCÐNíDò,Ï 8OôìÌÒûLü ÍÑü¨Ò$ɳtÅÔd–Õ\ÉÖlÉ×|I‚(¡Ù¬Ë±MV¼IæÓKÝ„ÞìMLL|<—áôG)ÊŒå\ÎæœçŒNèœÎÔ¨Îë¼ñÌNîüAïÏð Ñò4OôÍ?å@Õ AåB�C ÑDÅ�EÝ�FÝ X•ÕIM$}»Ký„L­‰M…ÒNýÔûò„P½R-u.Í1/EUµ S{ÓVu3�VIå„6�‘7eš8½"ÜUÉ<_ýU½Å 3-Ö”8ÖdÍ�eÝÑf}šg•‰h}ÔYˆÔ5­VÿX¸Ö�ËÖm«(•R*ý!+×rm›s �øÒuUÕveUWey­Xz¥U{µU|ÅU}ÕÕÍY�€V�íS‚•Ql¢Q›²Q¦…ÕÎ@êÑ»øQmqTÜb Š5Rk­Tlí*&} 'U†ŽýV�U‘UçIPS5¾ï`×q×–í—˜Ú·©Wb¢ÙCÈ×»Ù×�½ÛíYŒ Vé@™1X”@Ø£u–¤ÍÎ¥UÔ¦eÔ§•Ö¶MÓyU˜+†kÕØÇPÓ!-®åÔ�}„+êrÛ¶IP¬è‰“5ÛH¸4è¡ µu‘ u6Hu\˜…Û{�Û†ËW»Å[Ü ½ÅHªàÛ¹:ÿ¿E‚bµ§¶�¤5ÑC½Ûõh ˆÍ‰Nå&©…]jåÈ…¹ÉÅZL­\5ÅÜ®íÔ)…Ï們eÑU Ò}Znê�Ô ƒaúÇÖýŽ×�Õy•]¹­]ÛÅÙÜÅÛÝ¥ÆÞýYaý/àÅ�V⋃µ)À�™|³ß*È_€Áæ� �xÞ �_Ë}Ü´‰Üë…Ú¬¥Ëå^Íõ^ð}™Ï5”`*ߤ8ß�0>¼Zßöe]¥Ø×�XØ�U1¨U(¸UûåYüe`�Ý_Fìß_XÛ‚\.^fIàf`fŠæ †Úè•_Ë¥Ú‹µÚŒÅ^mÕZMÍ\oõ^F€’q_g)aÞ4ÕÒu6ÿ¼ZUCY[ji ·�ٞٮپYÒãá»õa"b!¦+"Þ‹n´Nb R`nâcxâ(f\¦âé¥Ô‘±T-ÞXþbv�1F'3öK4NW5Ö-6¦7>ÓÆ¥b¶aÎ[«Óã�åcüóc âd#&d$&%®ÝD†ŽÆ„žRè¥à ¶bŒ56Ê¥„­íÞLæ‹M¥N'tMa”[ã•5”å‹×Sž^ú­cÚ½ãºÝaWfeXÖYþ_Z¾­"Fâ�>ä%Î_EfdažàG®`˜•äô d Î^eîbfîT1WN!²�æ4NßÇåÉæWÝæù•Ù¸õfÿº ˜Ûgr†å@Úˆ¾E ™\v¶)+i’®Á6«h<‰@Êöª"(I‰^Œ‘&/ò">Qa÷�3@˜b <³¤`êX(=/Ó åuN‰y›c9!ï">êð.Aˆê¥ÊÀ8¸r¾jjÜh�èèføè¡ T‘&é‘6é£Û–þ(—v˜Î¢9˜ig©é ¹éjÎi9ãiòé ö j¡&ê¢ö¹Sxê6SêaêîrjÛ€j©6Qª «ÆjÈ=­Î®öêG"ÚFë±&Œy3ë1»›´ö¦µ^ç˜n ¸6¹®º6ê½Ði¼&½þ(¾îX¿þë—NìÁ]¶iêáìÿ?ˆjA˜jË”�ÇŽlãÖ�ÉÆˆÊŽ �6#Ͷ²ö.ÏFîë mKm[F…Ò~k+ i¹^íÅsm’éiØ&–œ˜í(=¯Ãé£F‰¤Öm©ám" kànÜ9—â>ný¶žëáhÅÀË"Ì–iÍŽîîšî Yéýhéµ"m·>mImðlñò–óΉ$jbPïãÛÖŠ÷6Ãþâ£ïÅÏÆn‹üÞoOî‹XnLhî°kÿ— o ü¸îÏîí†ðIíWФž`ïÖ¾ëñÎë ßð¾Æ¦q¶ÆíÀ ì(ñçìîªoÆîªV5ó�€ñ_�Ž;éÿsyîÏhíý¨g-¾’ÁòHmc` Ÿ@r½¨ðô¸ðˆÉðprÚ†òW:_¾s±r,¾·o¨91Ÿt s34—5×òcs•®î7OŠ8_©½ óÀ°s<×ó#¯k¾ðó'eró&ôô6ôëãDo¹îªrøù~ô.¿où t1·tÅ8ó¯ÖŠ4/pN÷.OsPo —óR§P÷îšžp¨Mò{m oò·ãp¯uD’åËõ¶øFwž^_öî‚ôf vañëi1>¹“‚ã2mÍÆÓ 8¸ƒköJŸwü̳»@$S¯vgA@>©¬ÈA@ttÿY‡R:�òq׎rOÎs·ò|[wyk³åwóxßo¡w±÷¢�sa!‘yV$ê`M‚¯ ƒ§v}§…7†‡W;ˆ—ø·ƒ½Š?ôP½õo3÷9@wgéøÃvtvÿƒ�{y/y“§ ”•g–——ÇÓ‘€˜¿ž™xKZ�›?J×yµ[xðA¤ŸÏ¸ ÷ö�#z!±ø£'w\×ø¥çx òx¥k³©û‘·zýް—¸>9Ÿð0´ɰ?âïp¦î»9‰Û˜¡HK¢¨ó(T­H¨Ð: 26Þ¨ l+�—°¯½8¯âùš1>—aŠ}Ù_jçYÎEhØD�7>´hÿgŸ|ÃwqÄw Å7Æ_ LJȧõ $˯Ì×üJâü¹ð|ð}^ý"}¹‹Ó·0gQ}½`ýÖ}ù˜}óßuÛ?܆Õ}äýß7üào‰áŽâ/…ã'ƒä§›å¿žæˆY#œdÐÂ^ Þj˜ãᡈ}Qäe‘F�g=ê˜ç#¦�ÈF’,V¬ÊWæ8åò%L—g>Òdó&‡œ:çðìÉò'РÅ-ºè(ÒJ—®jêôiÓ?R§ªju)€¬Z·ríêõ+ذbÇ’-Ûµ Ú�±½äö­¥¸rKÑ]Iæ.^Nz÷Bêë×,Ø¥KYFeX#ÁH'ÿ!tµ�¡Cˆ#Rôe‘FJj9z)’äH“)UþŒiúÍŽ7qêÌÙÓ§ÐØ@‹EzT°R¨ºWM¥jµ*VÀ‡/^m›Íl½…+7.ÝRvñÞÝ»×x`Ü„YF…¸àÁ„�{5¼µr2åŠ3ª�ù1OHL CŸL ôtÌ#ú÷÷–Ú:§lÆFQ¸ÀnPõ÷Ç�Ja÷ „ ‡œrm5wÉsÐÕõuÕYlj„[¸]wß)žcã•wz•]–Ùfîy&ß|¢ÙW~/íÇ_ÿq �?(Fƒ‚%øÔ‚E†¸$“öTár̹e •rõq%PyéuÙeMVVYwÝ%–ÿØb�-dR1@M¤—0¶×|Ÿ!ã �6¢”yê¹#Ÿ<öæc�²-ˆ¡…¹Ô‰*ªÛ¡6ù(¤Â=©V”^B¥1Vbù“–œpi‘—_ú¦ac‚ǘx½ ©fz–}êæF2ÆI#hv’Æ’ž{öÉç‚vH†€ƒJh£(ª¨É*[l¤Í: Ö¤U*å¥UÆueYzèé§¡~I**¦žˆjŠªšÄê!.¾Ê^¬pÆ72¶â™«»òÚŸ¯Ûß°Ä6zl¢Ê.Ûè³­FÓ¾…©¦Ùrºí§¼  ÅÃ+ꨤŠ[fª«þ´¦«m²«‘¬ïÖXß�?Ñ[¯½~N•ÿ/u¶µ °Ã ð'ˬÁ=GŠðZ•.l­%ØjKÆ^O\1Å‹ îÆ(žyîÇ­F +ÉîÊYÊ·®´rË.K3^2/B3¿ýÞ °Îðì3ÜK=‹ÂSmôÃHoÙ­pL7=ÆP›Êq¹³òÕ# TòÖô�6o®aë×k€¿š�voý"²ö±m¿7èÄ€…j‘iP|ñ…²:ëP¸þº±Ë^ íµK:ZÑE§ ï½£ ðž?|j�,¶¼Ø¾ŽÞ!µ_V¨)Ño¶šM¢X=!Ùkÿ:÷Ý{”÷¿)»ì¿U…³æ8‡¾>û_�Žûf§O’zH¬·Þ=ù±×nÿ{£¸·qá%zç;“/Ã#^jŽg�ä]iyèqžE '=µPO×Þö²ç½ v|Ý�ògó¢+j SÈ•÷‘.~§¢&ì·:ï‰p´»î(@Þý.xôDñ8 öÁ�“� /$hŠéQï‚ÖË 9(Er„´! Mˆr…,,ÝFä7ž^È04ÌŸ$Ò¨ÆbÕ­9;TFcaš *�ˆF”•ÈÄÕ8QRüc¾�/'\ỨHÐ}1-¦;ÕGƒïÙ°j\#n>¡ÉM¶ñ-oŒ£i ÊQŽÑŽ®ÃX ½%ªå5<’÷ÌH(PñÿuV,Êç²rÈEòÒ`�LÎ#ÇIIRÒ†—L£�6ÉI¡]è“^(G)ÊRÎGy§U*±Ê͸r°ìž,YK×ݲ@C¤`z©Îg±Ð…ãZÌ0Gó:¤Tò˜’XJf”©ÉNºå�,`4¥IMdX“{‹˜[éÊor/œ'~…³\`—ë¼(“ÚL!Æ3%ó­zUP°TŽ.}é@½ …šré¦|Ê©YÁ‰Ö´j® –½l[‡õÖCi1�tý¬èÀxWvt’{i_¥úW’–™Í,a³zX�r•  ìcŸ'VS�õ5:=-O)Û¯ËbÖ•B=Qå Úå’Å®YªAJûTàF“¬2{ÕÂj¦�‘ém *ª°js¬�-+mÎÜžV–¸UÈl¡6«$t‡¹ö Ëè6óÜH¼'>c¤“3V"Â_¸À{80‚Mc‚3€e„WòºVPJËÉPÑ6•¼ÈnoùKV”u$ˆb8JQ£ÿVŠUÔû²¸gùÕobú’ÿÒIÀù+°�|`3xÁ–!„!a×Q¸f †ñ¶á»t˜[î‹VDœ çï*'Nc‹³lÔ»SƘ q€2`ÿBÇ;ŽI�}|¡Gø!®0¥*•d s8væˆ åÝP™|Vе,è^r9˜^³�ÉGæ2›9ÍŽ6Á�íä!C¡ÈGvÄœ¶d24™KyÞ³nú\>˃>u ­TþÎÑb¾1™_J€G§9Ò¬›´›‰ ç�øÈlJ®³îüéd�X�ø«2©�êe·OÕ&ò2¦àDËnѲ¦u�m½:\çàÍFVK¯eÿök&ÛÙÉx†rˆ‰=ecs¯Ä†Xв™-ï¸9{¿ïyO´`�Çצ5ßRFˆn&ܶ9Z§/3l�…šÝ°3¤rç-qŸÕ{1¾wòÝ‹}ÓI„Hø8Èÿýh�ËP„%ÊSnp¤ ¼ÜžF·žuÖp–,H¾Žš8Î} Ì.cÌüÎÈCþRl“Ü~&w¸ëR®òÿ˜­åÁ6÷ÂAÝ Ô|¨Ï9ÖUñ‹ßÛçtzcÐ?.rG�uGg‰÷”Žò•Åé†yÛ̼ÌMÅæÈ:Þ!µu‚`<^wØÃ>öZ»¥Œg§ôëÔN¶/ÂíP‡»ÎäNw©Ø=ï–_ÒÞYÝõ%ñpð; ;Ÿí—<'W;ãÿrHD9òfžü*ùÙ' !ù,@*tüÿ  ¢ƒD*|İ¡‰‡#>dD±¢EŠ ~ÚÈqŽÇ�œBB™£¤ÉD(SZYÉò�Ë—«bÊIJJ•,WTT0ÀÀŸ@ƒ J´¨Ñ£H“*]Ê´©Ó§P£ ì¹SáÂŒ�$j5q±+#¬�8vüè1$'š&OÞL”såK˜2cÖ¹–mÛ�=¥êÝË·¯ß¿€¥ŠÐ*°[%z½VìF²eE’L›£n[+o]Æ•;×ò݃y‹Mº´éÓA +2|k∋-6v yŽY´”=çìÙsóª¹6×^Æ[µñãÈ“+'h°°Uį'ÆÆˆ�õëµoON[w'qÞ¾�ëÿfù}¹ùóèÓ3UÍzôéÔ3^ÇY;Ê•×zÍ;@øÎÂ}ÆSqêhà�Ëõ@{X9ö‰V]9HÉ„Îg]mÀá×Ý~ àá‡â­µÁˆ$*ˆà‰(¦˜‚^´è"~Î"㌧Ôh£„Nh! Î¥¡~ö÷ᇠid]$–ØŸŠL6édR,ºØ"ŒŽÍH£�5â˜ãŽ=ÖôãMû ÈÛ�y¤ˆIn`â“l¶ùd”RR)–•2b™¥c9êha—¸q¤w’iæ F¦©æ’n&ªè�p¾HYŒtÚyŠ–Zˆp‡dªi˜a:$¡„ºæ¢¤–š\£S>Ze¤vRªç|—Îÿ¥é¦œ*¤  š)*¢¦öê«q²ä›ÄËÁ±ÈrYŸY!ÅZS]R¶hè¯ÔVKm°+ [,±È&»'dRâMÑzaí¹èöŠ­ÚnÛí±Ê’nZã¦TnºøæËæºíûn¼ÍkR½(Ý«ïÁÈïfø5ìðÀ>Š ¹Ñ&lñÅË-×ÃKì¥Ç4A[1Æ$—L™øÖñÊ9\p»òfòÌ4÷…²Ê,sŒé¬‡”sh5-ôR73œóÃ;Ïêsš£íôÓA¡\îÑHËÊóÒI6 õÖNK-Õ'­)ÖJÊÌõÙC{'ØÎÒÄsÏÑþL ÚtwMæeooKìÛ—•ÿ‹rÝ€žZyëÍw[~“)øâ�+Xø¶‡ç”ø�ŒW޶ã<ë-Fä,imùç[+è)ÊŠÎ+è¨?mú˜¤¹:ЩÇôëµî:í²ç^3íØ^:îºO2ï¾{È»ðÈ[L|ñÇ'ï|¾ËûÞüóÔ[½íÓW¯ýöÜwïý÷à‡/þøä—oþù觯þúì·ïþûðÇ/ÿüô×oÿýøç¯ÿþü÷ïÿÿ  HÀð€L ÈÀ:ð�Œ 'HÁ Zð‚Ì 7ÈÁzðƒ ¡GHšð\ªH¡ !ÁªP…'Lß SØBÎ0†Î›¡*$ÁÃã‡@ âÿƒAÄ"þâˆH¬! ÷:nM‡=ô¡§XD#"ñˆJ„WçD¨A1Š’˜"«Œ+bQ‰[4]ŸöÅ(ŠQˆd,£³˜FÑ­Ñim”â‡HF3þ‚Ž@ÉÞi–GîˆqôcËu™·Ìm�%³á �AÉJNñ˜Ì$6ÉIE*‘‘mq¤O i².㔨¬d%'ÁÊVfR“œŒe,­F¾ä‘¤¼˜)QyJUR²•®|å3dIL2ò'‚ÌeÂvÉK_˜¬æ0‹9K4xÊÔ% yÙK_BsÒ¤f,5WGÏeS_ÌL¥7¡Nqn’œ×lâ9Ï•Å):³+Z‰„>÷Iÿˆ~ú“ ”á$yÄ4ʨè0‹Y£$扜z ñ›ø”È>ùéÏ~4-Õ AõrP„ÖP¡ =ŽCƒÑ‹äs¢‘¨¨EºÉ�šÍ 3ôèGÁR㌈%µÈI'ªRB\Ô$µp锎Ê ­éi²ˆ‰¦:5§q%zúÓ’u¨…ŠQešT¥–†©Nm*T)"Uª²” .…ÝS¶êÑ®zu4-bXÅ Íá)O‚Èë?ÏšV¢6…­uë[×Îce„Tó*ˆ½b´¥})T¸¹Œ£²P¡¼È¬fû—Âã°‰]¬^WúX´FV­N¡¬e‘ FÍn–³}ñ,h¡9±ÿ䉌u,P!+Ô�2…²”ufB[ëZ^À6¶,”ë\¿Y[ŽÜ6·¤Ý­i{+Ù¡ãºØ.7� ‹îz—Y!)./txܧÈv¹´mÐ]s]Ÿòõ´~ v³«]uªÒ»ß¯xÉ[Þ¦ø1±š°€w^N\æKöŠ–ý\_6ãÁN†„'\‹ [¸Îð"6ÌañN«¿Fùo]/"à[¨À.ËŤ´`36X•Z€Œglá gÃÄôpš@b3¸Äš 0xS,2Ï�ÁÛõeŒg,ãWøÆ8–¥Ž“Ä㢈˜]r�O<äˆùiÅ.jñ_\É%3Y+P.�;7ùá* åÿÊ­Ì2�…Ì,"¯¥\bF"™)iæ£Êk&C›Ý ?ª’•r.1�íÓ'µ€¹Ey>âž�Ñgk¥˜Ît ·5¢z H$…¨=‰ŠhÙÄóŽ�í…Hÿ‚²�“--‘Lkz͜ހ§? €P�z•¥¦ˆ€ËØ©z.à otøŠf;B&•Ȭpi[7bÓÅê4 yíkRätØÄ„±�M“dÛjÙ3tö³mYÏúÏ7ô yÝë#ŠÚÛ#f¸‰MLr—[@ßé eÕÝlhëTÚï–Hšå½czƒÚÞ¢þv€Ã-ˆ~û æxANpƒW¤ÒÔV8 ×„®›¥X�M°Ìy\Ÿ]ÔBg2Ñat= }ÍJgúÒ�þôfD¥TÇÊÕ±>c­sÝë!ûnÅNvØšÝAzÑ�™¤«Tîs·lÝí>k©ç=#{·zÖ±õ"t}_'VØ Ö¢Âsöð‰WûâÝÞx¸?òtúÝ'zù†d>í2ö»çÏ Á[• „?ˆQ�vų�ñd!f.–Ïü¸Ë=öP¯<Þ«c¡Ûo¾óŸ½FŸ™~°Ä'ÿîe¼ö¶¿=–ÌoþëŸ/ùºÏ~Ÿ`ÙѽÅ?~Ýg?ð¢<é½`+B‡üP~È÷NV é·|Î×tJ4Eß4cûä Ÿ÷yòtõÇyzø·}ú×}-ÒnöÆ×v–0‚$X€˜ T%K7õC (cèØuˆvˆ}¼ç{9°Ibç�U‚ªw|z@‚%èd'˜‚ÕTC M¨Oƒ;b}}g�»‡�½—¿|ÕÕ_>8c„Bh &x€í4Nz“„À´„‘Єø„™w}¨}Üç}§…?‡xÅ÷ƒ"ø…a˜~cÈIšc†­„†j(�Õ׆QhƒTˆƒ:¸ß÷V[ÿH~«÷…`H„b(LÄô‡¥„.È„0è„…¸wn8…p¸�r˜…óTH’P‡u8mÓ6s;µOk·všÓ´X‹‡õŠúô\áFFЋpî&c@�—ÆXøq‡‚Z§8C ¥Š?ÇŠ³æŠ…R±Ht³X‹´x‹Õ8QºHl¼è‹ÀL6ŒÅxŒ�‘Œm±Œñ•M¨�¶ �LF�!u×èÙ¨�ÜX�(õ�ŒŽFð‹Á8æ¸uƘÈHÊ8‡ÍøBÏ�ò…Ç�u�ùh‹s…‹‘à�y�IŽ3V�Ep� ™ iŠç„Ї‘¹×n!u·u‘´8mZq�$ .ÇÿÖ‹9ŽQŽÄh�ƨ9ê˜ì˜U!¥’sÅ’k/Ù�ybQ,Ú8“ 6‰Žò’“â8�"y�B©�ëÈ�)9C“·’,É”“yòR9•4)W‰�8©j:ù‘=’?9’A©7Ò5PŠP”ŽH–ug–‰–& –9–Ä2•}ð–Vy•|2uÉ“&à“ç˜_™ƒ¼µ€éU:T–Iy–.™–N™#2Ù˜U q™51™\™—^É—¿7]œ)–4ãI58HÆK VJÙt2 ­0œÄ“zcm�ð~ú´šs ® ’›{¹-}©Qi›ø¢C‰4GÖD7»‰J½éTÓÿŒœÄYœy¢9È©œ‘ÀœYI—[ �)�˜)›šI›Ñ™£�}Ä�¹Y7ßyJáÙTã æyž­`œÛ²žÒ7Qî0Z¹“¯y™™yUù‰�¿¢Põ…J•Сú¡zL)ŸUtH?4_×åG~4E“rÓ¦e’b 2:£Ù^Ä„i©eç'N.’a}†i¢6+A/#Q,.b$$£¡º Ú¤• ¢(B¢Ed¢À€¢Â ¢f4E÷袳£v2£4º,Ìr£É)�:ÚzîÔ£ö£�¤×1¤FÚ"HŠ1Jº¡N ¢Pz"RJDTj¥XzEZz�\Êd^Š%`*£5:¦²ÿ„£f d%9›±¤¦%À¦njpú2EJ,GZ$I FKº !0ª¤Š{Š } Š¢�ŠDƒ‹…:cZö.�¨¦Àšdš£�šŽ¥5©-â£'c@J BjD*§œJ§žj§ ÊMÈIª¥J§z ©ºªóÕªGôªk«26«ïb«¸Ú¨e*�gJgå«^¬9¬Åz¬sêuz1wŠJÏ ­!`ªÝ9¢3GÖŠ]Øú ÚJtÜ:ÞÚ-¾p°®±ä¨äº«æÚ«œD©–J¬oj¬qú®ñj1ózJõ ­CÉ®¥ûJFTz‚¸p²(KLë¯Ø°%F«‹°m3œô‹ÿÀ°?X®q®û«f“w)¬mJ±˜j±šŠ¬bЩ @9£PßÔ±Ñj’mÑ$Õš‰Àd²({²Ä¤e÷JY°È³;³PP³¿ˆ³\Ht:ë<»I¬À®ë®É ¯Ë*¯`ô´Öf¯÷ –9Aµ#[¢VÛJX›µ[ d]‹_ d´j«dk¶7;®9ë°; ±n볕 ·r[´t›´Êš$# ¢;ºzkk|û±+Ñ$̰º¬;sßôM…›²²Äµ×èµ,Iq�›¨�»I6‹¶�èç2dP.o»®CÛ®[·»(®æG£KºÐµ£ŠºV€ Sĺ­Kp¯ M±«µ³‹¸µÿ«¸Æ·v¸û­º 24Ë»g+¹i ¼»8ÄD¼˜;±È{´{·¤Ò¼fô¼¢[º™vº~ËÖ+DØ»º®»½„{€Yë½±D»±h»?H¾á–»`º»dлìû»Á ¿²$¿éº¦š{¼s›¼žk· K­:4CV:FUÔ¤…0Œ0ün�G±4”;�~d¥“—X w�GðÃ@ŒÁÉhPÄpÄÓvÄp“s€ƒ%ÁPÅœ³J¬ÄÓ–iEŒÀ+a(£«”p — d\ÆøÑ³c‡¡É‘Â*Œ¢,\D. ÃÃ(Ã[GÜdÃ�Ãf¤ÃuÇÃpû»kÄALClYlų¦ÄLÿìÄ9ÅRÌ3—QÅH­Ð@ Ê�ÍD=CÌ bÜ×— ½!ÀK=ÇÍÊÕ90ÕÖˬë×b¬‘Òë7-âÕ&ÖàUÓù¼Äf­�÷ÅJ[(i¢Ù3VÉZœÓ˜ ªíL`ç6Ýãunçx¾A®JCÞçîç�Þ"ƒþÐR‘E“6sJ[7€±Ô‹EðÇ&€ˆFªŒ y†@¥ÿšE:d¥Î&‘•w†Øwk·Ï5~Ÿœä…0ØÓæÔf�Ø-‰Pîþ:¡eÓvX’X€®pïøÞ–‡ˆI!Ä$]%¾ždªÔÁÃÎzTÎIÆŽìʾaÌ>•ÎíØ*ím<_ÕÞ’²�Ù¾íÝž{ßÞÙ =î›QîQ.cèêN(áîUïŠ ï³ÿFïzèdøžï±ïÑïòï³ð�¥D“fð,)ìE@ì oÇnËÉ~�Ë>ªÍyߪ_Ê(šñKÉÿ*ŠYò¥îÄDîæ>k)Ï +Ïî.ó2Ïd4/„ö~ó® ïÓ·ó¥éï²ð WBOð•DôiôH¿I Ïô¿¯�o¢Ñ.é�]XߨÎõáÆí^ïíDî#¿IdòpöiŸk¿:ñdJYï6/÷tO{ü~÷=Ÿ÷³y_Õ÷¼t{€/�‚¯ðPMøJïðNñP?•rï TÚ‡›TõÜ|õÍfíñÑ_ù¿”`_Ý›O�ÏÔ3úó­©¢ÿÿî¤ó¦Ï’¨_cä©ó Áó”àó÷)û¤1ðµŸy·/�¹Ÿ|I¿ô$ÝôSøô!À˜ÃÀ$(ðÙA„d.„ÔС*ˆ…M¤øÊ⌌4n|ÔÑ#%�€D "YòB”(1®däÈe˜sdŠ¡™ÃæÍ… WíäY¨ V®,RT$ NIÞÌJ"¨U¤ ZÕª"Eš´nÚu¥%°ak�%»ÑìÙHiÕzô¨V-H¸”)UˆS¡¼yìåÛ×ï_À�:\VØpÊ”gyõj±‰¢zôÈ”™Óˆ‘"�w…\tÈçE¡CŒîSÚ´+Ô© ›ÔÚ5„9ÉФ-&¢ÿDн*fÛñèÑ’&çéÚòeÌ™5™æXèÅ9Ïž?ƒz-ZähRNKo:…šHj• á7X¥Š5ïÖ�ŒÕïVŒÖm¤Þ�Pͧ$'’Ú™ßÍ‹WÀÿÀð¯Áºä@‡ËC±õVÒ,²É(³ 3ÍL଺φm‘ÑB0í´ÔPsmDa;H¶Ùj³í6UrÓ­¸³âûM$OB¬8—�) Êh[n?2œóB<ñ| J¨®ª»Ž.2˜â.ª©È»J‘ó´J¯ÁÛsÏ-Ê(£¯>ûðD¿…úóÀÓ °@HLp8±|°ɺœ03Í.ô 4ÑHû°�E$qPŸAQÅosÿQöÌ’qƇÃñ8“ãÇæœ#2<#§KÒ(‘°Ó¯©§ ¬BÊ)«ÔäJ,ÕÓÒ¬÷"éR¦/ç³�í"ÃL+þ@M`ÙCp¹˜c~mæœj¶ùœsîjgž{>ŠÝ ÝÍqÇ�ÖUȤ—Ö׺§³«+êš`+ ^LëF9Zؾ†ÁŽ8W²ùëïl´ùbQ•Õ 3L±Xã;ewÞc�ñ;„v³O‹åxP’W>曯ЄöÖk¤‘B±ÞúaÑ~û°ÂÚH-ÄÆNTÙ|:y¨Ò‡¼²Í™êNH¬âWÄ?ŽôêñxçußÔ_£ê;>�w¼‹O 葇‰o|œøQÜò@( ˆW  `c€Ù­¦tÉ]o¸ÿ;ß½'lÁÍð,T¼ã‰ByËkóž=õL¯z×#Dö¶§½F�og ÃTù q¾•¤ïë›Ã¨lò>çH‰~öë þˆ¦¿›tN*ýÌÿ¤@>|ðäbo8«5pVtŠÍtÁ¿d° dD٢źe„$4áåR¸ÂäµÐ…‚!cdHÃ.ç†8„QÓ>0Òˇ@Ĉ‰hÄ Ñ J¬Ÿ§†âÄÈ]j9R¬ÿbÅ*`Q‹]$¥|jÅÃ02Å�d4cÐè5„�nô㘖9¯Ž(<Çž÷Âdyå�4´á s˜– e•G[d´ºâÈxAR’”dâ%)•ÉÿqÒ“~¥(?XÊ.6l™© ##(› Zð•²c‘ ¹‘[…íó¤g+ìyOOäSŸ¹žÝx) _þR3}&õYÌí3ÉüÌ8[—ó9}ê‹fû¢!QÓ’+Á¤¥²É¿uS€ß§GÒµJ’“œæœ`:°NvÞÆ�î:K<#FÏzÞÓžúÜgÄ:t îr©N *PÇ´+üB ISC.”¡ÒB"J¼<šD#“B¦Iž%n#-š&I%µ)†4éKjÒ¡ô�*M%KÍäҗƒ™i£>byâô:Ý)O=‘K ^@¨D-ŠQ�õ¼ø(uÿ(Lµž~¶G Ì*”¡C  9Ëf…«ž0«ŽÙêÜtõU«„5_M¼¦Gmò@mª•­|øÑ[}×1’‘®å$cKÓ©×½Òn�®ÒÈ_ãXœ¶†=¬OG“ØÅj¤¨½|l…t÷ÁÑùÑ 4´¬ö0K ÍNU&žu]hDZŠrµ} AmUTË4޶¶¬QCk'e{ÅþÈûå/üû_ÅE®NÙí�ìÚ¼7"}-¤qá‚ܜꔹü,¡?›ÖXêº ²Ä®ô¶{½îÂâ»áMfgSùYó>3½¦Ý$F“ÖJ®ÖšCÃf‹f_ÿ­¿´]ûû_ÿX$†B�—sà¼$X¯ ÿîÖŠÛ›G°ƒ%ì„�«K í®f®;Àìt† nße3[HµlÖÄaDñ%ij¯I6Î(Œ«_»v7Þf_DÊc¦øx¿@²�‰ü#èìä£ÝI„oÕ S&Ë’¸Œp0H ¡!mˆ"!ÁμJ¸‘ÉÉìCd]ë¼â•�¼þõª—/�¸Efî6·\ÜL×­"sâq�[ K$ÏÉQNh•§n.ŸUÌ/söšï‹ÅLÑ9Ïwîó�$B/ Ñebt¤]éeúõœ^FÙDM!ÅkÕ­F¬k=ë¼’Ò×M?Iªˆ}/d¸ÄÏþ=‹ãlŸ«Ûu’è�o"ä ¢»[ìÿnò”få(k¹ö^îwÀWÈæƒ¿Iá �øõ(^ŒïƒãçùÈOþ—•·ÞåÏ™Í÷™›�OôçSzÑ“ž<§{êUÏú`¸¾5O»ì×N{Û^!p×½Üy?œ’û½à‚á;/à».ñ;™›?šS>Áùåp¾žû9í :š:Ù(ºðˆ<Ék�¥;7ïƒ:ç�º*"?è0?ÐK4Ñ=3¡t?±ƒ?ù›Ř2µëüË?fz;Ü‹»U™;|A3€,@Œx ¤ L¾9Áœ›+"‹² << „  Ì Ü¬í{î#„̼Ü<ÿ1Až@ADSÁ|Aÿ7´ Õ4;4 $4ËÁâAèȽÝ[�ÞS‹!,B½c¹4¾¾C¾: <'d>)4ãÂÄ«ÀÅ»ÀÆËÀÇÛ@ü Ã1¿2??CCESC„cCÑ{CU¼ °ó $xEX”,cËCüÛÃÛ[…{òCÿÄ t‹A$´XñŠA‚…㋹�àDHÖ!ÔÇþSÊõ`ʦ …�$¬‚4–ƒ¤J«ÄʆÜÊ…8Ë.\K± ”�샎ìÊ´\˶|K“LI(XIlIQä‹»„ITÔ:F[¸½ôº¾ôËLÁ|ÇÿùIÃl¾g4<ÓcÌ\tÌ?TÉlÊÊÔ©Ët“ÌDÈÍl�¬ÔJŸáÊ® M°Í)ÍÓôÈÔËÕdMׄÍÈ“M»Ä«¤YÁCÈM½ì�št)ßtCà4,žìIx,LÁʹãä¹äL4|Ü æìEç,œÉ¤Ì§´Ì¨ÄÌ©ÔÌÞHFìÌJÏTÐä@Ñ슱¼¡²ƒ³,O‘<Ï·LϹŒÍº�ÚL§÷\Aùì:¾´ÏûTÇØi½Q‹4 —°È_ËDÁ‡�"å ùÁ öóº½'‹l ‘ëÏîiª×"#åŠÎ|˱H¬ÜkÒŽ8 `Í^À1SDéB8Ó‰•çñÇÿdhS7ÓÏìÊ’`ÒŠôˆa¸S<ýIÓ¸ ÚØ�ˆä@å"•À¬Š$…Ÿ#•’8ŒÃÅÑŠÔQ í7 U!mˆA5Ò#=TçXR{âÒGˆ„'Îx”Ò³z *í�+=É,ª-­Ó.õR0S2U3ES—€›Ç`S7mS8ÅP9% :�;ÅÓ;ÕÓÒàSšðS_TA-ÒWòÍE�ÖiTÍÑBŠHµ„I5+e­�K…„LÝ‹#UNõOmPÕ¡ Ì(Åž)… Te‹U5ÉV½€W%ÖX=’Y¥U\(S �ÿ? ÔqE#i¥VŽí kmleWm—È Ò¤Rh­¢L×uU×øIS5§yõˆzí…{ÍW�ðRÓ½ØÈX‚5Ä]-œ^õU1�S�dXuuXˆdíƒoeVgÍXàÂÏŽÍÚ� Y¯ØÖný”å•%ÔsA—uX‘Åw ‹™¥RÂ²Ò },­-ý8PåYŸu E:¡ÍU¢5X£=Ú„]XamX}}Xˆ�Ú©µØfÅØ•½ÚßÌÚŽÝÚGÍÖ•ðZ“¥Ô°[µ2[V'mW(e[x=U§¨ÙŽ¸Ùœµ[‡Å[ÖüY[ X\u„‚5�ƒ}Ó¤Ö¥-ܦ=ܧU\ÿŠ]VÆ­ÚÇÕ+¬•Ü8¬ GÉáC�ŸD]¡ !a“4qó=Ü´Î å±EÚˆ0¸‘¹­ÛMXË�ýÒ×Õ[ñÇZâÓŒƒ ‹Á VAV‹|Út[á]„‹T«5ÞÈEÞi]^®Åç�Gè}(éuêµË–ý\à ݕØ^°èÞ#SIšˆ°µ”ñuUÖÉó%ŽÙ›½aßö¥Ý¿5�øpSùÍ]!¦]KæÊßå¨Xþm\ÿ-^˜:^fÔkËæ=�çU‘襉é-�ê}à6ÝŽÈ^ ¶ ö—×Ì`L3\‹ä`V¥[._° á&ák1áö­ÝnÓÆ…VˆÿËžýªu\²;îa±#àÊÙîž’ö‚VQ%fâPU‰ãÞäñ^*¦²Þ½bé`|ý໊/ã±c÷] Zê‹„E‘5É6þ�7ŽãžcÈ¥Q;V=<ž… ¾„!®�"ƒ#Œ$öÜ%Žà&6d‹@dPPd1Ð`°Äb{ÕâHæbÞ×J¶dLöÛ¡ØäGèdKødÙe‹å£(åá•ãä àU®V~åXÖŸ…øã@î\ª¹^ VÛ¸õe`f‘$fœ5æ|�d6K&‹fFág~�2N†3Ncæ]6,f îßgEeVåo޼ò ÿ‘¸}cÚà9•]T_a�^Ë´@ŒqiȰ0 sÚ� ±æŠTŒ¼­˜³%·xžAy¯àÙ§�å Éi¥¼£.™=BéШ„A%Òˆxh¤F›ˆžhĨh‹¸èV�ÆT†Ö«Žþh Ž‘Æ’ “&#¡^•ž–N_—¾ -RÍ ™io›†Xœ&,�öVžÆ Ÿ¦  ~ °&ê¢>ê¤þëYjæ¥è±èÉÄhš˜jq­j˜ºjVi­N‰‘>d¯.�“ê±.ë¹=k#Hkó\k¡é®xkc�k�šëü¬ž^ކÉk§Øë¢–¿lÚþ ÁÎQ¾ÃnJÄÿÅÖáÆþ�~ì¬Þê®¶„¯jÌ&h°Ôì,ælÏQÐÑ ÒÆSùÌéˆÙiÙà•»– ׆Øîkˆ¨móî‹Û~ÔÜÞí€ìíßfìurlÈ6nÊFnËëå®_+^é³hé—þ µÖ ¶f$·öÒt‘Ï!Dm]Qm»^¶ò»`åFi¾ÔÙ>ïÚNoW^ï§>쨮�÷æháÆjæ�l”˜ì^®ì>¸l”Îìþ6ëÿ oKe¬iŸ4(·‚5r _rorrªqîù¦òã¾ò×Îï’ØòGèòùò±ó1'ódf‹ê^ 4·q5Çq6Om×É 8·‰˜ŒW:êØÆs ×ó¦.ì çíÏh@_lA'ô)/ñ*?qûNqüÎòà`tG¿H¯IsJ¯t�¸tŒÈô߸qËñªút¼õuÓï ?uT7r—’èÁ^uÝnõö~õÄŽuàŽï'î§o\GtkçõEïb.×//ækv"(vP=ö ù½O@6fç/oñt2èBi§v¯slÏvÚf.nÇmo—8÷NLÿr¿s4’òt7t+çÈØ�¼°ñuytzóaÇw‡= ~÷÷M÷±€¿‰½æÀ‚—sã|�–´s…¯m†gê”Pòˆ—x(W=‹ÇVu…’ÖøÚèÂŽ‡÷Fÿx`ùHy’'¥“²߯•·‰–�¼—÷ñÃÌ Ù¤ùšl檎êðÇŸÄE… KpL“ÙY”EA:1×"y6ɘ{ºW+èB!Á¢µDœìÜ›Ñ"-R®(+ ŽCAfc¶ïøÙ”OfƒQ¯SÔ¯·ð°û" ûx4û�GÑ´�µgûÜpû0‡ûGfMº¯{ÚÀ ¼w½K¾ÏJ¿§«À'¬Á'‰Â7¿ÃO´ÄŸ"ÙlÉÿÆßM|ƒÁÈ·yâüÊ/œ²×¿Ì_Ï�Î÷ü‰}"}ñ%ýÒ/�Ú°1H}/X}‘lý†|}•Š}�š}A¨ýÏ»}èÈýNÚ}pì}úl?8 ~óž|±÷Šãx´Ç4bça+$bð„“2ìåða‰ˆÅPcE ÁŒ•¼päãqÈ�šF’|eòd­”*s°lé’%”˜2_æ dó¦ œ:9ñìIóçËUB‡Zå(RJ—2Uà)T+R§r¬ê*TZ·ríêõ+ذbÇ’-k6l‘´j°mëè-Ü!rç’©k÷nݦȪêëW àÀ€3$Bè0b† Mÿ0n,q"Å‹bhVõÈG/I’Œ6sŽäù3‡Ð¢iÊœùò&N�9{úêº(ìUH“êmŠõ©W«o8ëû7ðàÂÃþ*n¼­[¸oçÎU�×î¡èÒ™‚õûW0vÂ#¶åÝÖÂÆâ—¨(™rG�z°O0’sçÏžE�~Y:&MÔ6U¯fÍ©bE®µ[QF6•Tzñ–›n8ø uÃI8!…Áwr(·sC8÷ÒM·TuÖ©‚v…ÆÝaß�7ÉxãEt E4YVÕzí½#òÍG¤ÝGÓsü âß È�Dh‚V(x›W¼=!‰j¹%—[]X\†nØÿ¡‡:�¢ˆ‡D蕉' † œqª¸‹.†#y‘øÒ�åÈÞŽðù �AÚ7äKÏ-™Ã“‹*ò(¤‘>úd”RÚFeWV^¹Áš]zúéoj­•ᆎ�yæ]zñe"vqÊ9'‹„(v§x�Í(Õž.õéf™iÂc�>*diDâµ(²/Iº¬"³UÛ¥XUɦ Z{mY¢¦f©§¢šWS^}ùË1åš›ºéº 眆±8+Œ2Új€6z„cS¾þÊã ÃZl¢Ç&;`Q•2+©³U@ËÔ‚™R+-¶KÜ•¶Ep;f‡ß‚Û©Vãš{nºè®‹K»±Â£­%àškK»öšÿ°ýI¬i.):0“Gyp¤ /¼TÃ\= ñÄEc[ñÅÊyû­ª]yüñ1!‹¼nÉïΊ²­’±Ì’Ëùú³°3ÿ[sK7ã ›Á’ã�K¾-©ZŽù¿œ'â9T¡“^ºé§¤®:O-µþzì²ÇF»noïþ>üÚý;ð{÷ÍÉße.ÿUU¼-Ï<Ԝǣƅæq.‰\&—å\O'™3_L´Ç=Ð9Htß ŸøÆˆÕ�/MéS_QØg÷ů„&4Ëüè¼" ¯xu9ÿ‡•ÿA¢yãyž&¢wÀéY¬z ¼œ³×9?9…‚° éB Ä%jpƒåƒÉ}Ðg ÂF„ý«Ö ³¨Å¯¤ðw+l!þŒ§?äùï6uØ*�-•bNE(H�ˆŸ €÷¾·D&j�ƒQLo¨B@Æ­7[<$"»ˆ·/Þ/,© •·¼36&�”^©G9ëÁQrd]‡x»;æ1‰{ AýXš×R�Cae!)K-*2ÿLŒ$^_8Æ&+ˆ;Ù yT(®‘‡Iû2G!nÏŽ¼AâèN‰J ëu�â�^`³)NEkh³üf k™¡[º� 0´Â} 5`Š™îüÄ01ÙF19Â�Êô$3'ˆhšBš­«fš®y›¶ `›SŠ8º;qæÍ~¸td ÉKÞüòjãy'2ã¹ÃLöp“õLf'?¹9Qí6üô'¢4k> ›m3h7¦Ð™Î�¡m!g.͹Ktr;ULŒ0 O “%lÔäíÒ|:Ó¤ßëç)ÿù/–*Â¥?ƒ)ÃbIÓ­F̦õ^#ÅøÈýñÔ >]§EÛ‰Q�“£ƒÿ‚‹R±§R:’´ˆû|*J6WªZuaX-)B¹*XPyu8…¨DËzÖ�±³1Be«QyøÖ·Ä5ˆs­ã(Ÿ‰×¨¦‚® hKúÒMÔ›ƒ=-…¡ÚÕF‚Gab&b«• �–¸-n›¡ÛÝ >�ø-p ¥²±dÆ=.Ÿj 3Õ¥ƒ"‚TX*Bía¶*íÙ Q«Ý-­–µ®Íle;ÛZÔ6r¸ÍínuÛ[Î7¸@.~^r\ä†O¹Ì%ƒs¥]°HW}Ô¥uÙ³Ý+´»ªm-|^»�Øbb¼ä-ïyo›^õÓ·í}„psBÜÌ׸É}ê}ó�ý~¥¿²ûoÿ3­r]³X–F‚9£àI0ØÁåíC„-1áf¬w3Æð{5ß¹ÊäÃß ñŸû¨°´òÄÿ­ÝŠ[,å,¾8Æ›™q�ÇK‹-s9ÇRËC�ñã bí{’}sb‚ÄÓÂÊtŸ¬›(O¹Îð«òw‘Þk™Ë[ö²ÔÂ<æ —yÈž•É“æ èE#y• U“ogêBYÀv¾ôîV{\+3bÆ q°Ÿ·¦/ÇȦ>µ‘êÊÒ øÌZô¢Ÿ#ýJŠ,MnR{Ú“]Lózbš6.§=½P‡zÔ�Ï©QÍU·®Õ÷I4¬ç 땎¸Öcé«R–•köìº×Þ¶Ö¯7®lðΊØ~6vÈJ�lO¤:4‡%u] åNû³m¶¶X°-mo»Ûßþ7—Â=n=Ï*L¡¦ºÓõãu³{ÙîžãHãýlÑ/³®v¤l-Z¦ð;×þ8È'$ð<·^/v†¾¼ðu·ÛP«Ž¸öä]‘Šßåâ÷Îøµ7¾”Žë‹!ÿy…Fž`r+æäçN¹ÔVžì–¿›®/ šŸZoZã<ß:϶¤¶�€�½ëf !ù ,¼ÿH° ˆP¡Ã‡#JœH1bÊ3jÜȱ#C� CŠIÒ"Å‹¨üˆåB�.ÆÄ8sfB6%ºD©’ÁÄœqB¬ù¨C£2‘5(´¤Ó§P£¾ìèSæÇ m*}HÔ$ɘU½Õy“lV³#·J]˶mÒ¦8›&U–ëÕ—qY½‹×êA¹qQ^Ìû°áÁr™NLx`Ý pK>Œ•adÊ–ç\ù!$ùœk‰¡'PO~ö݆ Ey]aôí·×U÷ 6Þ[Q&Ù“8^)`ä‰ùdsY–©•˜]’É¥{œÅhäœtr‡e�xâ˜çžÉ矤Õä' §%Iè¡� Šè¢ŒV´À£ÜD*)=”¶cé¥ðdªi`85âé§Ò„*ê3¤–:Ï©¨* êªX´êê°Æÿ*Á¬´Ö:+ ¸æšÍ®¼¶áë¯R+¬ÄëÆ±È  ì²�6ëì³Ñ=º€¤“Vz©¥šnÊé§ Šj©¦¢zꪫN`î¹±ÊjëºñÚ믾 ;l±Ä`ï½Ðæ«ï¾RIKm¤”Òs-¶ÙÂé Üzêí·à>#î¸ä*p.ºéޱ.»¹»+¼ñÊ+½õÞk/¿$—lrFþþðÀílð¶ /, !4×\ÇÍ8G,ñÄTl±­ƒ-tDÒJ+´ÐË.+òÈ'7íôÓ¤LíÊ»|pÂ�¢õÖ5ÛŒóÍ„-6Ï=W¼îÑA]ôh’´²KõÜtç+uµW]ðÕ oÿÍuׄ| ¶Øa“íóÙh«]tÛo wÝ�G~èÚÓþËÁå˜ç ùæDtî9à„ø­5è‚×Axá<tâQÎøÛ�K.ûìsRþ/7˜g¾¹æž¸è€�.øénöêG+n4Ú�ÇNûóÐCg»å¹s°;ï½:ðÂM¼ñé"ž|ëk¿ž´óѧ¯~TÓS[½õ×g¯ýï¢w�ó÷¬PgÙÑcòÒ¼|jT Ï«îO«ÑLl;¸Èޱ¬e Šf;»ÐŽ6�í€j[ÛØÎ6©`êøz†"«e°«¸+Ÿ¹Øè>v²a¼ì‡9ûÙцö´élíkgÛe¼Ýíxíí·�àßø¿ë]mq�û9ÃF·±û‹ìRHyÊÌ~7(â-oÆR›à÷Æ÷–õý/~7Nà ?Á`ðƒ§±ÜLÿV8šÕípw:âï¦x=}ñzgÜqã¸Î¹ÁïE‡\à#/¹É¡’Ä+œå§1ÌáošÓãß¹Ô%%kŸÿàA§åÐ¥Rt”Ÿ[å woÓ>ã¥7[æN¿òÈo>õ©W�ÎWÇ:Á…¾õ’ ö»`_9:@ILÙ€üyý@øÂ[áð:F�âòü"âñ�/lÞUlns;ãò˜|à»ÁùÎßãó �»À÷'ÛºgäîÞ�ü:¼Ëw¿ÓXó€|á x+$~ñŠo¼v!yÕ£»ò(Æ|æaßùÎÛãøÈ}ÀIZÓŸ^°xŸ<ë%Ù÷¿Ã^ö³¯ýíq¯{æòþñ¾/6ÿðÕ!üËÃÞÅç<ò“¯ü3|Î×êÑ¡úéG²ú¯¿¾ugO{Äç÷¹'pŽ÷}áGlŒp€X~Îp~ç·~Ç×~î§?¥1õ·wÔçz3v~ØgxþLjÝ\ãW€h†€H_ {h z?÷~CC�χ Ñ—wö§ ø·�ú‡\üçÚ÷8‚¿U‚&¸(x€*¸‚�ׂ/øyW'ƒiCƒa�Ò‡�÷§�çÀ�ûÇ‹‚DxFh‚IÈKÈ„Þà„OX,W'>TX�ЗzWØzÖ§yHx_8„¨]cX€ex†L¨†/Ȇ?ç†oVˆƒX¨ƒZÈ…>ÿè…t†{È\}~H]hx‚z„r†xˆ‘ˆh6~9¸ƒç�~Ý ª¸Š c5gmM4~•¨pex‰Æ…Š è€Ox�rŸŠ !Š”|¥¨…¨¸Š¬2¯Xm±(‹•§zµ˜„ô…‹,¨‹kH,mˆ<ÀŠqHâGŒ‹hŠÇˆŒÐЊËèÍèŒ)vш‚Ó˜~¹¸~»Ø‹÷‹ÛX¨p’Â+’¤þx~�&9�æ‹¶2‹ã0s[�G ð�I9‘ …‡*›§~Çm­p‹7rÉ¢,÷ˆ�ݨzû¸+ýø�°�)�Y� |¿| I) xÿ ‘9‘)qy*Ù ÈÇ‘ 㑊’ÇÂ,#9ùˆn'™ )© g-é’°e�µ‚�4Y“7é 9©“<)‘ù“ó”C mùoIp!)KÉ”%9yO•S9eU)/pëÂ23Yy5I]ù•–cIx xÆ·‘hY”jy”l™”"ù–ДÅ6—‘ä�R¹’TY•y p{90òš¢™�\I ©“ù—…釉~iDI/F‰HéJù–”Il–© ˜Y—4v—�ùoŸy-¢9š[©�°'˜©Y“«Ùš‰ ›Ð¶?�¸–õÖ–’9™qytÞu;˜Ù›ši—œy•ÿ÷ äYž,Sœ¡9~Ôxš¨©š'kf©˜õàDnP,Œ7pÕÖ–·¹”¹ù]ÜÙ�z�: ª°p š‰ÞPžæ šèIŽÐ°ž8YZ¡™š¡ð‰˜¯môiŸ(rù ™Is�ý¹�ÿR J Š  š‰ Jžçù äˆŠôU¡Z“ª¡ŸÐY­xŸ"êú™¸™�醢Ԣ¢+šê¢ª 1ú 3Zœj£Ô…£z¡;šêšB)ŸA¢ÖV¤n)™'ŠÿÙ�Mê¤- ¥R£U*šWš~7ª¥\º£_úœ± ¢"ˆŸDJ¢û9’iº¦˜Ù¦O §0*§ÿj¥5j§YЧ:Ú¥{Ú¡‹I/BZ¦‚j¤"7žšk‘C9”cnGHlmŠ5¸Õyç§€Ъ®*^ä«¢¹9†¤ Hp«±Jææ¼Š ¾º9òB3e©y¯é‚÷ Ȫ³òs̨?µ¤j'õ©Ò ­´#ªkCª¥ªb§š0©Êy«Z~®úªá•«³ª9µš‰·Š¹º«½ú«š¬„0¬)�Çš¬ËrÍšϪRÓú©éc­Eƒ­Ùº­ÜÒ­Ýð­Â®­ «²š´JG¶Š«±Ê®î૨¬Â"¬Ä¦Ç÷yɪ¬À¬è謴D­%Õ¯žú¯û([ªû)‹°˜§°À°äÿP®9p®h˜®ëŠb¼Z±îšð*¯J¯{¯ —¯ûšR(»ms³²,»ŽGø²ž³°Çª k³8«³Lȳë³íz±ïš±ñº±Fk¯!‹¯#«¯%˯M lÕ µ-;µMŠª·¥ªW ®Y;® + F«®_«?k±,K¬k¬G›¶I»¶K‹Ro ·³3ª2y„aITÛ x ˜« º „D»Å„¨ºäð³…´Ck¶Èç±h+²û¹Ñº4#·h*°—›wj¦f™Û¦çÕ¹Þð¹¨+º×Cººeº§‚ºª¶‡+‰;¯¯[¯ÈŠ´@¹mË´¶Kp¸=–ûŒ“ÿ×»,ö»M¼ð˜·ÂW¼Æ»;ÈûÊ;ÌÛ¼†;¶ˆ[¶Š{¶Õë¸×;»ÙkQ…u;ª7·KgM$;ß;· '¾ã@¾+j¾Å'³—§¾ ;ºGTº+xº¡Û¼@+¶BK¶Dëšø ²²K²+`²ØBÜð¿ÿ¢Z27ÀWVÀP£Z}‰À¨«À™{^ÜyP )Á¹JÁZ`Á ˆÁ «ÁóÛÁõûÁÅ »ù;Âl[Â…Â*L-,Lq.¬c0ü42ü�àKl5,¾7ŒÃÈ…Š;ÜÃ>L@,ÄçGĹjĬëÁ®Û±Ô+ÂjË¿P¬L9t;ã§s/Ú‚?š‡¸\¹ò”Ãoªu;…¥Z ÿ†žòPªXs~¨ˆŠ²¦3:PÉ–<~,Cß%¾³¨zøífÄ]*ÆÝ dýâ�€*© Þ*Ý}9 ®ãÈÇã>®Í@îMBåúsáT~'ÝHü6uŽnNî1PîÞ«,âñMÞxžÕ$ÿÁoW>yYe[N*].£zæb.qdîÜfnãhn×jžãÖeÝöàæª²Ý”ÒÝs.èûcçH®ç¼ÆçL®r./�ŽÛ!>å«>о»Øè1öèÏéT:éšà§2æ™XæXpæl�ãðÂæ×ÍyÙ=ê^êþ0àâª^å6D9ª•Þþí¦ÇÀ7ÖšB6�†Š»˜_XI+�²ˆèY¥š¹eˆô^ïÕpïø®Ãz^²ÆÈ`wIc 7ŽÈ¸.©pð�nÖÝ�‡ ¨(s­È2±J^·s^¹‹k—qëâ´’ÃížõíàÞ_†V $_òäž)XÓiÀ³É,/#6Leäîÿ±Å˜„2#ïIXïöŽï÷®ï° 3ôB¿@ÿŽân&ðÈ6J¿ôlÐôN/>B£ðÿu† <>ÓŠã7ñÒ¼ÖU‘|ðõ`Ÿñ÷Fiäñ‘òÞî`#_ò$òð�òp¶ò-ïòÚ•`1߯ïYèV†7–ó®ó8Àó=Ïy ôBôDß¼¼îr3ÖpKÏôNßôP4R_T V_1X|Z]\�\^ö_/öÙFöëcöƒ…öéø8°ölïöp?erßò/Ÿ+w?­y?X{oó ƒó(Èú‚_ >oø‡Ÿøª»ø‡vŽÿøCù’�:aÇâŒÛ ¹å˜sÎ9§Ã)G6®ó)¨¡¶+jÃІŒ)<§�LЪópoK.»\¾´”[©¾úv‹¿»öãÏ¿ÿlD@Œ40±\�†+ƒÐ2 ±¡ 1ÌJiæ1ôPC ÿŠÄ¢L| ÅØV, Ea|HFÝh¬ñÆ!�Üñ„Mú‘³ a’²H#‘TR&µs’P)½¡’+Äò–s€ç4g:Cƒ@I¶“�©lI�Hžã‚¼'0™Éƒ±†5œt¬zUP T0u†AšÐ…z¦¡ù¡/…щJaUÅFy©Q³S›êèGR¿qñ�ëJ‰ÀW–¶ôe/mcLg*’:ÖÔ¦ßÄ©þº…ÎB6ÿ€êd§;‰jTyB’žJ�$Sï™›p2ªR­UçtU¬ª´-$èA]‹°ê�¡­$ë+ãŠZ«ok-£äÄ·‚b£sfT¬8,j1¯Êô"`$Z'603ccaSG™—¦Þ\l›¿Çö4²â�ìOTËÞžÌ,R7»T 6´ÐÝiKkªâ”«ek_{ÊØ²’Îq(,qËÝf€·¾•�ƒ;Ü1PѸÄD®1•‹<½67ºn¢¯Q¤ÛêVÓº±Áîa%�Xîv·~jù‰þÆñâðî4�’5 y׉ޡª·¨ñÌÃ<RÏ ªt¾�­T“BÂü¢vUüÿm„s^ (»–RÈ +#ÆÚ�²bá—Nð‚sùÛ]v£—Z–"qëZa�^x_]Ôðv:Öá¢t Ês†ÆÌqg<ûAÏ{>Hü°m"¶›ªS1cÓÒâü½x1&àxe\@Êâx‘—å±�+ÈYJ 97p6i�<Â$_uɹŒ“]8g)·ˆÊ²+m±l[2‹�˺õòEÁœQáÆ•£ö(šïªæÍ±y€Î §¹Jg(ÛÏwÞ3Ÿ âç0zŽ‚Vl¡YÇbŸ¸Æ¢± ºiÎ uÒ:Æl�5ûcLšC.`‘Yóé>„Úª£J©còä(tÊlªò•³¼eÜvYIlu«ÿ˜áë];à¸ÉEærGÚfs˜ÈN:6²•½ìfë¹Ï6R OÛWýßAœõðjÝÖ[?X×YW8….Òo@°Ü{»)NPd×Y\Ëf6ÚŸÍñéxÅ„~ûµ�íDo{yª»ÝïÿžwW–ï;¦¹¥�ŒÁÀKdðF.<¨¯d%1ÙÔÎ@µ¾UÍoV[ÙÕ“—õÓ-u/}Ì¿LøÂ-Üð®¯Dô<&}±Ån²ÏÙì­ovڥ͎íÒ¾ö_[•ˆÚ˜øK6q¹»r0“¢$ BЊ•kh@l£ ¤ŽÙ+'‰•C±‰:ÈÀTØ@ÿÈ¡ƒá¡ ¬ VAŒ¨ 8"!@È“—Ź?ÇxŒ-‘Ž¡ �0”ØH²ŽZ”?ù QÀÜø£Ž1“Ôs-8ÂHBJ¡”$l˜à9ƒ:rÊØ¿Õé¿ ø¿F@ÕK4À˜A@¡`@l@, t Üÿ 4 Ô@Ä!pøÀ¦ A@ ÁD+#JÁ»[ÁiÁµc‡¤� ФA<ä5\ôÁdÐB7!Bd3B$TÂ%¬ 'LB( ž)¬B+ô,$-ä™ùÂÝ8@$É0Ã3LÔ?l9@, AŒ=ÿ)Äi¬F׸FÈÆ¼yD¯8¦c‚ ¸¨D/ÂÝ(ƒ:BsäDtÌ�O|B#‰ÂvŒ�wìšSLEÔ³8qÁÇ¡”_ú%1ìÇH� ¤ „8ƒ”<ÌÀ^œCU ÆíÆ],F=DÆ>TÆ?dFgŒ h<iÌ+tì�I¼É® É,2É·ÊX0º¬ËŽ�J¨dÉSrÉsŒI™TÇšÅ:"Åœ„˜�œÇ�êɲûI Ê¡1¬KS£ì�¤, ¥ü:7³·§”Ã_¤Ã3j/çpHcÔJ‰äJŠdFî±H8%âÒH² å æ¨Áyˆ�LJŒ«ÊAI·„Ët�Kÿɤ˻ÄË:ÐKâK˜DÇ™\ÇÆ¸É”˜Ÿ` b@‚Zhƒ6¹tÌ¡ŒÌº¤L(H8˜� Ek¿˜ę̀üÌ© Í<8H¬ä Ó‘m�¼Õ$ ƒpÍËÈh„ÁØ$‡Ùl„ÚDËÛ<ˆÜ”ƒÝtÄÞlËß„KáNÖ#ã¬ìÂ.ךI¿üK'tNÆØ›èÜID‡é\‰ƒa¦ïÀÎì ƒíl‘ÇJ‘LðÜñt·Õ0©ó ŠôDÌ&kHb¨LHÐ4£¦Òd:°d¤‡ûTÍÉaMþLØÄ0ÐõÈ]PmdK®pËlÎ•Ì ­Ð …#IÑP¿œÉêØ‰ÿG|D ÑöÑý†-©0RÑìlÑÚxÑ}óЪÌÒ°ÑjÀÑÝÑøtÊ R©T(ªÌED½Ê<Á$Å­%mRíkÆ@|ÆAœÒ”(K9Ë´|>Þ\ß$I0Êá4…15Î25€3ýÄ UÓ5mS|S8]9õ ê¬@;MÑYQmL}Ì>š‰TÒTB=OC•O õL…äU#ýQœTÔªÔä©HýÔTŒ$Äÿ4ÄåHÛ¼AQePRuPS…PT•PÖ#Ó2}U'\S;hz­WY­Z][½ÕôÈUuØU7ìU¦ÀSíÖ=%ÖëóÓÜ@ÖñtûZVô|1G�VHUTÿ÷dÔ:¥X›¨Ö RÒ­dÒlõÊLËMýÖ�4KEMXc•†UÖ0ÊQrhÖGEÈEõ@iMj•ÔŽ¥Ô�µÔ—øÊƒ˱¤RDDYkTÙ�dÙ�tÙ­ðÒSÅÇT¥Y¨´Ù¹WžÐYzíYŸ�UZ Z¡õ 'n Úƒ±¦Ô{È€I«‡¤g¡É�\•"$NS\ŸL3ºÀ°ˆµµ‰ý@6a?«ÜØT ��RÆ@ÖMä`+r߀J":°‘°Üu]Ψ¹à¡ÞÐÿ,±×dŒ)Ô×kùŠc2\`¥`�I-x^èEâ iáAiÁ—A\ö(ÜqB\'Á\:c\#q\c„Ü9™\Ê…&Ë}¿¢_ù—ÍU¼Î­ˆÏ­‰Ð]š«9®…TDÝ�PÝ3`]DÐÝ@I�Ø�‰ÙÍÀÚÅ­ÛÍ]äà]ðÝŒÞÞþôV)¬#ã%LtUÞeÞu^è}^é�^iÑÞÕá^>òÞíp_(ßé _=4_A_É­Üõ  Äm#{„ßâÜFðÜŽ„Ôûõҽîeÿe`þnÙÕÚ"Û ܵ†'^–àsð�àͦ ~N .ž§åm‘ÿæýÄ&á™^ 8aöTñ´¯Å-͈j܉z܉\Æá6††‡DDNäø ÁbÛ]ý]#ÎßÒÅÊ%nâÖ}]©ë])F`*V`+f`,vàÝ‘¹ðb0®`1àâ5ã—ÍÎNÎNa$ÁÞ9Æ£:FŽ;&­<ÎÊ=6’)œB¤aŰaJä.äCNdD^äF¦ß!†d~�äFªJ$æßÓMŒÔõÏÎd΀ÝNö†®ƒF­Öâ6eNfÈß-…0ή1&Þ2>ÞR�eh›eh«eè½^|ÉåúÙeÎèe©úå=”¥€æ:*æ?>ß@VßA&dF¶ÿfvfhžßh¨_@(âk>ªý5]%ææÿõf'Öä(fÈ).…*ž€+–€,Þâ.nšwŽç`"c7Ø`wDÞ,Âg?Óg?ãççõgãhú9;H<¦h=FhaVhäA@Fß”0£G«1i`fctægþaù bi~dû�düÅf†<ÒK&ip.àSî)©Ðs†c˜fç–é †gU–gV®gþŠûñRŸ Ö¡6 ¢f£æe¤öe¥fY²I§~jÍHÉžlàœêÊauJ ƒA­F…‹öꌞ氮æ±öèõLâ³Æà’çMžëò·e€ëu>iç˜é»®iz¾iWöŠÿ¾vËß™`•â¾\.ì¯9ì�Nì‚^ìƒ&"ÇfÈŽìÉ–ìÊF 3ÂlÓlçæl­þlG6Pj¶fx"ë�¶d‘fb´`“^ë×vŽØfi«¢íR¶í˜ÀmV°à¼æm{‹ß&Éà‚á.n?näîåN ‚f�Í†ÈÆLéžn¶¨në†KËí¾ê‰߬þn®fdŒÖhŽ.oÓöQmi9èfÕNk(vïö†ø¾*úîT¹Fe ÎïUöæVîo¾/ p O/ð>pŸ�¼Rpæfðîvpè†pb–plòë^‡ì^ßÌFŠïlðþjñmòÞ1ó>íOíÆXmÿµnç�ñùžÞ¸¶ooÀoýÖq½Îi=òqàî òâ6p#‡˜G‰_�7ÁèŽr §r ÇîËÆòíÖò&çò�æÐë�ëIsi3_]_q~ï˜`óÙvóÚvïÛ®kšÞ æï½öm<p=§p>'n?ÿó]é#.^„y±‰äL1ÕU³¸@6Ù¨³µ:Q-æ`4a«ÔM~¥”ÛuDb�4¸=Üq+ç×Qù»êØclj4±ó·�R9…§—^¨cû¥Ñ�£ò8ª‡Kžƒ&83Íùi®9=�{Nè¡£É é¥«Yzé¾ùVë­Gð:ì¡ ´è¢n¸÷ Cl5ï½·…µÖu‡ôuDaG3vÙgƒ•¶Çl°�–Û4´H÷ÖvMoÞ+uȷ߀ ^ráåLž¸J‹gÔø�£ùä’W~ừϓ�矇:š°Ã~ÿ:ꬨSë\§¿Èn ´;‹ípç»2�)ÀãZ׆g°‰M%ÉC›Ú8ò< DozOÞ:îæ ìucoHë;g‡Á­#|ã•â¸Â8ÇAKísƒàÇ.ùѯ~ô¸þ&4Àðuÿ3@Y7Äð ”[£(E¡<„Äk„ñ�³a°yì ‹¨Á^oÙ3!ÁP¨BºPräë†ù€>õ±ï†xyj0ÇCÁ„¡�~"!ò7À"¦îI,Àe×Ä'ÂmŠŽtd«'ÁqPðxÜ¢ò\¼²h°&ms›±BF„„hä•¿ç­Î�0,Ÿ ÏGÃõÙÐÿŽwÌaã·¹ìøÑ�‡Ì0ƒ9DB’Ldhy;(>²™ Œä¯˜ÅK΃‹ËË ó< =P†ñƒ’$ã7èÕSnï„ù[ U•6î�qœc ýcË[ªF‡íÒ/{†_˜Ã¬PÿügÈ$"s ÊT 3Ê;hzm‚Å« Ù0ÙENfÓŸ”^7�óè\ñ�zóPyNï©Ð1¢ âfæ¿ }±x)LÕ§¾ÉáQ3zÜ%õÉÏ~þS6&2‘6‚*Ôc�‰dä ªTª1t’•Ôb53‰…MŽemÚä 7W¤Q¨pÔ¡�ð¨öä䑲�% ÜI©’Rv­”+-ÿmLc*STЗ6Õ%>sÚË� s�úéM„*T|¶°�ÝQ—ÙÈ¥2¶YM]‡4!zÁkzñª`ÔêVcÔÑWæ�7cÝU*KšVr¬5Tm=Ç[‡חΕ®8¬g.wˆÓ°èsŸIì§?ýêSÀ 6¨…5lQ™X„6¶¸}zld-ѨN´ª�´è61ŠY�jÖ«`-!HÉjֳ޶´ :mjW‹Ö~¢¼æ­,Ò«^À¦ î}o>÷z[Üö´#€Í@oµñ[±G=:(3�+à«e ‚ ¥äC•;YMbó‹Y=Î�~´Õ�Je³Ô §XC Ú‘¦S´�R+^0Þ·Š—¼æ-oÿR¬bõ®—½ x/|õêËùòt€M¼o~÷‹�ð¸Çþ�nô�:à!¯¹^�ær­ÉàÊB«Ò…p„W0áê"ø«œýh†µKRv7Ä*mkxWkâ«xÅ,†…‹_ ã6ÄwÆÄm†xcÞöVÇ=öñ�£dÅ&•È~nJÍÆV TÉ˦JU;5ìGŠx"-é o£Ò–†ÏëøãŽM+d!Hލ’5,t.*zÜ85£•�}UÃ/fˤ›[ç!F¡Ö¶^s:DøÈ¡×¾6ˆA¤ ìaÿX¶;¶ ìŠMx«¶¶µžÝ¦§?S;9�îÀ Åçejzl‰.aÿ}¬ 8Ò’>7¥-]iLG@Óœ>�§! j©n˜Ã¥vÛ©¹‘êY…Õ®Vr¬Y7ë>»Ö¸Öõyíë^» Ã&ö�‘m;e?z(ÖÆ‹Sí�ZÐà#´¡ß�èÀ,oÑQ»I¹rntoUÝëÞN¦+³iwt:Ÿ–(Xê]Ö¿Ý›ùÞ7ÐróoX÷‘¯¹Õ_Á£pðþíz; gxÃ.ìbK<Ù˶øV3ŽqŽs})×ÎöZ»­’o›œaãN¹OV>é­jE+ìv7Íámsyãü³£æùYL�j®©!þæÊ«Áð \F�óîô§7œR—Õ%Nq¥h]w]¿üQ¾þqÿmTbïÙÃ}rr¯¥âi—tŒ úÕ·}"o—ù»ÃÁ�›37ç}CaÏÎw~¯z_C|ÑiÜWà ÿè‰|ªŽ€å3¿ùËÇÝb2ù¤T~j˜¿¾P4¿Jv†|äh+û�P^zsG:õ«W}ëßñzÊ̼æ´µÎI�w|ï}k}ÇßÏx— ¾ð°;üñéOòIœó @_ŸIßÕ!Eõ% ö=`Ohß:�œç‰œ·‘œ&�_£�ŸÊ½E¾™ßù¥ ÅûÅÞìÑ]íÙîÍŸÏÕŸ:Ü«½ÚþaAÿÑ×`"ßv(Ÿ6*GB ú„r›Ž*šè™ÿ�‰ ]OˆÇBÇù¡_ë�`»Á^ÜÉ^¼)×¼…EüáÝè�¾í^С„ \ð½™ ÖXÞöàóAVßa²çuß~_†é­€éE¡ž²Þ ¶CûÉÝûÑÛíÙ êžýñžßíK�m½áðý_ñ!^ÖÒá&Gæ!î!÷U ÷•\ n !’ßJE€2b–àž Ö�¨­àÒ_^≕W ¦!ð…A!œÊZÂÎ�ñ˜ Ö!qG*ª"ö±â~^è‘…¸=!žÞÔbTÜb.ÞO#>"ÎÝ/¦`0Râ0¶`1¾ÿ 9ã'\Çulâ26cÿdêÏ4Ž@5"Û5bc€Ç6r#æycºâ¢8Ž€""Vá:†N;š`æ 0†!;äž R…>ò£Wø#ÿõ@¢Ž@†âäA[B ¢":äõiä·$„ƒ¤ÄØC1¤VEò:ÙZ,%Sæ:†„=�Ê…E*¤`F%�ü ‰QÑîd�SžZm’ŽÁ:¡“‰ÄM~áš´¥[ž•T]”9 OÖ%ïø¤ÉeD¥J¥QŽ…ˆ$e­1eS†eŒDeæäUZe€CV†ÍVNHW.ÊWfCXrÃXQYnÇYþMZÂÍZ®ÿ™[¾åYU�]ž&á%]èe#ðe7øå[¥`Fa.åeflÝS~dGU^åeݦv*§~j¾…j'Ž*ì ²�jO¤jŠöi«^kr¼j¬¾h–ö¥�~'‚"e¢FmÍ®Z…€øªŒë„Rj…6£ëÂ+²*ÿë©1+}ÂŽ2EkNê©ó¡hµ: ¶l[h+‘p+­z«­&踖«:œkB¤«Jþjë»Æë„d*½z*‘^&¾‚¨þìë±I«‰þ+Š®*Á¦,RìOê¬ê�*Ãâ*¹–+Ä"„Äò#ÅZlšb,lhlg"k²vlX~,’ÚXbñk6N«É>©µª,ÔE‡B�8ˆƒ0ƒ¤ß™ÁBméãäðÌMµé„”|�EãqÀRv‰âôý„œf�ËmÃãEžÒF-ÞRÍÔrMÕ^mÖ¶ÞÖví1~­½„m~Œé”íXœmÚÑÚÊNÛ6ÌÛÅÜÖmÄI\‰æ­æöÉÞnMßbÿÖª†Öž™àžá¶ŠáBⲂâNãê�Ú ÛF®‰LîPT®ÔÙíÈFßæö.Ÿt®:|îe„n嬯ªÈ<©Gá’©êŽmâ*îë |ÌnÛÖî*Źé.#ù.÷j‘R­Õ‚nñª†8!ï<�-óÎÃê¶nôßôB.íÞ„í"Ź5`æv/þð /8ïø–/j$/úžçá:/ëBoãå`¼ohDî¸ÍïQÔoõÝoþVðRìoøïø¯ƒ˜¯-ñŒÏjß´.YÌ-Úæ DÕlSHpåY0 gë÷òm÷ï7½x°�°J ÒÀ\š°§°@¬0ж°¤5êd /±R`°ßÞ0k†ÛKgÄoG»Ü Kïv�ï'Gš31…‹/çpÏ“üT±\1ad±ºm±ûv±ì|1… k]÷±ÔΰçÖ°ÿo3Ää°Z÷°®ü0Ÿ•£ðvÔäı%ñNú1&Åkpï"oŽÃ1Yȱ¥ÑqâÁ‡$[W²_r&aåÄ2-×rS̲-ç²..ï²/ïr/ÿ²0Ór0³1÷q1³2Çp2/³3ão3?³4on4O³5Cm5_³6ck6o³7ûi7³8ÿg@!ù,¼ÿH° €ˆP¡Ã‡#JœH1bÊ3jÜȱ#C� CŠIÒ"Å‹=¨üˆåB�.ÆÄ8sfÂ6%ºD©ÒÃÄœqB¬ù¨C£2‘5(´¤Ó§P£¾ìèSæÇ m*}HÔ$ɘU½Õy“lV³#·J]˶mÒ¦8›&U–ëÕ—qY½‹×êA¹qQ^Ìû°áÁr™NLx`Ý pK>Œ•adÊ–ç\ù!$ùœk‰¡'PO~ö݆ Ey]aôí·×U÷ 6Þ[Q&Ù“8^)`ä‰ùdsY–©•˜]’É¥{œÅhäœtr‡e�xâ˜çžÉ矤Õä' §%Iè¡� Šè¢ŒV$À£Dú¤”F`é¥6dªéœvzç †úi¤–:Ç©¨¦z꥗Jáê«eÄÿ*+ ´ÖÀ­¸”À®ôê믽~!ì°»›@£È&«,‰� )”VÊjšnÚ)§¢Þ`À¶Ü–jªªÓ†Á«°Ê+EÅ«n¸æºì»ðÆKZ³ÏF;i¸Õfz-¶¢rÛ­·u¨:‡¸Ó’몹çN”¶{«¼G,1HôJj/¾ùú«ñÆÿzKÆÇ ̪ÁR4Û,º»šü¨Ã,0ñË0ǬPÅÐ^ tÐ]ôÑH»ËôØd7:ôÓQO-uÕ:çàöÛY“.Âe¬`÷Ý^cvØ.—ÿí÷ß|ýì³i«Í6ÇoÃ�õÜß�·Êí6à”W^¤àƒS€qµ‡oœ¸Ûq3n®ãvçí¨Ê|?lù꬛†ùà(Ä.;Î�küy¡OK7é+˜N‘äH·.üðQ½þ¬ì³g\;··çÎêî¤û>ð-oýõ«œ9ÈÇNûòÛ6¿¸î�G¹Þ¨§Žýúìsdì®Ä/ÿÓZÔoÿýõO ÿþøkÈÿÖ°je«¤µï€œÓû ¿ùÙ«ýÛÿðÀ ð Ì ó´ÀÆ�~¼Ÿõ׿ þï‚Ü  W¨À÷�0„ùa M(=Úð†¥Yà a8 ôo�5Ä¡ÿ‡è>†1”àßD":ñ‰1b´�X?þàŠXâù ÈÅ.VD‹&Ã"·gE1þŒ'ó¢ר4>ÊŒ? ãáèF¢±ñŽw¬#å(@:2q‹x $õhF>Ë�Æj¢ iCBŠÑ�ÂBd±ÉÈJ>1uÕ³¤&7ÉÉNzò“  ¥(GIÊRšò”¨L¥*WÉÊVºò•°Œ¥,gIËZÚò–¸Ì¥.wÉË^úò—À ¦0‡IÌbó˜ÈL¦2—ÉÌf:ó™ÐŒ¦4§IÍjZóšØÌ¦6·ÉÍnzó›à §8ÇIÎršóœèL§:×ÉÎvºó�ðŒ§<çIÏzÚóžøÌ§>÷ÉÿÏ~úóŸ ¨,�@ЂÎà (.G8ô¡5(Bª‚ŠZT¡±d¨ шa¢µhE1êI˜ô¤C“€JWz‚–ºt0�éfJÓšÎÔ£@iEOzR’2’§&MéJUêR—Zà¨HMêQmºœêT@E€OU¡µ¨-UªV-ÀT§ê4ªSdUU6T¢bu«J½ƒZ×êU‘rÔ¡a dTÇ@׺–UÈ«^ÑšÔµ²Õ£O}+ âŠÇ¹Ö•®wÕë^ùzT¿ªµ­,aïhØÃ ᲘUl^ÛXǂೠí€hG+ÙÉ®±²uÅlf5ËY 8ö m`ßjÚÓÿõ°tUíe5K€Ö¾6¶Ÿ�-GkëD–yиƒn…À[ßz¸Â}(q‰h\&w¹Íåìo¡«SÁ‚uº*¬n¯«Ûì2v»±�®C¿ ^ ²ì®]ˆ¯|!@ßúVà¾øU‚~÷ ƒþú7[©€g0ÚÑFdhC+°h½ Ôö.ë½e•ï|ëK_üæw¿úõïû¥±ƒTÁ80‚MbóÔÁÊ‚ðP%_ WØÂÀp†5 wØÃ±ˆGü¨¿•½(fT÷PÀâ.ìë2VŒc,ãp‰áÉP�”§,` XùÊ‘ãq�lâž¹QC.ò‘“Lc$ÙÉP~ò”© Ò+cÿ}Zö1G�üåC…™Åc–q™Ï<­4«yÍ"¨²›1�å8sùÇ ®3¡Ž×=1ï‹Ì4V›ÔМf@:¤*4¡áÌc9?´«U4ž�­šßÜæšîyÏYt3&7hO{`pRô¤»ýèKiÓŸnÒ¨“dê¨z|S΃•·|¿0G‚Ì}@ó¬}ìƒ;ÏÉNº ã6íj_{Ûßîö¸Otî;­»ÝE‚w½w�ï~Ϻ?øÂûìðÐôVÏzÆ;®Èg‡|Ö>€ÉSé–G(桪ù̓¤óz=Öi ø­¾ë†?¼êY¿z×ß ö�—=ím{£çþ »‡ºï;üª ÿïZ<ÿ×Yåõ¯/Ÿùηô+ûÙKÆÕWúL™NÐmkûQÜÕJ=/ßÐ?ü¥‡|§§|ƒÆ|Íç0¼³~uÕ~ÓFç_.�·ç¨{€¥S†Ñ}žçV|âç$£s:\ p~­ç0XuEÆ.ø‚ ø~vt(�”G�~`�·†�¢¥�¨TÇ]à�þ‚ƒ7‚$¨&ˆ‚Ø.+Ø‚/è‚1“Wƒ.0�ˆ}(Rèƒ_„y'„DØ_F(sHH‚KX€È2OÈbQ(…Ò'ƒøEƒý�WxƒY8 §]è… †B8„Ã÷�h†“„J\L¸lxrnÿø†S 0‰”H‡0`‡X˜ƒZ¸ƒ\؃~X4û'†ƒX„…(‚‡˜„ièfȈ*èˆö† ‰8A‰•ø€uhƒo‡ƒ:Øl<bŸ¨í)+Åk,F)ke‡v¨U+·Œ!€ˆù†c3`‚C6d°ˆŒ¸qIàbÀ*Y�醉F‡Tp0Ž€PŽqpŽ:Y5Z÷÷‹Œ0ŒÒVŒ“rŒÖ¨ŒÌØŒIøŒ8&�Óˆ<Õh�ب�Üè�èŽ ŽähŽè¸‰êÈìØ{îHð(�ñ&aƨVÖèøÈŒÎHqÐè�ÿ;‰Œébù�¸¨�pPŽ€pŽq�ŽõP)UYÿ©RĈ‘õ¨‘÷¨Tù¨�$È�&’#Y’vx’–’¹’G5Ž-É�1é�3¹Ž¢ÕŽ™“°“ò•‘w°‘¹ŒZåvgv;Cx�Wfùnù–1—rÉ”f€�,é’0)“*@“W)‘7 ZÉ•ñå•`yT�”c™tey–Ÿ“–j‰li�o —r—ti—O¹�/Ù�zÈnU ‘}i“)ðxg<ùöx‡ i˜0‡˜JE–ǘ‰ã˜j™È8™nY™–y)ÝX˜I•.I·—Vé‹£I‘¸)¦Ù•=ù•Ni�wÒ9�‰‰t‹ R·£›1ð˜�Icm‰›ÚY�¾ÿy—å(œÙ‡Ç ˜ÉÉ=�F�¨é“ª©UÓI�¯©˜±‰�Ÿ£�Üi›vˆ›ž¼™ã™™Q æù™èyœ¥Ùž§™šG'ŸóyÕyte9z¡Ù©›ûIc'nþ  –Ò›?ù›šy Ä šÆ™žêy+ÊÉ ÌùžÎŸJ¡ZŸÖÙqŠ¡ù©¡�YfZª›â9¢äi rç™'š £¹ ¥æžŽ3¡jtš£C�¡•¹¡ö£AZ™CŠŒZœåy¤ÃÉ—)H,GZ¶eFgà¦~34 „B#);´8‰ haZ•dØX~ú§á¢�wÚ©”õ.S�¨ŠZŒÿÚ¨I¦ã“{øf–”¦f´¦bQõTpZ6rú>tZ§(0¨yŠ_{*c}ú§~¨º9¨…ºq9-Šº¨�ʨ�ªTP)©[kV¶I–*F˜ª©@Å©‰V9Ÿj,¡Z§¤*‡÷uª–ªªÊª•éª «()«³:µj«2©p «œÈ«›V©£¦k bF¬'f9ÇZ,É:’4ZªÍªT|ºqªºªÓ"¨wúª«¬’­Úº­·J¢ßzŽ“Ú«šô«X¬ –®_U¬”Ó®»ò®±c{±ñʬà¬û…�=$­rÉŸ”iP²&‹¨Ùº­%0°, ®¼(R”ZI {E [`ÿ+R�J6›‹‹±*¯K¯¨ºq›¯º)².@²&[²(;«*˲ê²H*®¾Z®f”Z»µ?z�%\Xé©*3§Ô~?k±K…0ƱúÕ´%{´¬"—o0·JË´Mû´´Z¤ˆaH¥~ “T;œJÊH3û[˵êµÛö�a«³*Ãw|7¨f{¶iKöZ|�¹šë¶i·—"·të�Öh·'‹­P˨{»_}û·€m5¸‹T¸‡«µ]{Ÿ_Û]ëå—34�›r’+{gk•Ëv0†¹š›¹œë¹–ºoP·ùȹx›¨�šºúµºzк®»…°+H²;»µKp7ÿ˸º+1!'R¼Û»¿ yÁ;¼µW¼Žu¼Èë¶ÊÌë¼Ì½¦›·Ô«Ö‹½¯ë‰œ„ƒ8xd³›ß›náû™�[$›ªSŠ÷å[¾÷Z½Ëé›vë¡*+Àh¼Ç›¼#”-õKcÚHº%;¨Ë5½ýe,ÜÂýÛº fQÛHì콉k»‹«Àã;' ,RÁ!7Á|Áh—Áó¹ÁìÁ›+¿!,*#¬a%ü¼n‹Âº¥Â0ÐÂ.|T~{½0¬`2 ÀN¤i&8ZPF£“75=2‚ÐÆÂº®F¢iOÅTjPÇvŒxœÇ*‹ˆaÐÇJ£€¡Á‹_k%0ƒzׯ*ÿT_ikn57ÉW0ÉPÉŠpÉÜ~ZÕ�œœA 2¨¢cŒDÆÀeÆO†Æ¨jÃÌÎ ÍÒLÍ�gÍ�üÉÊ VIÞZ¢uÆšÆR³ÆÓÆèüÊK"šævîüÎ÷Ï:7Ï~ZÏ�|Ïù¬ÏÌÌÌÄìÏ-Ð CДÿlɘ<»š¬T׌Į́ÍsÀ͂џÎâ<‡ä|ѬœÑ®Ü¦="�t!-Ò´ÇÇ~|Ò(M£*­VÉ-]/ý?Œ´8áÈÌÕÍ\ÓÑ|Ó‡›ÓIµÓ M]`=he<ѧ\Ñ©\ÎûsÎéÜÃþñÔHÕï<Õ¸\ÕEpÕX}¶„¬ÕªbÖ.ÝÏ`}Ìb=d-Àf]Ð6=Í8]Í:}Ío×3ÜEB ~&A *F�t¯7ªZê W–n ­T"�_´7Á¹œËˆ¡õu±K6·ÀýŽÉ_]A#pÜÓI{ؘÇ3ÝÕÐ ÍÝÒ}ÜÔ= ‚TnÜË7W³lÿT–\Ú§ý)©}t«�5­ýY¯ý±�n³�Tµ}_·}¯¹ÝÇ]]4êÌÎÜÛûÛÁ-ÜËÜÕÅ @Ô�Ük·ÜxÜÜ-ýÜ•,ÝÓ]ÝÖý)Ø�tÚ½rÜ 0Þ½Fà}¯â��¨}_nwÞ>“Þ °Þ¦ÑÞfðÞHß0ߪZßapßù­ßWÀß&àßÁ=Ü^ ÙÆ�ÜÒ©ÜÇÜsß þÝá70áHWá!páÞ’áN$`®ªÎŒ^!îX¬-i®í×±le² Õ´ß.þ§0~ß}°ælNã5N_¾ cÿ à-àÓ’ä&þãä >äÎÍàG¾I~ÝG•Ýsÿ»ÝYÓÝ;D«HåÞ~6Þ7PÞF'â Câ&^(®âGÅâgî§iÞÕlÞæ4nã8Ü:.xnB{~@.pBND.èG^è~èžè¾èÞèBôè Uåzå˘å[îW]®6_.šEÒédßf¾v¸]ßj^ê}àæ¨.çÿ½êwáyþê±nn³^ëÏ=踾äºÞä¼þä¾åÀÞ>š¦iLU–yztÀ=5%ÛÒõõ‚´wtvL�M{ߥZ«h@½, ßðæH<�Ù"sQ(yŠnH.ÐÕªVÃlŽYîoj¥ß÷Í-]Fb4,uuŠ céÆÉrÿ Õ’Ë7×ð o:¿óËy��Tv¨Å,¬)tPô7×s° 8ó>hLµd÷ntù.5ûÎÌýî‚ÿntïßÕÿY_ ¯ �óAðð8ñÒ9ñ>PñT8òÿ*ßÒÏÁY!�#_òÎ|òÛ’òsdF,OW.ÿ³KóÝ8ó5ßÇ7Oö;Ïó+çóqô(ôF@ôFosHßÔ«³ônÖô0öôõG0õ‘\õ põ�õ[ßÒ]_OaŸc�óf?hjÏö–ëö~ ñ/i¿æ ¿vy&ßÕ(߯*�E�?ƒçføY€øšbó6GöAÐø:ßóhÿG{’ï”oùtpô<—ôÃùWê2ˆïs«ïiÀïôåïÄ�õu,ð&Kð¤bðˆð $XРÀ aØ0ÉÃML¤xÀâÅ5úðÁÀ#ƒˆ!+h iƤ?RTJ‰PÀ¥Ë1e~ Y³ÏM!9ó„ŒHRƒI3wî\!zååKI-UØÔé¨c¤^ 8±ÂU¬@³l•#ÇÆWaÄr Û°¡!´iC¬ÍÓ–gD q]Ì5R×.X:yÉrxÐÁ_À&\Øðaĉb`ÜØ§O¬‘%¿€ÕçÌG4§IsÂç�”}ª!�’3ç£.ë¬ÑzÁkØ;̦­X°ÿÓqu[x˜$dÕ‰/Z!^œãG�ÿÍ#‘ %ÉD=,@<]„ñ5Ùfì@N;Í´ƒÁnÄ‘2àLäTT$î8!G„%#¡{)É–üÀ:ìÚ쉹(¿£R,+™ÂR!ôÔc�¢.¿4i«0åûŠ>ûÎD“M6)ÃÑ s¯½S�OpÃUÌO tзHÔ�CI QH!õã´D']‘5×.ý”¶N;�á_€i3Írf]ášÙ$mÁ™�ðùqÈ Zh¢ ÝiECd˜iyé¥[ê/5ÑDf™½Z‡¬ÿØ ‚u£ Øc�±ËN×áX×–Žâ&ßfº;¹Á;*Øò>YK½Gެï1¡ ¼!@ ·öp3¿çÆ!×^Ï8º÷^ò …:]G�>´ÃzÝUZ´G�öS˜tãPCîä8‚$=S`æ*3RªIÎ%“Ÿ)A5­Y²’ÿ•Ê™7$e4„*Z-Žev$çÀðˆÊôq"d@ ‰£Bò3‰ü�Iy…G®%’&Iç[.‰Éin2)�ôË'CI¾ Œò¥<åR™šm¶ò•²ì -m©ª\ê’—ÏÜÛ{€)Ì`S3ƼSA” fNa›ÐŒæ4!`¡·hÓ™Ý|Ë7ONœ�³œ;EÈ9ûÉ“R±Ó�0#¤oš$DÆ,$Pºg>C°O3ü4$ÿ´¤Kj‚"È Â%ìHIž†>ô(UäD)jQ2Ü2£Ø¥zÙQ €4¤©)&CŽiÒe6Ó™,�¤Ka Tàl“¦<±©!“$Îûð”§MÉ£T%¡öèÿ�»‰'Rç©T¥©ùü«cybU�fõ˜ ä*BÊPTæE•Δ¨P(:K—Ô2­]k[ߪ¼¸ÊU¤G i‚ðŠR½®’¯ÿ_ÔiÁ”°˜g’rð\èêT±äd,:Ô?Žm²º©¬t’Z¸0µ‘Ní¬g ·›«ŠA½ë­r•P¯.¬©¥ÃjWÙZXž5¶ýÑ1mËQÜ~¤»í-pÒ/¤t¥À!Ú¹Ž»Í±y“¹G•t£›ØéR×§×…lvUµÝ¸tW&ßm¥fÇËÙɘWfèèzÙ»Õ‹t_]JXU QÖ–Õµú-€l‹Sà¿ü÷¾¼JnLבڵ¤ÉÿÌ«J÷Ê`„:8¦�uf„k:aÃVØÂ9�n†[X]ÏRD#â�v‰ O£¢¡#ž¦�µÙAÎå5ïµÒëb1´·´Ê¹ÊiÉC ±Êd›nžÐkeû’+9Amm+ˆ�%¹òa½/!³fîÊdô@eÁUi° œ‘„ýÈ©³›C©e²e.³Œ!^f!˜9ŒÜŒTúc³ŽuŠ T­9&.%ôc^ùJ5ɹtö¬�[ŒçÅ‘6Ʀ�o)}ãÈ„^œé5”€rh—$:þe´½ÁåísÒ.‘u)—òÛL§@Ýë.U§+ô鄺8£[©çpê-_µ!¬Þž«¥*æXWšÖµîÃÿ­s}J6g²Ú$ùµP‚=ç«ø¼º¹³‹“íÞõ¹Ù~ö¬b2í4,|‘×®%¢UÅmF{ŒŒä¸ Pns£=ëf7”ùL¹)WE#ò&½fo|[Xß«æ7äüýS€ß@Ö¯µÁO¥ëðzs€jø>ìˆKüZ{Ä žÅpñ=¿×ÏKyv}%�‹ªØ.ÀØPÞèÏ<:Ü-W/¥+mnAÈ*4W·KÝMg™Æ[lªò9ª€T=E7ú†ÿ=‘1 \UïƒK u©/�ê ¿:±»u®{ì˾ùØQv�£}Újß'ÛÝ~§n{;îàþ%ÝÅ`w2ã]ï_à{ üÿeO¿…�;¼¨óIjS#>ßÝ7ã}vô~&}é“'¸åÓŒù6O}BUï|ÖU ú=ŠgʶˆŒi|úŽŸ=íÚÌÚKží“þÛ*'£¸ëNî»ÇÓéæûïo.ež>P+¾y;¾zK¾H<æ#:çËØŒÀ"°¹�@ ¼@f±7{#T£ú  ,5ºI¸Á² !œÀÛ&�`§¥ª¡Ë9Zéì�h"s A ?(Žš ›±Qõ¤d1“h.épž•¹XÂ\Âìà³Þx%Ù’­ìͰ·æ;ˆØÂÞ£•@ $\¥Å Á9�5(8C4œÂZ‚£×òÿ7|׌@œ@N{‹ ÄÀ­ CÜ2üÀ0 ÃܵÏ(A䣜K:ÌÔ¡£�Á$©Â¼ÁåÈA”àAšðAUB©B’Q30B™@B–YBhB'(|)TÃ*¼ÂRËBƒØÂèÂ$ù C�ä4LC5dCŠzC8ŒÃ=™C:´CŠ Œ<´À Á>´°?ü@AÔ1DóÙ#x[ÄhÄðrA‰ÁœÄŽªDÌÐALüMüNO¬€’ QŒ RTB&Ä¥TTÅF‰B¡PC2xÅ#ÀBœE.ä;/ÄÅ‹ÐÅŒàE ôÅ_„FY"F74Æc¤Ãÿ:¤ÀˆhF$xF ŒFèšFìEk,Då2AÌØÆŒ¸*o´œpŒÄq´ÁrtAt$ŽL�äÄwŒÇ"¤°QT™R¼GÈÇUL‚VœB€ÈÅ Z´EéðG0ü£«bH{sÈ_ŒH›iCŠ´H=AF ÔÈàH�ÜÀ¼èÀ$Ä@$I+ºÆ“<Ä”LDÈs&–ü£ÌÆ—”I”Iå1Ç7¨I+¸É£›LƒŠ�ÅyŒ€z4 SDE',Ê£¤Â„Å9�Å‚ E ¸L̤¼*Î(ªÁÔxHˆ ƬÆ­äÊñÊŒ¼CžË=„ƲôóÄj\ËψÜŒ�òsD®Sɸ*za¿ÿGG¬Aã”ÉÈ ÉK´ÉLÄIUÌK)‹By$@zT dˆÅÄ¥èÎÈ Ç¬ºZJÊXdˆ©Ì-ÄÌÌL’ÍìL÷üÌ9°J`œB‰Œ%Šô‚¦@MQÍ PƉ`ÆfäÃg3Ë#DºDéÈMÝ<wóMà<�®ëKŒ‰¼áÆc¡a(áþc/q^è…®¤xaˆáÆŠkadºé^޽ßIád6ßK>‚Lö­Â¸å‹•ßP–'&åRNÖ1žUF -Î.FáÝøâ9ã_ãE°eŽ}爽(hƒæeÏzã;ˆcA˜c «ã!£ä<–‚ÿ=†€>ŽgVhnai–ÞB†áC–áD¦ál¾ámÖánæa!ðáÌBæò•!†."#>gŽýäu[çùmgüèxþ˜y>Œz¾gX–e £e×hhh‚6è‚FhÇRh†vhè‚h–þÆEšèоè6Éè�䎦fkilÆmN n†Voîa‰g˜çrÞä#¾ét^b�fçQîéwþéa jÑ…TוsÕ }6jèBÃâp]ƒVêHèÑuê§fc F(4ÕA„®X²ê¶~i8âjÊdAæ B–ÚÑEäŒh£¸8ë£XœHþæc®dqbL.bMÞèwVç»9È^ÿŸ.ã ¿¶ill/VàäçÄnÝÅflplŽím¨–*¬¨l”¸ìçÊì¶cpæl›ñì·íh~®iþhh5í@m Pí—`í”–d¶þnK–mr¦ms¾í¥Îm¾Óe]Få ÔÞþm‚îáÖoã>á²¶€ÂãY>Ãæ^„çflé†Vê–ì^&ìöíÎî.fï~m­o¾gòæhóöhÒæXõfo÷v øVk•¾j rë˜~®™®iýnlþ¦9ÿVcpÈ&ð�0ðŒHMpzZðß燂Ÿp¥®ðH½ð1hc ?G’íð7æ–†mŠ&ñ‰ë§æÿHmñþÀlò’“æq‘µ^éÍ®o™žmš®möŒÑèÞþñ òð½ny>òƒHòÖl’NîX^î'�ò‚†îè~çdžìêþ©ëÖrmåò®ÐlúÖc17ñg^áòÎ�ó^ñôéÓ^óÝhs%xó½ˆóÖ˜s�›—¾ñÈq=ÿëý.å?tÛtõ$ôRæk,AôDìE?îFgpåÖ@æ&Åžtè¦rHµr,§lN·l5ÄìOïîˆõ0ñæ‰2í°Fï4gõõvõŒ.Y' Z[¯óؾóûÎóüæsÜvÈöaGe!wj"ï) FtÜH‹6†eBxøâ€.ÿôg¹n�¦€Šû½�gÐ,­ÝØÖR« TCÙŠ}„âI3¸ËÌy·€*Y£<2¤¬(F¯KŸx¥¢�5ryC™`'@É#4p¹XÕ6>és�¶t²UöÆk †�P‡‡xâ�x5¤xÛΓ‹ÿ‚Œßxàóø¸ù9ù-#yŠ5ù›Cy•w aùÓ�—'¸˜ŸŸ™Žš×¡›Ÿ T#Cž� ŸŸ zøûÊUzÁ_x´hxy¥‡'„ˆ®‰ãŠg�«Ïú àx»ýø’ yšyo-yÐ8yP<{õ�µ?]iûZ{û5ˆûª˜{¬®{¹¹ûÌûØûÇèûûcSÀGXÁ|ÿ§hú^~zÅ�zÆŸzǯú‰üïÕøÉßzËo[ÌÿÍ7ÎÏ'Â”× ™Xù<]ûé�‡€ù”ù« yg·y†³û-Ã{7ìù?úù<òû¶S•Àß}…ïýÂwúÊÄ_ü2.*hB 2lèÐa€ˆ¾| dñÆ6n¬àñ£…�~FÎ)ùádŽ”*¥°l9â%„˜ 8vô¨ä¦™œGvFèYàgLB†ÒÜò¨…$J—öiêiÈ5R?š¨j5Ö¬EhèêõØ+bUª,ivŽ—´=#0hëÖ«W4rÅÐýi·€•¼zƒð}è÷/àÀ‚.lø0âÂ%ÿjìv+T `窱Wå@‚ "D�ØïbŠa¼ ‘æG�"IšDI6GK—0eýxSIN3;�¬µt¨ÈP—2uÚ4²Ô5T­Vͪµ(Ü®“Å^y�ãlÉ´^Öº}].ºbîþÔ»·ïçôê׳oï~¡Ä–ÝÛrTma¤ŸÊú Yh¶sgïÁ'‘heT›G¹á‡ßI ~ ’^ŠH8áK#5j6á¤O>pÂ!EœR©y™‰XUšsXmõUXÔ�õvs¬ÅÝ|‚踣xâÙ%ÞyA8$‘E‰X|,͇áöá·_eý ô€ž ZEš†` .臃®åÿá„Vx!—·å¶[o ETQ‘‘˜DŠ(š¸"Fa~ð¢t1Êh]�7ö¡…îÈc�ãýd^| y$¤‘JzeDòÍW߉«å¥”dP ‘XŽVÚi˜v™Ó—`† a^eš9LÖT�šòæa¿ÁI“œ$Ö UŠx^ 'ŸL'cu4b'h…z¨ ‰*Z£V8:)¶ÙjKX’R,iêQOrúš%Ui¥€¢jYê¬^.¨'«V¸ªÈ™´eH놺u�o îÊQ¯ÄýŠT°U•¦gPAÁx²É’¨ Î m´‰þHW�Ûj¼±ÆÝ~;k¸#AɹSš[e¨fIÚ�÷ºËÿàª)‘Yf½±¦™/›¸ê*Ä’/5ðQ›pp˜ Ç´pÀ.±ÄK{±s<5ÕFz|)ÈšŽÜé§RQ�,oé2ª_Â+s«®Ö,k“âfk›¹úËó|>—h¢�© ‹°ÑH#«ôYÌJ†Ó/Šq£èU½8ãê­ð8ä7H0TpX~ùÈ™ d^^^v.èU 0:é˜~:»\E—[­OðºJÈ>{µ«ü…¹7°ûsFYpÛd|¿–uvíÞÀÉ+Ï\s-.©¼ò5H?=ųÏÞ:öuÔ¨9œ[áøá3˽žÌÖ¸úé7¾>ûAùä¾#u9æPrï½ç‚…¾ÿ?¤—~ºéR °Îu°K‰õdW»*Ü.wZ8^ïà�Ex| ÞkŒ·;è%�y&hQžÇÁéQZ 4@öZ·=Íy/|âùÂd>ì¤O}í»á ß÷8ÉÝ€ró£2ÇBÎå/0ü �ÿFÀBgu9ÁÞë&».°�ºã�‹(GÁ;XƒdÑ ò8èAŠz$”^õ˜Bíaç~œs!øÆ§¹ò ê|5\ó¸>®€‡>< ƒh¿!š§ˆ€9"è’(€%J@€N4˜ƒVlq ³è»-v±'ÅûÉñ8x€1:o>¢·KŒôR‚P&y†ºb@ÈL&ò–é•f>�T´�%qWÍkþ.›Ü&¿‚éÍ0B�”ÎY9hN5¦0�êÔ\;Ý Gx Džô¬§=ó)S�Ñ ¦û¼€ˆ&л”kçBLA šD„&”& }b GjGÙsšÕyUQ%L†Y%�(=š�b§œ¯±*yL …u¦t5¥Á oC½¦‹ÿ™)\±uÖ›æ,;µKOzDê ¯~`KTG©ÙS*SíI‘§FU‹½X¯úféIZ5 ©õ¬Y»ˆ•¬)=kø^ ÚÑ®µAmmj\S ©¹î³®”�R0󊲽ѯ ,`»Ìfb±|iêbØØM>–YŸ¼ eÃdÙ˞ūdÙìO:‹Ò²‚|£%íÃtÚ˜ª¶»Cbí.]{ןÈT´xÀcÛ¾â6·%,o[çÛ —šPm‘T·hÜn"WP•Ms›+Ò¯ *˜bÕŽvÊjÖš†öº/àž",áí¾Õ»nxK#^ØÔd>�­a’“œôÊe½:h/ÿtkԮķó­/cñëXª‚e¿_$Or´ÜÏÁ¹*�nŒ`/(¸ºpð b)á ¿µ~rz2Œ‘ ï'¶ÖkˆE¼£ÁÄ(V1GŽ É¤¾fv‰ÅRŒ�“ßâ ê¸vÉqƒv`§ÈBFp‘l]+yÉv °D ,èÂ$ Ð)84d¼çd2,¹Q"ÝÙ™ÅQèòË€bpºÓGѨ™eâ˜@¯6bBR�j²Pº$ŽZ€=)@�ë. „¹®U-Ù(F‘{ ø5°ƒýë5SÕªŽ KbËÑŒæÎ~vSa¼Ø P»Ú²¾69èm¦Ð 8t ÿ­æ0Ö Ž–¤%Ýê9X:0™FñÀ@­fIZÒ¤Vž©mT›Õ¨4_`½YÓz>¶Î ®ù�†]óz¾6ĉMc§ÙRP6™m‘g?[0M­¶µ±Mn“<1Þ·¸#¨ïs§;Òën7`ÞÝÞx‡ZPõŽô½“—ïr+|ÕSx.‚�¶Ö-ºu®SÍp^?âÁ–ø](ž‹cÜ…Ç�íq{‚œÚ"yÉÃN˜“#ZÑªË Ë×Rï—óåÒ‘9ni>o›ß<ç©«À©)îo  ="D­Ñ�ƒt…/½×škø˜d©S½êà»zÖ°õhS>b¿|`Ènÿ³¯,�V»ºÿíê¶»ûŽ8=êåNïºC Ô¨É{¿>ú ÇzÖE7øÑžô…_ñÜC¼â *‚…€Ü¹"ë¹^}ü¡ÏÕ¢ Þ¢hå¢^!/BÍ/ ã0® #2*ã2’ÿ&f"4Fc'nÞ'R#FÀf#DÜr£®b+"Û+Æâ8b N¢ßЩ�!";*Ý úâ�Ác0ã¥½Þæ¡êP¢î«ÆõkMýë…rk,Êúµ�V ´,s2ÆÄVx�(�ÍÞ,ñP�H ÷X’‰or€žXÜ/ †"…ee.Qä¡,ÓnŒÊf˺ì}zPUˆÈQÌ,óÔìÍÚlÎJÎÎ&JÏ"ÛÏšTÐ-²íaäŸ 1ÒÒ6­ÛbËÓFm ¼,sX­ÌÍrÐÖrm×~m�„mlŒm:•m˜í�!†Ú†ÛfÝÛ6n¤Ä­hµìÜN-Õn…åâmÖêíÞ®ÑÎ*"à¶ÿ„à¶œ�„Å ìCDªã¦î¤@î H.ÝZÅåÆîä-ôìm¬Q©–ê´PËç²Dè²Òè~@évë` ®ê¯‘°®ëR®ÉîåÒ®òØ.îæ.ì®ô®ü.ïðž,a/ò†ï{(¯Ô&Ló:/Ö2‡Öníôæ®õrUÛh‰÷"›é:øŠ¯þªùN®ù2ú¦¯UˆR�´¯î*â/ÆïÊŠýúW˜DÞý6Dþî/§-é,pë–/Ý0æª/p Qoõ&Jë�ü2°I/¯Ñ¦i¿°�/ïÿÖ-s„‘&g�KK ¿Ï #Ù 0‹ŸÙÁ {oñº 0 /q Ë0ÔF®ÇD×ö�óŠÒÕ€c‡S©™?±±Ÿñ3Æ313Dÿ†à£¯ŸQŸÅ�p�ü0ä1’‰ñ’‘ñJƧñ&n 2!#† 2"'²_²"7²"3²#Gò C²$WòS²%gòþb²&wòñr²'‡òÛ‚²(—rÁ’²)§r®¢²*·ò�²²+Çò|!ù,4*�üÿH°àÀ9†YÈp•ÇV"JôE±¢˜‹¡hÜÈQ#™� ‰Y©¤IH(S\ɲ¥Ë—0cÊœI³¦Í›8sêÜɳgÍ@ƒ2lø°hÑŽP0fDÚdÈ‘"MžL‰Ò§Õ«X³jÝʵ«W�A… c´ì*¤J/2mê” Ô¨R+Q­úµ®Ý»xóêÝë2,бdÍí(&‡ábÖrlëö­¤Ç�çBâK¹²å˘/û Xð`Ž…'Vì±íÛE�!g^ͺµë×67wöìíaĤK;=�ú1ìßÀƒ ß+{,íÚ„o�&·Rïç’†KŸN½zl¿²k?~6¹h¤†Â‹ÿo½·õóèÓO߬}ûq´iÁ‹O¾¼jõøóë¯Ì¾½/X|J�6}qÙwß~ 6è Výµ €Fˆ‘�Ö§àƒvèáLj7!€–†óih߇,¶èâKþ PÅŒ4Žè�4n ãŽÏ½èã�@Þ´Ùf8θY�H&©dKCúUdG.)å”@6–AQR©å–Z–~q)æ˜ùy ˜W’©æšÒ™š_²)眭¹ ç™tæ©'_v”垀ÊUŸý)衈îDè@†&êè£1-*P£�Vj饘fªé¦œvêé§ †*ꨤ–jꩨ¦ªêª¬¶êê«°Æÿ*무Öjë­¸æªë®¼öêë¯À+ì°Äkì±È&«ì²Ì6ëì³ÐF+í´ÔVkíµØf«í¶Üvëí·à†+î¸ä–kî¹è¦«îºì¶k�›!f7ȼôö讬ðbç½õšwo¬ù†#¿óÚûï«50ÁÜjÂ@-Ìoï q÷›ZÅ®ºiÊÇ ß"òÈB1*q<ªÇ <òË0WTÑ/4ל²Ê¡²Ü2Ì<ß"3E5ÛLΠn–ÊÑH·ìrÏ/ÿìKÐ4ßL´§O"�´ÒL7ý3Ô¿H=5§U[�ŠÒ¦d=²Ó\{ý5¤1¶áöÛ³Ä-· t×=ÉÝx#£÷Þ}ôÿí7ÚPŸ¼vž1žbøárÏ]7Ýxç½·Þ~ÿ½uàþhᇞxÜ‹3Þø$�Cy€-¸årbžùæ³tnÂç ‡>:é“›^9ê„û—¹æ›»{èÈÌ^zͧ㮦êˆ÷Þùï¡+ãüóWD/=T\Ó¼±ñd&„<ï‰ûþ9ðÏC/}ôÔW=öb&´ûú§¸î}ãà‡¯Ìøä�Tý/磿¥úìgîþòß“Ýè†g½Ûé/}éŸÿþW·W8ð�Ј …W;âð€ûK  ç:Lxðƒ„ #HA™q­x9¡…ÿ vðƒ ¡GHÂV°€ùó‰ Wèš ¸ @DëÿAÄ"^âˆH4†—Š&‚d#‡AÊi¸Æ‹*2I_íÙÑŽ’-êH2’iÎ /ÈÞø° AâæŠhD$q‰LtâG h)¾…ŠVdI¼àÅ p!}ã\ÄH¹–ÑŒ? âÙè7¾ŽÆhb(ž¨‘(vdŠP«"/®(0ÿôñ�s¤ SBHÛò�;9cÉFG^’‘”#è˜;–/hšä¤Â<éEP>ã—ÀŒ†0‡ƸŒñ”¨Ì‰*¹FFº–’¤$,ÉLâ2�+Ùã'ÿÌ`S˜Å§8KiAd&ó&Ë"+ÛèFhÊ’–¶$‰Ih–K=bQ;Ûäb7ùÿMpŠ3œäÄá‚ΙÊDª³™Žø ,aÉjÚÒ• Í`íùçÍ(6ÊÑ}>£ŸÑø'@�YÈ�T™Uc⊨PHò¬¡uÔˆD$2ˆÚB¢¿ (PºŒj”£õ(HEZŒ€â�Œ'­I:U*7–z–/m 5g‘šB”k: O7çSŒ5¨ûªH�ŠÂ¤Æd©¬l)£ê”©RÕª¶ÀêK*Š�žvõ«j?‰JÔûͬ:A+BÕºD¶‚Ä­3…«\û²Óºrõ®_Õë7ù*Rk �*€�‰`WJDÂ*ѰA,MEbÓÅrr«‰ëê#ð*ÙaRöŸ–�Ú\2Û’ÿ±â¶¬“GKqJ/-b ªŒªŠâwÈM."–ËÜõEâ¹Ð€t§›‡êZ÷}ŽCF/¶KTŒT¤÷Smb[Üæv»u`oÃùÛ´—¸Æ-nr•ËÜå:ºÏ�.u­[]ìÞmoÛíEw/òÝðm¼)/+΋Þ�ò’¾�pßKÒ ÅW¾óÝC}í»;üæW¿ào?½xÀb(põÄ;^38½¯Xo1Ú« ãÔÂΰ†7|_ü‚8Ä"öoì´Ë]‘z—"à]ñ�L^ÿÜvÁç…q-¦Lå_aÂT…o|uÌ:{9?q„ à"ÿóȾHrÚ–ÌdGÙÿÁ¤r•Ù+aSD“š<Ù…UÁåÍ}ÙÃa2‰³{b#Û9Íž “œJ8šÁHˆ´ _!ç)Óï NÃsõœã wùÏѱ˜ß÷ÀïMœH5šÕ,[Ì.z Úq4% -iVº—F³¦yÁé-{ÚÏ þ°~ż>¼•z»§gª °j¨IæÕ°nô£Ïi$LúÖ¹vo–+\³=÷9qÁö~ù[ì»»É.Ʋ›´gC±žvn«}íJg»ÆÛ¾q·/ÜŠ~ûûÓøu…Àn‰‚|ƒ†3¶M­7T«úЬîÚlßïYS»Ö!Ä6ý°"�^D�Jv#s�é—�±�÷#òÂ0ÿè¹; ÿT7)b©v  ©4 éi i"JA‘«#7é�·DNù‘%’#ùŠ/b’Z„’-£’"Ã’lè’Á“�$“ÚQ2Ï�´>9I7;É_= C?”-3”Ey” ‘J™Ž÷˜‘9™8T™þÁ�ûB“©Ñ™žÙ9 Y]»ÐœÎ \·S±>v™š<ƒNãš›©9›µy˜×”›-ÿ²›»Ó›E÷›kˆ�¾Q–1˜™™È™œ:¹œÎùœi�µÔÔyšNé …3Øù3Úi‘§€š˜Ê0˜}P˜àY3WY\%Ù$›ýFtç)?+™ž-¹žÔ#—Ø":¢$*¢hÙóé™x#fºwŸÍ �щýÙ|… K4pש#‘�É”úŸP)˜RI˜TY V™˜X©› Ú jrèÉ„êìé!Z¢XJT.º )Ú–+wn¶¥0z2Ú£4ú6ªD8* :*<º”}ù£™ Æà�Dj›FŠ›I:žKêMú¤¥65¥ÂÙWŠ¥$ª¥.Ú¥9ÿù¥ 7ybšŸ1ÊŸfšQij kú2±£j¦°)§²)¤´y§JOH*¡û±}d%Zžú\¾©¡_É¡aé¡¿ñ$iD‡Š¨"ª¨÷ɨ ä¨,©.:¦¥3j©@ª¦—£PÀ©2S >z©vÚ Ez¤â‰ªêE€­š9þ¨¥Ö´"­�«¹º«¼ê«Î ¬ÿ#¬-Z¬’J¦” §Ê:§7Ú¬lú¬nÚ©pú©Ô*ªßy›á¹§Úê}Ô­@ñ­‡®°š¡á³¡§±åTV{�®i¤®ˆÊ®Íé®î¯ÄzŸÆ*�‘¬5º¬˜ª¯šÚ¦‹ð¦| °([­J°zªªÿ°1)#E"k² >û³Ë¶ldc²8p6›Ò#ó$sŠVÛªEß&7uØ–Ö…Dè #º>ª;Ú�º÷<#£ŸŒ!\…Y˜™@†Hô`uê<#J[5cS¹ê€³ð¤-w}±´¦$–˜±GO³Žö³?› „[¸C[©«g´Û…´Ñó¶'qMûO»#3*µè™U{DW›µ»³µŸÓµõµl+2bÛd[¶|p¶Å˜¶ê¥ mûŽ·5·§¸èf‚~“·p[R¶Z'9û·€+¸>[¸†«4DËQ¶Ë¸W»L{“«#•7S›“™{ ›+¢ZÛU\ëa?E¢« aÿ�cKU¨›ºh{Dj ¶ÄǼ¿ ·¹Z»w·y¨»�k±”á·;¼ÂK¼„KTÇ»QÉ+ªIz{Y΋°^½³0½ T½×ÛÙëSÛ‹_Ýû½á{ã;S嫺Ǻ1æºëKÀ»Û¾³û¾$g»ä—»QÀÕ»¬�¿8¸”ÀHŽÀ¿É࿈[´ñ»¸ܸ"ü¸P—Ï» ÌÀÿS½ºgw#ªŸÀuNüÄv嵓§¾·PºN!\}ÄÁ$çÁA ¾!<\#쾫tÂ;|»£X‰}C¿ÇÄ·šñ»ù˳4lÃ8l¯‰[ÆÊ˾lC\Ä—KµÕ…DIH¶ÜÇÔûÇGÈXËË„ìË¿ŒÈ5ÌÅlŽk»¦ÌÌÌì̯KxL3Ó ƒêXÍ&¶]ذà³Ðàý;¤}á>áîE®iN0FÞá~t?)~L¾D%Þ'.”ç¥âpÄâj¸.Þj0ž 2î|Uãyxãq¡ã;®<‹ãã„ ähÜB~³[QäÿŽä ¦äúU泩à^-å7LåV>¨X^$^žè$]aŽrc.€e®DgÎi^—kÞY+.?-þ¸�;çu.ƒwο6þ8ÎçCÀ:¤æ@?î<×WèñüßÙÁ:V˜ämià˜Ðæ¢ é—-éþn —Ž# µåxÖåüÂ`Eèa°„ƒ^h߯¸ì�tê´t(žV­>¯®d� ë;M㶞縪Åë$ö@¿.vA.�Ôxè~îǾèɾääÞäáäìDí”.íW~ �ñíš®i\S2þ˜°´©îFKæ^IљîÏÓî± ïå Tx>èz.ª¥¢æÿæë�ìý®o4óïDð}˜8¯_Œ>]ŽÞìOΗ÷Z”ÞðP1í.ñßOØ®IO0_tÏñŠ]òÓ4òjžâ¬Îìð½„qëÙñd1¾Óú>ï._ï0ßU2? kŸ ‚î7Âða!ðˆì9©ìbïätŒ¦(›ô£ZåoqÝDäôRN½kS?#××âJ§KÄñ�õã¾õy¸©"¡Ÿ2 ÆæFM|òäîÚ�öt®ö4O¼N}Là^ú9-o÷q�€:/ÄûðËo¿þàš«®$ Å D0ÁÁVlP±ƒÌ/ û °BÌ0ü…CB7üÄïF$ÿÑD8Q\‘ÉÚÈŠ±˜ÜhdŠ·�ɸ�x쑤ƒrÈ�|.¿$Sã‰I'Ç‹²€)—tñѰ1%5«Ì-×:ó­4×/7½DÎ9PpÁ;Ës’=±üS ´PnAÛã[pÁÔËÄ^Ê5÷Ür?QwÝâ�p÷]d╺Xê-.¢ŸP|eßWö|ö°h3ñ©§èSæZ­2Q¬ˆR´’(èr�xâk‹£¨°ù•·¬ç®ðø +¬P�­¬8à”Q9ö‘§Ðí&è*cO[IjŽëœc ë8ØLìy6eEzè‡Z^y'ž8½üj–¤ÛnÁ ¾qgsÿÙe:²ÖºÝwÝE:^zí½÷”|/á·_Èþ XàÙ.È`„³R8†!r8RˆŸSZ⊻ø®Œ÷ÝX¡Ž?yd›J>9å•[FæçdæŠf›áÂù�+ây1Ÿ9ºQ£….:ô¯‘Ù;¦¥sjn¥þVܼȽú\­·¬k¯¿;–±ÉöI_~ý­“ÁµØm¸ÿLxa¦Fña„"Þ»oÝ&ÂøWW¦p�׊äJLNYe¦ sü\Èo‘ÜÊ%¹9çDw>ég×è(èÐG7ºôÓSgkuÖÊu{€d7»rÕ.k\ëZév×»²�Mx$)LñŒ×6äÑ'n•˜[ÝNqÿ7ZCzJ£ž¥ì8ìi�{ Ù÷¾Å¡¬qqYúÖ×¾÷a.~š›ŸçêçÃû�. ºÿöæ?›0€Ÿ ©–—³íËeç9�éPœÀ„Ä�Ï©ïÆA~¹‰j³àñ–< -�nͳÛóð=½MïO³ Í&¸xqìc!âj¢¸ñÍ5tNä(33A9-‡™‹ÏæØöÃG$“¤dèDq­k�®ÁÖÿj¶D5‘|uÑK_1E*BÁŠXÌâoÑEþîŽû#‹G®}LƒÊ“óxâ¼K@ï #¤ØýVÇG.{y$Ü ׬€O|Œ+ß]ÎWÿrr‰¬œ.ÇÈ0921�‹¤@(YÉÐaòOš<"'›öIP†fóåß!FSš :©T¥¯•ÅEœ®‹°ü¢,ÏVKˆ˜Ä‚åÀ+¢K³\knœ0S4SÝ¢˜˜¤ã “™Bfnϙ݃f'HjòÄ|4,6 ©>m²�›î³ü”R£26¦<ç$ù©N ±3•AbM”OÏÌsõD&>£¨ÏçðÓŠÿÌ¢@êÅ{�‘–n*‰E:ÎÙ8Ô-‹D'ºÆYXE5ÕFK{*S…#í£ ÿÃ@V“e,í…K�³˜â°¦:¼é¥ÄyA×L‹§=ý)P)#T¢ºSÿuðDjRéÙD{:õlP½…Týù'€Zu ±Œö^�Pãxõ«²ÁàwI¡³¢U­—`«‘ÜjÌêyT®!]¡÷¢ùÂi:Q¥Ö䫹²)DbH‘ƒç�ì'ÅF±§¡h¬c!K™¢þ⨕U*S=ªY~qÖ³µ£j`DKЬ4Œ\M¨jã6LÀ¦8ð-]G:[ŠÌ¶¶#\{:z½YΕ�¾5)J…kÏó÷¥7œi/w9ïR么îÙ¦[] ^W ÙÝ.R»‹Ù¦º)ŸåÚg*§ Úªîíª±ˆ-¾Ô»UuÕ°�/l|ãùº­¾ö-~+ÚF8í7ŽC�©—ܳ+Ý‚zÿpI¥ÃQ"¸¸å:.{¸ÔÉåzóÁŽð�I› óë©tìcÙÙEØ5‰”­,>œ×ïŠø©$Žª‰?K¡Ðªøª-†ˆVOËÞÔÎx15¾±�sL°Û×ÇiòE£’Ñ�²ÇÈGŽ«’™üL?ž¯)•ò ·à˜^yÍ4Õò–qÖeFÙAyZì91¬N s˜ÍÜ2�i>Äid:æa¥£Êm1iû¬BØÃ6Z®eŠÞõy6`Î|§+ h›�ÑN)î¤âƒMlâ—ƒQ¦¯Ò�õ]ÙdPÒp÷êé¾6ÓHë»[ ñnáxP/èn餞i®X¨Ý¿Ø�fjmê0\àž*Žÿ& ~pN$\ác¦âéøÉÏbß'‹3™É~Ú\ëÒÜúÀ¹nÌ®¿Ök¾•9âÃ&v±��l²-{Õϳ£ ×üú®JÕVn’ím“¤Û¹M1Àj.�»Ü�6—×Ó}×ä݆ˆ7O1otõ¼÷Îw¶ôã›àç:×Ë,…+üá©tøØÏq€R\&¯,Æ ñ(s|GÈ‰ìØ‘“|?y²#¡r<å©å=…¶,¤ÝçY�ËÚ7×vÌuŽ=oûü(áºÉ†ŽÌkª°ÈÍ·t–ÞôœC]ñö&)¾}¡o›ô[ÿÞr×]†¯‡=áf?OÙi�ö‰«�íHu;ÜWÿ¦k¼ñú#¾¾VÞIÎ÷?!Û–à£ârÃÃüÇÔ¦÷â±Ýx/“_‘ÿ9ç}!nË«ŠèõéѽŸô_|ÞX¡Ï ½Ó]s†PýôVç7ÖW¯õÖ¿Þëe–='hoÛ3;Ü µã…Ý‹§Þó\ó(à áë_Ó·Ë0¾’¶¾ƒ æc ç# è;<™K0ëÃ9ÇÓ¾}á¾ÉC: :ñÃ<¾2ºÍcôS¿ÿ`?p?©“?Ô»:HȺÒHпýs¬þû?(À±@‘(À¥lƒ,ŒDˆŒ@ ¤@aC> Q> „¤æc¹ç#¼—“ˆ˜£¾Ñ³¹ëË9+�¿îƒÁÿ ?1·Ì+¿ì”û;Hª0W‰’Âó@2äC3A/Ó‹�[Ão;Áó{Cr[A�J0:3?ô<<œA=l¿¨ëÃ�ùCúS½ZóAC ¸¯[D~¨+ã'¥R*·k3 q;ï‚BK<yÉD<ØDÔ7§qšOŒ¸iœ'-”¾žÈ@pŒíãT Ãm[ÅzkEìKµ44A£àD}SÁ8¿Ñ‹(¤óE¦ËÃWÆ€ìø£ÆCC {GY”¼} G ñGAr4êÅ;,H`<ÈÆœ\È@ D e„È2sÆT¢Hõ°HœÀH�ÜHÒÀ¸l¼‹i‘üF’tC“GŒD·|Ë•<&—äB œŸ,ŠxŒ¾–œ¶ÄcE9ÃìɘüÉ6¬º~„âtʲȤ½`lÊ„Œ¿Ò3Ì}CFÓðAŒt½ˆTš‰Ì¢+ãÊAðJŒËÐèH8ûHÇ0KLIÊË8IIhË·t˸̭u¤ËvlŒ»<ˆW¡É½´IÌÉÿksE|L5ì¹Âœ¿Ã¼ÅdA÷{¿ÅHÒl»GÃrBú OiêCˆ ( ª¨ •À!ØR.Ö€ÉeB† € ,åå&í‰YÑÿdø‹ç6‘¸Q£zškĸe ÈS=½ ™¥[ºýØØDÑxRQ_йÅ„=ˆ¥¢>…&9Ý–xêÑÝ8FÒm4†"­…#-¶$åƒ%“xR˜ˆÒ_šÒƒ¨R…¸RÊÈR}ãÒ.…�/ÝÏ0Ó—(Sõ8Ó4mŠ5Å#7½8 ‰H�5q;×ÓÓ=ý“GýÓw T·TB]"CE+D�7EõÉF=�GuÕüà.� =LI„ØÔN¶O U^±R} SÍ/T5UUVWµXÝR/] 0•[u\uÕqÛÕY >6ýÕ`]„a¥SZ³Ó®CÖ<åÓ>eVCpVÿH€Öhe�i­›D]TcÈÖíSn•o­Ô¸»ÔY%׃0×�@R%%Î&mWgx׊Š×y­×{½Œ|‚}e„~�— جÐUø0X_…œ„]X¨q;„X�X¥X‹ÍØ6ÛX6êXlåGÙ¡}Í“,YpµÔ MÙÔŒ –í—U˜•™¥Ù´²YŒ°Ò ±×®}Õ|íÙŸSŒ ÓV5ÓËØ¢íÕeBX`Qب\³¥Å8\Ü49Qª%T«eQkõX�…‚m­[Œ%J Û“[~ÍÔ³M[u­‹Qý4(å)�*�ÛU�Ûœµ…�Å[Zõ×½½Õ¾ÍÕ¿5‚5ÚÁEÚÂUÚÿnaZÆ^Ç}ÜôŒÜjm¿kÌÊ}T ´…Ì]¢Í ×q-["5Ò–õÔOMRü 'GHs‘˜@ꔹìx4² -½[E!ÛÆ ñmŽk!ÚºàÝx!Ü´ÖÃ�ÓÄuÈá]Üâ5^°DÞÃZæÕZmíÓç�Þš^±W÷�„ñ]íÝÞî5 ð-—ø5�)_VÉ”ô»…U° ‘Ï}ø½_ùýú¥’§8XßÍ_ÃE?íbØBÞÿõÁ`k$`F3`5l^–@fî\>aë-WìEÛ þÔ ¶ˆ î… &_ƒ4_Ÿè ž{-õáXå öÙZ6þ]7&Ö Áa9Ž‹®c¨ÁÈi›Û_æ(VäK`ä2vdHÆIa1`ælsfì€f–æl¶Ýj¶À­_lþgÿmnãn¶aBAåpgr ס’² °¯á§G–@�DÓØ·õ^“�ߘÅè/®Ð J¨i0) S2˜•c'1˜Â+<°È¡êi#&q+†ò:¦‹fi—)1(èd@ÄÑŽ¾ê6 �–%‘F’îS“^Â%Â8•FÝ&mé¨xi ”éïËŠš¦„›¾‹œ¦��6ឦØ£¡&ê<1êAj[ê¦fЧŽê:›j–ÀnÅjÆŽ'­Nã�fS¯N¥’–Ž©m»Z+ëáÀ)´& µFPIkëJxë¸~„¹6‹º&‘»6‹¼v“½ê¢v“£F—¤ì#pêf1ìβ ªŽÔÿÆþízìUi‘ݚ쭥Ѱ†DÌNé•þ—NûmI£i›†œŽ"ƒÉ(0¡ˆ0^½~íØ�Ù>—Ú¦¢ñ\¦>‚ÓÑÌ?‘êÞvcàŽïÖùhÈæjÉ–—¯FnËvV”. ͦN–¶ˆçŽî ô>+sëêf¹ÆnúÐîíž…î˜ïÞëðÖ &! Ïðò>�óNïõþÎö>ì÷¦aù.ñ  ‰Jãâ–ûâãu¡Ëæ½Ìþß™ Óèîé>ðÑ®iJ3·K U>¤Ãçxp7aïvmðîkÙn‘ ×ðÀ6o‘ðð½ao qo5Üwòfÿm_Q^�SJ´bpqÓAÿ± ²nƒyªq͹ñÏ.ðÐí·þq{š(’¢-&ò[ÝFr Wò½¶B/ô]8tD¿ð''„ çí öd7¯*?vIчöíf�o·[4hÿ SJj~5’u=øøo uî´Îq˜®Œü÷ÿÒ>m|Žsçît¿ðÚ—v·„wß`_ôy‰÷PÊà§9·eKßwrî÷³ÚjN?�O%‚g 5GxUø¥ pGàö‡§Œˆoõ‰gp³ õµÅxÁõRŠ¢Žÿø�ò‘‰’?Ä?AùÐVyfgyvyMßt€�¢™§¢š·êàÅy·ÓyÎð†'pUƒ ïñpWpÓ&úŠï󣟈Ww9;›¦÷§Ïð¨¨z7y1°zIÃzŒÖzVÞP`VxkÒs�‘ã¾2»âŒe|¸ÀÈ*è|Ï¿²<µÍD~¾°Æ|¡J¸“•;-6‹Ž8�/q: ·éxT¢½E,¯ý¸²ÿ;mÄE˜s‹Ý ÌWüŽf|Ç“ÈÌž«üßÂ�á÷ �Î÷üÎ}}ï%ýÈèŸÔ¸Õ¯ÄIh}©ƒ}$ Ì@£}‚éx"ä§ÜÑÝç’Þ/6€‚Í'þÆ6~V@~ûˆW¯ŒTf°X1( ¡XiXéᯈ%ªªà"Æ7 èèqÈ�UF’|h²’§Vžšåò¥£˜˜f4–즳œ}vŠééë§­‰¿L†)Šê%ÒY�–NjêêiAƒÊËaõª©¬Ig±dó«£™b1Y*kv!Ú´j¯^UÛó­˜Er!Ñ=ù°(Þ¼xÉðí+÷ï"I‚Ó- #âÄŠÿ3nìø1äÈ’kô(€«­/#q¾äYàÀ¨S.lhŤЉU)ÞÈѲ²g“,i7e×­_ÅÖ¼™,§³�}Þþôt"Q£š•2u Õ˜ÔÑUÙæÈjŠzŽ®+ÁÊKÖlYµâÓbw 7îܺvõ²Ó×/àÀƒ¦;ù>þüú÷#®ìór³p‰g—€V“T¡ej©E´Zk®[l³Épv¡¤Kºu‡Io8éÄ“O@ •\Gi¶Ô#MMò”+¢I‡�uØ�w#Žïñ5�P”—Ö�6Ÿ`²§#ñÉ7M:ù$”þuàrx h –æDþabNÿ›…b茆¸u˜Ôn4äpÂg"rw)·bs/>U4fe#Ž�ö„d�ãýˆV�éAB¤$Fê…¤’ŒB9)¥•6&åe™UÙÙg!xi 1Ø¥j«Y¦„­¨ºj™>œéÌ-±ÊªæJ†å¦M"G¢Å'Š*nÅ¢‹0ÊØ'vÉæ ¨ „ºuæÁUߢD:šWH!‰)©¥Ýzû$¦Tjfe§¡Aê‚\V’š©§ö—ꪪ¶úª¬³rX+›†øÛˆÃ•h܉v¦¸±ÎÅx.¨Ó)K³�:û,Z‡.t#µŒRHa¶ mKä·{|_¸šŽË©�žf*Cê²Ûn„®Å+ÿo™ôÖ{ ­-å{+ˆoê*ç¿¿F,Áy‹ðŒ 3Üð�C¬�Ä Q\ŸÅ[–ñ3ù1ÖYGh™¸[‘[²¹ ¢<êºBµËZb˜©ÍÊË­Ì{æÌ4ßk3Rmæœ+¿»úÛ+�À ,lRëy0Ÿ}4Òp)íôyò8ä^H>9Õ[+õG[=˜Ö�kr€_c‰°–¢ªl6Ëi¯ÍöËocwͶò¦sÞ<ó p�•à8R‚]¸Â‡/›¸â:Jû–ã�?>9å[>æ™g»¹`ž[ï1è›Xî§£¥{©¥ŽØê¬Çë:p°Ï-;®pö;'î~ë~ç°Bï)vð‡_ÿü{Ç÷”¼ò˜'¹ÊAírÑ£õ$q½~Ë#™x`€ ÁÙ‘!H*ŽDx¡Á R¨ ü`€ $BÏ £„&¤J,R¸‰è+£Uú‚¼ðEd6üÛ¦�S€§,Ðø!±cÓ ‰=«8"‘©øhhƒ<…ÄÄÀ)RñI„àr$H âï‚?É yÑÁz0„#,� Oˆ�Æb…›haL^˜“òe†e›ˆ �Ã?èP;=´ƒH�!6¤ˆzAb•ø%51ŒU|$$;vÅLDp‚¸ê¢Ž0‘0Š6d,ãrΈÆ4"…*dár\h2cÀЂuü ‘Ç=ö±ÿ+ ä…HHCæ‘GTä"™hNF²˜Æ´bGHÉ,Zòn˜|�&ÁÉ1’ÑŒ¢$e)×xÊ7¦2Ž«le1dË;Jd–8ôå*vx#\BC—Cä%^Ð Lø¦‘N<&>ó9™IVr‹—L˜}F'R„¡å%°iÊ6¢R3ª48Å)†áñ†çôeJ2j€A‹-„´µŒèËyòEIú<)JóÃOfúÓ™Íä7Æ‚‚R3M()êF8:BŽÎ #ì˜sþ�M GÉ3HB†ô�#%©IS*Õ©&f’ÊÜŠµX“îõ/©™&l¶Âˆ±’õŒ[%HÜØÈÆ~‚4¯ÿB’†JT£5©hQRjšÚ˧¾'�y¤*`‹«b)Y•àY+Î’Êå«aDd#+V²ŽÕ¬gM«ZcÁÖ¶¾â­:Š«Ly1WŒÖõ»GG€ÎíD}èYçSÊ ²•}ŠG› Ë’¦t1,-fLg:)›æt§{çB…ZÔ/«s M�gA‰Ï}þóyDü YÓºÛ‘´5®«ÿ¬k^ûÚËÀöÎ;€u³ÙÉNöÒЂΤ‘ôFÔ¾b¬ÝlÃ…ÛÞþ÷IÁ½è\'%ËœIs¹¿Léóª›Ýëv÷»Ýï…Ìû<$ êyî͹ÄèûH®>�¿.rc œÑwôÁ!} I'Ø ÿ­Ã¾æˆÃ{âP¨8ÿ€iïTsŒã«¾öÇûÝó‘�䉾õÀÅ}ò]§üØiŽù^NY¨CœæÏú Å}Iïyî<ÖCÇÕ<ÞW׆¼èf_`É ŽƒGÂéj†ºÔÉ u÷¾»iPPÖ‚ó·\<¹zþúE¨&øŒ¸ìg?<¢5¢h“¯åmwû–áwFÌ�³u�Vtñ¾ˆÿ¬#rëÀô{Dü=øÑo ð€G<ê³–v¥7žé�‡¼äã^ù¶^ž-§Õ<ç‘èyE‚~Û§'ýàM�ïÔÿc«¿òÒyíöØK}ö ©}[2�÷Üq÷Jì½è�O5áo¼øÞÿÖñÇÝôåÇ|ò”�9Ý“mwÍo^ïZ·8I±ÿ{ížì§ÿ>þ‘itîp‡Ðy¹ˆà¹W( ªÅ†-4 nı^H[ž…ÞýåÊlð_ÿuÅÿqF  g!`¦Åþ…> FD †Æ”× _Ö TQv ãào‰àŽ�š`(( Ž(É 6 âÐ ÂàyœÿªÍ`÷Ù n×ú’²R– rÖ³¤ \¡-$á,a >¡DL¡RZáº^’Õ à.Ô¡Ú�ZØÓµŒ J €­! ˜GÄ“^áFBÎá$Øáb^�è¡ñ¡¾à¢% Ö Eêà!&¢‹”(†"#Ö¡Ý}$òBËéUâ%¶â v!¢"ùßzbS„¢(Žb)Ò)¦¢â+º¢0æSÊ"ÑâÿÙâ$à"(Žâ.ìâõ"ªØÚ*b×0^#�U¡1Vßy ±Õ�2c)8#4’�IÓ4ªâè#6¶#QÈíÑÞõ„7[827#9:â–Dã09R:þb5¢˜;äÁc<ÖWçu£°}ã=âb>Ú^Z˜b?ÞÓ?€ö±#AfdÖ!ù6,*ÂÿH° Áƒ .XÈð�Ç3"JœH±¢Åˆ 2jÁ±£„� C~¤@²d‚“(ª\ɲ¥Ë—0cÊœI³¦Í›8sêÜÉáCˆƒ Ũ1cG�"“–,Ù³©Ó§P£J�JµªU•?Ýj±¨Ñ£#’*]JáªÙ³hÓª]ËvjÖ\ãJô ¢ƒÝ»I2lË·¯ß¿€ FX‘îÝÈõ.̸±ãÇ�#,ì±åŠHÞ̹³çÏ;ˆmøòáÌ S«^Íšóè×°MŸVܺ¶íÛ¸¯ÂÞ�@ö]Ô¹ƒ NÜ%ïØ¾1Ó.μ¹óÛÇ_'W®÷¹õëØ#G=xöïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ(à€hà�&¨à‚ 6èàƒF(á„Vhá…f¨á†vèᇠ†(âˆ$–hâ‰(¦¨âŠ,¶èâ‹0Æ(ãŒ4Öhã�8æ¨ãŽ<öèã�@)ä�Diä‘H&©ä’L6é$…D)å”Q`å•OfY•\ p%–Z† S—T~i¥˜h¶Dæ”f�æ› ­)e›pÖY�œUšiçžàée›gò™¦Ÿ€*¨˜„z(š\žàè£D*)˜‹É¥¤’¢ é¦�BŠi”V:䥟nÊi§'| ª¡¢òÈ¥°ÆÿšÂ¬´.aë­/䪫©š:àë¯++l«5¾+¬´Öz«­ºîÊë¯À ,±4{l²³.Ël³/ðŠ´¾J;-µ2Z++¶Ú.Ám·Ï‚+î ä–Kå±È¢«møækÀ¾ü‚ëÀ»ñÆhn½É¦›¯¾üîë/À¿(%½Ç2 ñÄÜG »+nÃG« ‡<1Å÷ZŒ± oÌq‹Ã²È#3PñÁ'§,íÊ,{ìòËBÄÌÀ@mñÅ‹aôÑë’UÎ%¶lÏ=Ç´Ð&}´ÑI“ÅtÓ:?ͳÏS=ôÉWcÍ­Ò[{HÂÚl×àöÛa`ÁÜt×=·xçÍÁÞ|Gÿà÷€ƒd’ž1µéçáT¦}ÛlÇ·Ý�[`Åä”óÝ÷ß��DR„Ãd8â +nãk;vävS^¹åøàc¾yç/}úᢗ§Äî¼›>5êu«>9ë­c»æpþ¥L¶ßŽgîäñÞ»ï@O·ðV ýö®Ã.{ò´»Ô¼ókB?žô»S_½õ’ ¿=÷Ư|¨â›I¾Ÿæ÷úJø^Áÿt{ƒï@Àbï}Úë^æ$0¸åÎ~÷“Sþ²³?ôù€sà h@÷!P�Çcàìè9NI(L¡·Pu.M;”Þ+Àrðü`ü�7?VÕïK\J¡ ÿyÅB¾Ð:1œžãþGà Ú�ƒ9|å¾–ŒOBDá Qå­¤‘8ILŸé˜Xà Þ0Šð{ÝH¿– %gˆ£³(ƒ-vª‹"yãI¾h›0öoŒ´€oˆCJq‡" _¢ÇÈqŽY´ã£ð’Fòq5*Èd6é&þÏ  åÄø5‡Ršò¨L%VÉÊ“•á•°ü�,Ûh.}á–¸ÄV ¦ÀË^¦+]ëòÖºiÄKJ&“*Ød:éÉPŠRb¤4e)S©JV®Ò•°|¥,@Ë;Q —¹ÄV/}ùËe“WÃÔc1� d*“™Lt&(G¹/i–�°æ51–ÿMmÎÒ‡±%8¿ Ëqò²œæä–0¹EÌı32îä¤'+ OÐÓöœ>õIlfs›Ý$ˆ@ÁYPƒ"ôVxH©JO¶®":ô¡�‰è2'ZÑ‹ft£úôh,ÿ馕Œ4œÉʃP‡JT¡¦K¥+ÅXKQµN˜2F¦ðü¤sŠ1ËÐɧ]gEÃÊס’µ¬;‚`uÅBIII­Ž�*Mߊ±¸no®Ö ‚d'k×*ruJ>Ûk_ùúד ö„E•a£„ØÆ(֭΄kUåÊÑÉR1wU —2+ÏÍÿr–¬žl® ©Ã–v0§�'cO–0«²Òµ’­ì"2Û˜iÖ¶Eíl`uûÞfÀ·¿m ¶ËÝàþà /q1FMTVá¼èEn”ÛFô¢÷ð�/m� ]°J7aŸ m§F+€ìò…»ÝeëL=^ñŽ—_åý€{Ï«^ötÁUˆ¯|�[Ûúõ¾üÊïnEÛ[ÒŽˆK±Ð]ž@â˜8 (ö¤Ä V‡»˜ 0ޱfLã¥vJiÛܦeöÀã l­ÿ\@ä"™nSÙ–Ìd»˜£þèHbËþgÄ%>qŠ™¸bž9¹Å1–1�glãG­+DzÜq�y ß©yÿÈF62’ƒ¦d&/ùËu€2¸¤Lå2YÙ?X~‚‰[€â$¨˜,þr˜aöKC¤ì�ö§Ù„Þòÿ$&m'¿ºÚ�î¶Ó¬í‰�ºö6¯3îq—{Ø H¸‹� .d{¨Ý[½²]H,hg³š¬®¦v£ÍÚ8Û‡Áõò`éoó®(ÿ?²Ý:Íñ„+`áéö±ËnS»›?ð^5´ëýb��™ãfmÖ£¶©A мÒy¸'ÿÀô¦£¼*¯ËÍír˜�ùW3÷°ˆ ÞSå\Þ 7ƧæX]©ù&zÑßpt’+�‰MwzÊŽr: �ã辺Ì;œÖ¡ù\7Ðן=ïh“•ã÷Þ¸¹ƒ®_µýè¹Î‚ä'w¦?=ê¿»¹óNc¬ó�æú;“âðü þâHå8Ô>}�³'ìã²\;Ûý4`ò”¯üåé.u»ãýË w@Öûëw4�^$¥ÇÏéw~xs¯þÓ®çì {ÈW÷’¯üvÿëº[óÃæüÿŒ=Ýu (ÄÙÍß“ÂBoýj›Ä¯ ×¹^( R©‘oô ƒßøÿÿdH0€øWÄ34i�€ XS1Sø€xÆQ9¬g€¬£K63,‚~ ~hÆ~\Ô.·16W&$%ø—G×ÿç�#€8€h9¨€ È€#ó€jú¤@„qÃzxF<. Â�˜c xG"H‚¶a‚l‚‚€Â%+ø-_/ƒv#ƒ3Xƒ|sƒ8¨ƒÃ�?„@8„ŸV„ˆ-þ’„U´„ÛÄqí÷„²­!…sB…WÔH_YxAƒ5ƒ¨}h1AF†ÿƒghhMj¸†aC„_f„ØÂ0 ¢„°Q`àe‡!h*ï—‡%x‚@Th…zˆ„H{•&ˆeˆž„ˆH ˆ¬34�8U1ƒgPЋ¾ÈQ“¨lhgx–`º¤‰ ‰¯á‰ŠN(о…ògЍˆ‚ªøF¬8ˆ…Ø…‡ˆˆ¶hƒŒ¸XÎä3¼è‹½Œ“8ŒMöeƘ‰*³‰s؉ž}ûâ,ß�¤…ÔhŠ~È%̘�®¸kž$‹LD‹Ú™�¸(Ž¡t2åhެŒÃØKÅX^´"GȈ Ê8ÌH�`�£x¥8…ö7%þÒ�Tò��h}oHtã…x� ‰� ‰Z ÿ‰1ù‹«$‘p@‘•¸dÉŽ9+ùŽÉ�Ë8�‹‡vìr�#˜�Óh’WÂ%)™Š+é‰éIq³�u#“‰Xy5i“ሓ ä�_fŽçØ“™ŽAyCédí˜Gy3 Â�üó‘Mùz¹²)#©‡¬Ñ(¡è—àòHqÔ&y“7,)a.é•t�™.çr4Y“A–‹©¥“i©–Ù–jX‘¼t‘Ô”‘q´‘²~"ñyÉ”Ãt„•$™¢—Ew�Ðb˜ga‰‰7‹_�‹v™’9™ P™ y™µ… €–N¦–PЙ?é–SÃdqébsY—H ¨ª‰>zÙšNùšÒÿø³)Dµùš¿‚›º¹›½ ‹\ dÀY7 ™ÄYœb9–ÈéIÊÉœ.æœÐ ”Ó)”¡I”£i”¥‰”ðÑ&�ôwçd*rð oC:¡L2ÇQº”ï².[ð¡ jP": ¢ÞÂ/ó›ùYqc.ú¢j£2Š}Y;°ƒ@À/LŒAƌڇ£®ó r°DZ¤šŒ�¤JÊQÁ÷+�× ªG ªP¼"¤:¡Z¡ç:Š-úg~Ñ¡ÜR¢:¢E¦[p¢û’¢ 4+ú?-ú¢.*£2ª¤Jj£€ƒ£:ºd<:Q>Zy@ê7BZ¤FgHj§À¤1-OÿÊQúFSÚ,Þb¥nƒ¥Yú?jn]š,_ºl€!¦Í‚¦f:Nhª¦À¦ïéfo§rJ§1Ѝ€§c §û²£“Ø£žø£:ƒJ¨kp¤“«ŠªwŒjŠîñ¨(©ö¸)”Z–JZ ~\ªO*ú©ââ¡d:ª½Tª¼‚¢£¢ùɪ/ª}°êœ´j¶ª†¸Z`ºzH¼ú ¾ú«†¬ˆ:¬�×pÆ ¥f² h¶.1°Û¬Ï­¬ÈQx&«¸ù ª+¢Ê­$J¦®‡ªLÔ•«6w窖éÊd„d¬¨}C0²$¤ 1È„LÁVûe°JG×jÈzÊš+ÿ;°Z©–j°�زN¦°†É°Ù:¦Û ±h:±áÚ¦/y™q“±M·±æØ±Kö±²•G²%+¨'K/)›I+[T>ëb/›E1+mbz$«{³1 ¤Bš7Zµ�^¬”°xŠ›ÙéW",*5`UQ"z´{É/qË¢ð¹¢A31NËtPë‹éÊ/„TdLÄŠ*ÕtX;²‡²]Ëœ„`õu번JG%qsàq¶$±.²ê3lÛ¶n+p{©žÄŠt»Jvk£x;.±·ÁÒ·<ó·%O‚ ž S¸Á¨ió M›«•׸½ø¸û¹D6¹�X¹Lw¹C�¹\»¹� „Ÿë¡ÿëdc+D¥qã�º ºxʺlûº°‹7…K½V»tp»°“»ð¼»¾û2À¼¡4¼®s2Æ;‰È;ŸËë®Í‹¨èŠ@'#½ðD¹)e¹—«½ÇÒµ*À¹Là¹Eº¶+ºvJº$aºß�¾êk£ì{³î»Ð*·ó ^áëb@ûHyÛûÛ¿!ó¿Ìm�’¬†,œ ^æÊÀjùYŸõÀ7$¹ÿ#Áx@ÁXkÁ±‚ÁÌÁDåÁõ ÂJ*Â@ÂÙaÂܲº1Óº+ ¿²+¿ñE¿ö 8ø7œR~[T;J¬èò{¼q–¼C ^El§Î‰Ä‚¥ÄÄÄàÄPœµÃ¦¹)ÿ[ÅÞÛÁàûÁâ;ºYT¾]‡`Ü,b<2düº, ²s Ã�,Ãwk˜5ÌoŒqLTs Ju<¸ûòÃAÄ‘¹ÇÐÇJúÇ€,ÈDȆ|½lnŠŒLŒ¬ßÛ1Übã›B”|WÎü̺”.Ê7£RÄÖbŸõ�Æ7K<¬;ºò+JÓH�ô.ø³»±f<æ3AŒ}êI`^a†½¬ç3¬ AÃdJú “™`îK:$ðÖ�Y7D2°ÚbU§¤´B~R‚LNàÂdÕœR·òY$c€Ó)âLÌœ‚QòÌÐŒ-`¥>PÑxpÍu�Í\Ø{ÚͬóÍ€ξÿ2ÎäüFæü<è ê¼ÕÎîÌ®Ï0Ï—[Ï1sÏÒ™ÏK¶ÏrÐÏåõϤ#ÐɤLM7- ] �¤ ½wå'-Ñ‘IÑb‡-X cý(½4ÏÑÌ"_UT&�Ò*ÍÒ °ÍA Ó–#Óc@Ó`Ó7}9-A;ý=ýÓÔB ÏE%Ï1FÏŸæ3ævø 4úœ¤üìrþüºMÕÊDÐ0`ÐC…ЈªÐ ÇгâÐQ2Ö=Q(�ÖG°ÖdÐÖŽòÖ}’R2×Qð\Cu×g�ׂ¥ÍÞÇÔ~Í7€-Ø„]؇]>‰=˜J@íØdDmÔX‹£¯vÙ™ÿ=›=��pŸí¶�´}Õs“Õ[ÝÕðÕÂÇw°]Ö²}Ö´mÛ¸}ºmr-ÒÀ-TÂmx)í7.¦×|ýÒëÍ«ιòÖhûFºÔ ›’|±Ó JÕíØØÙE=Ù—ËÝ‹æÝK­ÙMÍÙOíÙQýºç é]ÚX}ÚZ�Ú\½Ú^ÝÚ`ýЙѱ}h~ß#«ÑcÀÑ5íÑü ÒàÛÿ�têƒ×ŽÍÅívÆi}-°8¸7ËÝàC¾�áTj*ž~°qá&�á@¨ÁÛÙíáÛ�@Ý=lð‚” àÔõIÞà¾+þ-nÚB2/˜¤ª�p¬�®-Ö9NÖ�ÿid…×ã¶‚Ñ?ÎÖAîÖYþFÍqE¬˜änÍM¾ÒOÞQnÜLå hå >ÓX>Ød±åØ"á½¢¯€IÎ�ÞØ“h朋æ®ÝüâavÙp.ŒoIçuŽJx®Gè]Õ›¤Þ�Õ>�®ƒ^èó�èL<ÛÚ‚ß‘žÛ“žÌÑ&oó6—^aD•é)EÜGðŸê[åpå/àà$!«\.©"è¤ZgÕ'ëc>Q~ÐïþnëL€ëD%Ù0F²»Îæ!îæ¿>ŒÂ^Ÿ¨DGy>{þâ}.ÍþìÑ~ã¯}è©èagß×þè·�íú½í{Ôífòínîôe×K>Ü›nàÇÿMâÉMêtÀàïžå%!ï«Þåèé+ Gùn–ûîIþîïïÌDi^ð#{ðïÓæ®ƒÙ#Þ%.Þ'nçÔñÆÎâÈNÚ|ž¨m§�^ßa=í0`ÖŒ¾,Ø.ä¨×Îáí*Ïò¡TÒ//àænÜ.�Ü Ó¥ا®K<Ÿ,¬•öþê1ôÂåLhÐøŽôýžôÿ³ôd`ðûÂë1&âŸì&ÕYŸE/¿Þ0ÞÞ4þÞ6nö8®:Nß<®RéÒö’þö×ñ*_tJvO=L~nN~î-M7ö|5ßî/Ø‚�§ó¾¬­^¬ñWŠ/UŒïø�ù~ ù œ_ùMÿùfJ­†¬Þã­ ¦õot죭ìì-ãî ßü…öjû!?@îöL�DYqû¹&ò $8ÀàA„,ÄÓ0ÂÃ:�LlPÑÂEŒ 52¸p!ÆÇDޤSrÌÉ)¬LÑÒåI˜c\ºLYó œ9Wît À' 3„}SÔh¤IM,eŠÆéS?Q¥j Z5iÒŠY@€@Æ+™!a Œ-PÖìׯÕ^¨ZõÀ[¸j'Ì•#GÁ]ôî•Ñ×oÀ� &¬BEÄM`ÀÀh�`!BæNžo�É.wfàìS€aNœ,^|©Æ†x–¬fvÈד'dŸØIÁ6ÿPܹuïæÝÛ÷oàÁy&,Ú‰ä •0]ÁÅsèÑŸ'¡žnê>Ù#Öq]Ã{ã‹ÊS§~¯ôé=¬gÏÕ=� ÇÏOm3åìÙœõg˜Ó¿ÅLcŠ)µ²ë£?ç0À¬²Œp£æÊв¹ð*‰Ž)2Ôp»í†Š Cl.2!4œ /×&³ï…3ZŒ8�‘ ¥saÀ¥XcÍ@ÓðñÇ.åš#àH$ãû(»ôÄpÍ¥œrúaJ*…³òJ,³Ä FŒCN‰åjÎF©Kº·°Ó.¢î¾O¼ùÊ;¯I1Økï=ˆ>úÊ+?Ùöã ÁÿZð*M(ÿ0»û[�A�€Ð4 +¢p KÒpCëðP¨E4�D+¼+ŹVlñŒ‰“ñ©°1QWã1»�´OÈ@ˆÓ4$“T’Éôžl)Jœ¨¬RKf›m–K/“ ó 1ÉŒÎL4P³�íÚ¬< àOλè¬ÓNðÌSO>ãô3@O”?ÿÇElôQ³"�ôªJ¸4S 7�¢SO? Ä#+ÓSÃRѾU[%ìÕXgűÖ%ní#Wƒò­"� –%c =cS@e§tvfšƒƒV´/§¥Ö4k¯­©ë2°Û°¼ûöÍ„ú|hÎ&Ñõ@9=óhwÜwã]ÿ‘P{Å·#U�Áü½(Bƒ&¤�`ƒîôÓf¢á3<1â!&¶©bÀ¸Ä¸Féh­Õc�Ó¹W’½êd”‡í£É–_Žù‡š#—|K£SgæxîyºŸ+�¡Ù,ÚÍÆÄ%oéré„ËW„¢NTi?­¶kCï0_¯ùmðÁ±)-ÛÒ³ïº0íÙvî‡Q”8UŠ]Ìƽeí{ã¿o |pÖw>üä”Wv2,(‘õ˯É˧ùæã¤Õ¹Úͱ:M¡×änô£KOÚ]óRorõÂ[×óuüý PW«Wí´v;®1j_`›È6³Qm+žÂ†<¹™J¨š€ªœ—ÿ½ÍˆoÑñ›Ž2ìõO{IA\÷W,ðK|ã“�ùlÈ,ôå sÍq�kBðC 6‡ÝüzØÀª„ §ó“¹†µÿáh‰y×D¬xΡP‡RÊÖ.еB*R²‘rä2— áe$Z‘mÜH��¨PI!‰.ÕðèŠE«jÑ üx±WÉ(1‰ùR¢˜rÂ\­è‰†cáÉÚBïá±n¢¡ ÜxCLÚ¬r8Sß´xˆG Ñ4C,¢$‘H%MTÿ ø˜DMïŠÀ'’Å-ÚŽ@ ÔW‚t¶1¡Œ 9ãÒx—5f¨�o„#¨äø:ÖQ2’¤ùØÇ?ÿ&�‚d iH òGÒÂ"ÒÒ�摈$/UÉKfRžÃÙdú.·>ÓH2”?"ÿJ‰ÇSj •R[eyœèÊ„¸NŠªœem‰Ë¬u�_T /Ìa"¤˜ÇT@2§°Ì7Æ‘ sD 9ïˆGk^Ó�+d »éMä€3œÖ9͹B¤¤s1ëlgßIÃxÎS¨@Éa'ä&UŸûìçêþyDÞY ‰‘%-�b”›R5ŠªªC¯QJt—í%‚~LaJÇŒ™ G= R7Š”¤0)5Q²”\ó +mé«^úMCj¥"�³)BÏi�€§/d™;) ÔÛ uÿ¨O le-·Öµ$U© dê(ý)?SFuª誟®Z”¬’v«L)myl‰ÅÙ�‹%•f¾^{VŒª•˜lEcIÔ(6Ú‡™ÍlÛ3[Í:ž´‡)å#_µ¹Í¿Æœ‚mÀFRØÕEÍF‰],ãKxFV²ó¬¬e9yσ¬¥#šEêRCÙT¸<Õ5(ËsÚ7¤V¡\e(-_ ÖÙÒµ¶¼¼íEǘÑôòÖ˜¾E&p•)\fÊš´M®]—‹×=67›1‚n7›(êZ—Ø…‹v¥ÃÝGö”ƒ“ /ÆkC. …49ÈIdEAäXÇ`+Z¼R ùB¢%�‹pd$ƒK]ôÿmÔšƒßB™I½¨H|¼rÅ!—$ɽ» 9´‚9­ cŽC™“Ë.G$“±âHê"š¤Ds¦h¢/=&2\¡LcÅ2˜ÌfU_øB`°ÍÇ86Wsmp!AÒ“–ŠT¾ô%$#Ù ›æôX P_ª&„þ•pêK.ÆB™qx bãÈàXÇ9æ±�Éd!g¹È`Ëô‘Á5D&£R«�yòi£Ü9¬4ÀÊdÀr–·ìÀQIóË–^IÄLf3#ÍÈ]ó\Ú,’7Çùs–@� sgå™ {†@Ÿ¿÷gZ6ƒ.´Å£hÑ0<�æw"=iIW:*—FNÿ¯‹ÀéN�ÔPuJHmjT§ºf«žA«ÃõjþÝx"³¦5Øl�k g™»f�ÁÍ¿` tØ)öU�}&ÓT$W¶¢ÈŸ 7M»aFטËPæ8œ9¢îö¾Í�p·¤&ä6÷aƒgäèY|žŒŸ‡àiyŸ€Þ†Fߢ¥Óè~;ú߸®ƒ#|Óž^xÃ_ðð)�:Ÿ8Œd¼c|u?ÇQkƒ¼"'¹YL`ϧÉzj¹Q^Þ™„æ±¹¯¹ŒÜœûÌզõží&l›èaóDÜ\q3}Jv~zº£¾î©·»êï¾: c3ïšë0 hôÿݘ°‹<¸ÀmmpZ²=Ô5¡!>wºÏŒâ¯qÆc½qŽ-‚'ü»ŒÜ듯.åe¹i ü÷]%ò1˜ü*_„a>2:ç¹�|t¡‡uô1(ýNg¥“3:[½sk=&P·�`7wë!¬»=­Ë½z{âè=Ãø½ø >¤;J3>[ó±äS¸å£Œæ+µ¸‹¸è{»c5¼sµ€5!�µYÓ¾¯à>]ó>^?ÄC9Å6Õ"6ó36ôC6¤X¿ö{¿ °:¢?Îó<üÓ¶¡C¢;º¤K�¥À`½&€:%�:ª› «kÀ14ܽ ¤@ ¼< ô·á#¾²ë@ÿ|åc8æs8ç+Aè;AŒÊJ,個H¹-O# �ó1(DCì>?ù¾L ¿!Êž•ö„?˜D£0“ôK¶ek6:0°«Ø›¦ Ð9‘c��¸?Ð=($=o3=pC½7+ÄB-äBÙóBÚC1<ݳ7 @8C °D!¾Æàc<Æ…[87D ZJÆh$5R“;¹ÃCD€=Ô©>|‹?´¥@Dñ9Ÿ3Dr,ÇÂ+‹ÃkŒF4,òƒDöšÄ?¨Da„L?t@ D+Ê2@JÏ4DIZÑMqJGìÁ¨|GJ,Š‘´J{ÔD}>~”KPôÊ K±,H²T3U4º³œÂ*dKÿYœHZ¤Kx˺­ãE_dâC¿”À LÁ$L>0LÄ$Ål»¹˜Éšü‚ÇŒÌ,™Ì'¨L„¸L#ÈLO»ÎüÌÏ ÍÑÍÒ4ÍP´’ÊÕ|ƒÖŒ¹z”¼{¤¼|ÔJ.ãÊPÔ¼ˆÅõ(El#ÈÐ{²ìM)LËàl:tƒKŠ”K‹ÄÈxsÀäÌËÁXÎOiÎ猎è4ÁDê´NÄÌÎglLiüNð”L=¤Lm´LnÄLoüFõ,JöôL÷|Ïø4Mú &ûŒGÖœGý¼JÿÌÊúÙJÚôG­õý<EÅEHßTH´dÈ…È E@ȘËÙcÀŒÌE¼ôÈ2ì=æ$¾ÿ…Ž-ÑmÉ}ÃdLštÌ›|Ñ+)39s�c”$ÜəÔ�À@4_ôEXTFeÔÊŠ•/Ñß)OþÉŠcD�q�KK?�pÖ¸�êØG„¸Rö°"×ø —ÈE* t³Dê☯p�˜8‰y¡\ŠX‰²„ Ö˜ ×À‹½X*ÝhÔEõÅ,hVgJZ¢¥Ká1‘3¼À‹£”¤*ØVnõ ÏÐÓfáSêðSëTcTg$Th4TÀØ�D¥@emÔG¥‘H�Ôê[K5F„¡%MýN]O] Pu Q%Õƒ0Õõ@Õ°PÕ–`Õ)qÕֳĨ‘U¯ ÕÿZ}\¥]¥^-ÕÈøÕ¹Ö»V*Ö9VàðP�Öhõ“i›j¥“k½‹lÅ#níVoEVpÕqMrÝsåtMFuvMw}WЈWG¥,HEIÅ׊¸ÔNáW#ØÔÎéT®øÔ’Õ UÙôX!‰S�ˆTõŠUÝÈVŠW5“‰­•Y ‹ZŒÍU¡ØUôëÕ�] ` aÕ b5Ö)ÑYßPÙ¡`Ù–}ˆ—e�˜m’™U€ší¡›ÝÖœ5Ü�ÝSgb‚>UˆråŠ@Å£AU×£ EeZ˜W*¨W©¥Tªm«å¬ÕZ˜«®…¯¥°ÛI![³MXÿ´]XµmX¶}X·�X¸ÕŠ º½XdÉØ�¥‚Ž=ؾ]‚¿‚Àý€Á=ÙÂMY dÅ]ÜÆ5‹ÇM�È=ÊH_õå’Ì¥™žýÙÛ Ý]B-]šiÚ'xZ%ˆÚ¤ðI¸ÈW>Ø×wéWäøWØ%ذ(ر¥Þ²ýˆ³=‚´%ƒµ}À3hÛx[êˆ[™Û!¨Û»ÕØ¼åØ½%[��‘Í Á-YÂýÌå ÄŠðmÙñ-‹òE�ÈaF_õM_öm_gy_ÏZÐ=WÑMWÒåŒÀ¨üÕ_þE ÿ} `?!`%0`Và!`àÞuàßõ…}�áM‡ýˆ•H‰U^ÿ¹­Øæ�‰ŽÞé5_õÛ�Ü‘]a—Á‰~á¤UÓO™áh­á¸a1Ðá.Çöab- ·QŽø%L׸ú=Ú%¾ßEU]Öíß©… êÜŽ—à¬õ×­Ø®د%ذ5X9æÍˆà ®à>cIãÇÈ Ö°µí€‰7aé-a>á&Ù<6Ù îÞ߈a¶™�Å-A¹ ˆfi6äæáþaF¾G^H6e ÎI.‰JVbCCZLN]§¥W¨µW½ódÂåÄeÚMŠÛÍÝÝeå@X0^1¦`âµ` Öà$ˆ\^ ]Ž^~^¼�½mŸ5a:Fa;Vaÿíeaîuá,YæO9Ji¥jÍ2ižfjæ’DîlÎfáØæPéæ.â• g:ç (gsž™&VçýeçäŸOŽˆP®âQ.àRniÜEeÝUeÞíß…`à•`áõg2.^3>^4NÞ[®ˆ\ö±]>‰^fhvh¾ažhbΉ=Îh� Ž~—gé�Þj^’Nä“FiïU�GNˆH~é°¸�º-Tr64&Îät^Ýun݃P—ž®ƒŸ.+ÆâSNàT^àUnàV~àWnêXþçY¦êZ¶j‚(è%8è:Hè(�^_Žã|®ÞëÍÞí=fŒÆ’´VërŒÜÈ%ÜÎm ØmÞ~kÿ¸i)麶ëÃ5Œ¼Fˆ½–_¿®UÀžérltÎ_œ~â PÅ~gŸŽg žçÓðf{Fj|Öç0fبhãÍ`äÝ`=mÒ6íœ@m¯þe°†hë­cì½ãŠ.æ³–íÙž�£´í™ÍmÝæíÝöí¸žëk^dâ6]ãæf½öfpîk“`îu ìK¶i–nÃÎiÄ6ˆë^IxÆNy&åÚ­g£¾gË^m̆姖勦eÎí�`o­Fh®VhŽoÕžãú–èû¦è×FYþžíÿp¼pÜ&ðënºVðß�^¤@·‰rB˜×Ò-ßrr#·Ë­™¸Æ·ã0 +—&,·¥ÿ-ßr ºB­ƒH™÷{¶¼SqŽ)�–!Öœˆ=ß󳃯·€ó£‹ôX‘š¸ƒ;(C™-ó œÈ­[žX‰šnDUÚwE´’Žò¡šòÞ«r=¹òNÉò4ׂ.Ÿ³/§™0Ç7% óN7óOGóP_ó2ks|s%‰s˳:¯;�¡™x™=ßóà"@ï¡A'ô0tDŽ«Xt�iôZ}tˆôÈ¡ôJß&L—8MWé)ó::ó+ uQõRŸ™SW´T¿ n'o·"p‡õ8�u•C@2¦dAg�]‚™(Ù<ÿõ(vþv×(vBGö-Rô5FŸYGti¯jOTÿD»öTËvרñ*.p§i*w/QõÇÐø«}—v‡uxW8ï!:¨÷‹ËuÉ÷}/æœp²°öZô! ø1xAøŸt�Àʺí·§™ˆnŠ1‹WŒ×’—]“u�7�Ç‘'ˆ¨ßZ:ù5Où„XùIvù`Öõ‡¸s~Ç ›ï7œ��ÉÞyô0öc?ôƒ_ö„÷;¢¯U£¯x(_zlwÄ�§Ïƒ|)"³èzªn«Ïá¡0Žª8÷¤ ˆÂ—ŸÃŸú476ÿ�ÑÒ±ïëtTŽ{_ ™ß÷—Y{~k{�x{žO xôùD·û 7¼ÿF˜Ø‰½gú¾÷{¦—HÿÁÉç%Ã/ Ä×Kn×Å_€Æ�ÇùÉç–ˆ¨|?Ùrýü&ÈüØü…èü!hy|yå¨ów™ù)3ýGCý�P}:©‰Ö§ûŸ‡ýH™ý@¬ý•¸ýñRzÝ*àý‹÷ý�ˆ û,Xç`�„2Ôâ0Ä'¨hñ"ÆŒ+.è8㣓�F*©`Òdž”/4ˆP!Ã…µ@Ìà¤I“8:[ð©aPBc-JgÒ!tŠ0mjá)ШR—P­saÑ¢+W¦ìšçäIbÇ(k6+Q:G“ŠiëöÜ?rïÜáÉS,X³Fö êë×àÀc;(üå0âÿ3nläÈŽ'S®lù2æ�Tpîüô³¯)[˜z5D�ÂãØõ)(Új—/mÊ4ÔãU­^M¾U`n°&Ç’5[6¹Ú¤Cܾ…kž®ÝxOêåë·o`Áƒç#Nüú~dÉ÷÷óï¿sgœAšh»õ†ÚUÀeКDþa$[Gµ…tÛI¹ØÛo7q=�tÜBˆ8"sjÅØ€ µ"©Yw]vÚq' 5Úè]Yá±Ežæ�W—]ë™ÔžïÁwâ|ôÕ÷…bR–dNJ9å”8 …¤˜!M1H%„³IHÿ!Jj‰a‚fÀa‡-w܈$–x¢)Ç¢P.¢uÝ1‚5£ 6Þˆ£ŽHñØ£�/ ¤ y•µW‘FÒ™ä`K2IecP"€)§�^f¥gÐeÙÒ–iv¹à—S†)¡mÚ�êÒi\ÖÄfq§%ÒA§�RáÙbu{Â(šv*h�8Pèx<&ª(�w5ÊÞ£î½7)¥–6é)Fšrû-¸,ˆ;.mI˜[슖Ôíº›¼ñÚ1/½Ø{¯c÷ê»/ƒ tð/ÀO<–Úý:¦%µ¥cHðð?0±ÀO0Á„¹çÞ*DQ %Å!ˆ€>{ˆ ë“OÎ1eÿÌ1#13ÍpØ|³xHA±3Ï#øü³A M3Í5}4Ï<°4Ó?ÿLÔQƒ;5ÕUW4.¹!eŒ®PêÆ®»íÆ+/½ób¶/Úô pÀ‹U0X'|ÐÂj5ü°ÿ0ñ_œqlÜñB‡ =´åL3½9¢/ÝùQKm5ë­O‰µ¸åžkp×­‹TØb��BÙf_–6¿ ²ýoÅÓÎ"Â(ŒÔâ­7ß~c¼õàDyŒÈ#“ �É‹7.Õã,KN9Ì–_Ž99A:êŸm¾é�?êªCí:þùßÿ; ²~¼× �”ä%ow)è×Ù€w¯µ ¯xo;ÞŠ’·<¥ØÍy“Åö7êIeD„‹€á´—8¸�ì{Q ŸOèD>3˜/5 yaØ×9÷)à@ñ›ŸéP€òP>ü¡cøç?®1 €$à ˆÀß)Ð^'x" è@�Ð$rSݘWÁ$=ƒ}Óàô4ÖA}0„ˆãžâ¼g p$t‚aBZx8Æps¨ûg`CÓáPt:äá�(ÈAZDˆZ›]Üj×‡Û ‰IÜÝ-ÓD'Bñ‰Rt!( f‘‚t¸Û÷–A‹…1pÕ‹Áõ†�½3‚¦{%\c5ðF8Ê1ÿ&t”¡Óòø‘=Š®�Më IÈaúp\8ià™.Ò$%0ŽŒkR%É}=«’–Ü ªX�á¡›œ¬CÝ>9(vQ”_$%à7FŽY¯pØ;œÈFèJ”ÁR;¹;Â,a˜±g>£@ªK=ö憛‹_¿‚b2ÆÄI2ÿ·ME¤™€y&¼¢Ùš꫚Ö4`6�×M<|3œó!g(£Ætž2•«Œ'YQ@ }p¸g>_¸Ï9ö“sÿ (@ÊËÑm. F=jBƒÙÐ¥Zí¡ÈLæI–Ù‹£)Шk¦ÙÑDYó �‘6¹é͹�S‹âJóæEé±t�eÿ|§cê“™Ò”;6Åé‰è¸S[ö ?jPu9Ô¥‘î¨He�B™ªØp‰ë˜�*E BU«bµALܪ�ºúUî„U(#-©YOúÄrª�ŒŠÛ B¸Žl7�Ó]ë*–»æ.§0ÙknéÓ–B-(‹jØ($�‹=n§œúX+F¶“E"4½´ÑˠΣ•ܬñɀϒդãmJG¹A1¢–Œª5£È\ ¹ØÊ–¶a³mp»Ýúõ§@ýíiâw á±JE.€¥¤\¨2·ˆÌDŠ3¡›Qéfµ2ÕåêG± V‘Ž‹eõ¤hO@Zñ–R�åe'*Ý©Jx†@½2M¦ÿlÇâ^wÁW¾¹íë_‹_Óè·7ü-n¬cÌhê#û›«RÒ€!ƒÖ“8²y 〨 SPÚ”£œ†)Sy¤#%–“Ò°@ÎÃAñl7©œß0$^283ƒ=‚Gœp§X4+ˆ˜5Gº�i/½¤9ÚÑøD:]щN"ø3 Õ·ßáö‹ gøÆ·áu`ÇŽvR�gðcŒ9Cn@‘—sd$¹0Lvr~¢åÜX¹›X&ƒ–)Åe–yybÅCœ‡@æ…˜ͨ’ˆš?Âæ±¸yfpž²úæLç:ïÏF;õ©÷<§>ÇÐ�ÎÙ  ›CëÑ*PôÄ­í*AÉÇ?–h™,ÿMäîšuÓ�^2ÔšÌM‰ʤ.õ©S�¤U›ìN`†5°‘2ëÔZi^@w-¤“¼™ ±Nа¡PçßÙØÈÆ²²™Ãìf;[‚¶ñp§ »C#ÛØ6ÈýéIƒ»]¹t¦Õbn¸(ùÓë~r»ßmåx#eáôVœ½·æ|ËA´†×™ý}ëäzŸX Þ‡ƒëLØ ßÍ¡N†ˆ/gâ�©¸øw o5†ãòxÈÃŽŸnKúÛ•F9¹�Œd–{:Ý Ž â.w™_9Ë5¯óÍ –ó‘ÆzßýþwÀ›Ðfí(�éës:±Iõ‡SÝDV7ÖùÇh®¿�ÉNò³~‚š^ûèÛNu/FS¨O½hF4Rõ¹žÕ°Ç·ï{“¿=÷‚ç5á}-Ùß'œMP>ã7Ççi ùXS~~0ßòA¾ÆæY牦¥ÝõqÛ¡Ûö½d|䆸uùáÝëùʽõí±îÜš½ßÀ™„Ò[Âí ›`Ýâ![ñщ¦hŠä åuß VÆRZ¢è•ö‘^šÞ~ŸŠÈøåLùÕêÿúÍÞúٞЅ`à ^ÒÉŸsÑŸ°­`ŵ`²éß²ÅG BÉ ²M jÆ æ !xVˆç-àª�fræ¡$¡x,!Î5!ßñœßI!à� ¢` r¡³y!Ä�!s%VâæGÌjÄ&®¡'Z„ǹ!¡¦ˆžâ!´ÛPà†b j ù bìAa™bû‰ ®‘  üÊ j!X1£#$’›€36c%Zâ%BF&þK'vK~"6@(–݆›ZŸÊ¡ö©"+º¢ÂbÊâÒ"FÅ«y`¦@Ðb/r0.ÿ¢0£1r â²-c32ã3Rb4JcòÑà5rbBfãŽiJ˜Jâ‰J¢ Kº¤À$¢Í$]Ô¤MzNêdNò$¢ùäOª@P%]bŠQ¥l$åRâÈE^EF&ŠXJeÄxdUâÈU~NVBÁVÁ€¤d‰¬d¼ˆ%YˆYÒäU¤¥Z^[¶å’ôdµÅ%Pÿ$ÛÔ%iB”à%„è%²0¥:¥ö@åF æfašÅa Mb.fczåc‚edºädvFe¢¥M®%[ZJFÀåOòOi6'·åjæåD®&_6¥_>%`ºäl'wÒfmÀmMnÆI‚†c2d‹d“µyqÞ¤fn&rJ` :§}ÚåiFgDN§ °æH¹æÈÀ&ÞpgwRåw†¤ËŒ$`”$yr¥yò&zú¦zg0±M¢aÛ{™qîä’`4Þ'ˆößÜåQ&eR²‰²”¨È(Ë¥]�nçn|gx*éðJW²ÈWÆÊU¬' 1šÇõfn(gÖ‡‡^bˆ&ékðÿÍ1<)”F铚¨D²‰#©è¯€ˆ‹¾hÄèìÆtP�P¤±ÕÀ�žÈfBW)™’uUjÐÐ@Yèµa[o±iaˆ¥ýlß¾é*©ŸZ“6iH)¡r•®�•"–≖â—viŒ‚i˜Ž)²”陯Gš®©�ºéUÀég~�–�:žÚÚði}þ©ª6F 6i¡Jé¡&*-*‹4ªw<ª—JêtPª XêæÐI¦ZÓ¨rjLxjµg¨Õ¨–ªêœ*}VãªFk«:é«Bi¬rÈ•–Z–Ç–¾h®’F˜.¯Úˆ¯& °n¦¦²)±2„±â²*Z�Ú)³2Ùž>ÿëBF«´NŒ jµN)•ÊjòÐêŠØªYàj¤‚뤞™Û¥F°VÒ°ZÓ›º�r©¨Ê«K橳²!´âk’þK%%Œl¿¾êÈR�Oï½J/üb õ®�õ^/à®îžïzoL€oôŽˆ/s�ïr8.ú"ïò¢mÚ¶¯ûêGü>p§Ìoý^/þnïîv®#ýn˜ê#1°êoØ–ˆµ…ɯ€¥tÒ2H ·0•HpÔRpöæ®ë/#‘O[�'.®# ð [S ·Æ ;ÿ° /qÀ°ÝÚoƒF±¨h_…úìp›­®Ð�ã1úZJ ñD$q”0±[F˜8±ýÞï ˆMQ1[qÎ`qï|p‰pqÛzqò‚ñ‹±D�ñ¦œ± ;Fw@ÈVo ÛnÆ—ZÇÄsp÷ì»OCH ó1úúqò reÄß ÔÉ–²)Ÿò)K¤@Š´²+È�¨�uuUZáM@2£Ç…‰c(Tb�²/W�(OÌ@‘2*óȪò*�+¿2,Ÿ†,C-×òÃÜ2ä2„ü26/V0?À0ë’132¯ò2·r3;sÎÌr4‹%5[³ld³;7Ô6ws}üs1KNü¤F9›Æ³ 3-‹å;ÿó¶Å³`ñÅl0Â.(¼ð¾Õöû¯ÄS\ñÅgL…Á\pì1Ã';òÄ&Sˆrʳì²Â0‡ü°PÓ\3ƒ«æÉò·-$=ÀÒy4íôPGÝÀÔTÁÕX‹¡õÖ¡à5 2„�ÁØ$ =4�Eãy´·I·°ôN?5ÔS7PµXg½µÖ]ÿ¶ cgPvÉg˜ö ksÑöÛq7=7ÝT[�w{ó�Â×`‹M¶w…xxâ‹3ÝøãÔ}÷ä”WÞ·×>x�®©Ñk‡÷è�›.yÞ•‹±zæ€oŽjì~^»Ò¢ÇMºîxOÞûï­ o6ñþÍÙÄõ‰+¡ýÛŒ7¾Å÷àß}÷ä—�Åù\_î·æ‚sN=€Ý®­½Ü/ Áýøƒ¾ø”o>ú–Ã\ôÚ7¼÷ý'~G›_ý€¿üéo üëŸÿ†p>,¤O€ì{�„@–)°~ ¼ß!È¿ R€¾Së2è¾ ò§ƒû ÷B�FЄ¼àú‚GÀé•dU²z•¬ÿVåBÙÀ°^2| mX æ0€;t] ODQ QTD,âeÀÅ.Þì,K‚Ç(„2šqhLcïŽÀÆ6Êá�pÌÈßþ¦+Ü Â mb�÷øª5øñ�¬ IÈ/*â�ˆŒXÄB£E²tÑ‹7 ãÅhÆ3¦�kl#áGŒÌ1luÄ Ó´G>zê�€ $IH†!2‘Š\#)–Grñ‹’œd%ËxILVN“›ä¤äøÉPÞe”h*¥ûˆÊ5¨r•¬ä€+_©ˆXÊÒ3´¬¥-¯ÇÍ&ärŒS§8{9�LjR˜Ãôä'­i’<*“™¨|f4¥y.rZs–ÙüŠ-ÐÿMìl’bç8{iN7 “˜sdgIÚÔ¶¶qÌ�¨ÇæÉ0{ÆŸùìÊ>ûéÍT á$ç3�yt"ôo UCÚ‚‡F¢�fE{yOlfÔ+�|G¿P�ŠT•$5©:Ëv¦‰¥-EØKaª° 8õ©3½ä ¦JU�Dv7uJN9ʱºÕ ¤SÀ¡*y@Ö²žà¬hÕÕV~�Ò�‹eHuéK=öT¨Ö³—T­jG®šU­ÞÒb\E˜W§Vö®¬fEëYÕº•¶ ä­‹«R—J׺^ ªiÌëT­šÂõU)[ígW[Ø ±ümM‚ËÍá~¤†­jS«Ú冤¹ ‚+t';×éÞö®RÕ,v}«Ý›ÈŠeûî>ÀßþÎ3‚@¡¦"*5’ÃÑË£“$]ãòà±[öKˆ°„ç™Üj«¾-¹¯ÁòKØpö׿ÑðNLà†Xcõhܸ7îÁžp4+̾ cx%®‡ Îó÷¿ü 05KÌ�¯ ÁcdqÜ\7Çx V­…§xc˜äø[;î±��,>!¿’È02OWü¸3ÙiNŽq”;åV9ÿ&WöV–=¼åó�xÎ3‰M•1#YŒJvÚ™›–f³’Æ<´ñ›Ogŵ�\úõñ¸|·<ëyÈ|.ðìðtà4ÐMt áyZáÔV8ë—ú.Z%vʱ¸J.°JšÒU³4žÃÀë^ƒyU*3éˆ@ìb{,¢h¶¬¡ ˆf£:Õ'Xuà\ýj”Øi§ ­ `ë:³2‚º¦C¯{­[©°Le¤Sñ‹ml…!»i`]ö ›ˆg«š}¬¦vµMrí~Ú«c ëö‡qí�p�›×åÎɹ3–n€®›ÝD86D�ïRG“Þˆž6•÷Íï:a»e ËXÍ@ò’Ó¶(ÿO¹Ážð‘,œ`¤ëÃÙ�Ôwç¡âP¾x³3>6Eã§MWŒ”ÏûÓïnþÛc#/9ÉOžr”¯|ܺ�ƒÔ§þòyŤ3/vÍ'o�Ê›—r�7î {JVCçOѹyô€ƒTéK_jÓ�®ëƒ‡!êS—zÕåuu�f�Ø[·Å½nqV†�Ícws}Vu¸<‰àñ��üãáø7ˆ@£óyÖ¢TƒÎG” ½èAßùÒÃ`� ~ò‚ֻ^°�ý˜Û€š0ö±ŸßüFÏÕ‡[ À~r]«ÆoºQ’Ã(6Ë?óòѼ�8ïyˆ.°ØÏ¾é;�úÆù^×®=ÿîõ0fÕÛ~‚ã׃ÖÏ~ÞßÒÁ¾j‰Ÿã'êUÉ_þ+ï|èÇGúuB}0Q×—}Ø·}§W?©÷d¬~!�~å÷dçç?éÇ~í7zï—gñ|ÃWT¤)¥2ùw.Ì'ÎGþ«‚SzX?ƒÙ·@xPƒ6˜�xæ€! {Ú£b6xƒO6O·÷Rêg�à~ ¨J¨t ˜#¨Hð‚ý¤25p…X¨rÀ–—‚ﱂUØ‚Õg(ƒHƒ?ˆ8H:ȃJàƒi¨zBˆ~Dh„Gˆ�I¸„Mø„Q1S˜(,H0X˜…$¸Í×6µxTØMø‚Üÿc†1ˆ†?(‡ƒ”g PF®ç†p8‰AMCQEh�¡>¾·„Lè„_…«%ô‡s²G�8/ƒx…ZGºå…ëq&N°‹¼‹òB[e‰ ‰@¨fä“gBz™Èƒ›XŒ_W>µ¢uh„£ø=¥¨‡¨è5ª¨\aMÙE¯¨G¾H³XµøF·˜ˆñ¡‹¼¸‹�5[KŒ�HŒ5(‡ÇˆgÉÈ˨{ÍX��ÈJÐH+ÒŠvX�[p�J¸‡©˜VÝKߘyr‹a(ˆ³xŽr�Ž�AìØŽï(.ÀƒÂˆ}ô¨† ~¨‰•†$©fžH>Ñ8~‰‡1ö{؇ƒUûÿŽ,0Žåh‘º•\4”BéÙ‹¢Å^Žø6!)’õ£’#Ԁᇒ“¤’”�.)�0I�£§’4ɵ,ú†Àâ):É“Yˆœô“ª%”Ci«òE¯t²OQ”îx”ðøRòh†æ”•û8?ý¸’Ïx•dP�Z)z\©k¸� )icÙ(e9‘²x–Ó‚Nj©Xl”—ñ–7—g'*t)vé.ùˆKÙ—iø”&•̘’qø�„�‡™•¢¸•iØ•ò§X`‰“âáN¥ÔLk ,²bœL°œÌé‘5øó}u0�u°shÅjcóЇS¶Ô&²ÒŽ»ø*:ÿ0žäIR$pžè™žçÉ2ÌÉœ2¸@ Ä{´7Bã•.¦¨„&Ôv˜˜1ПàÓŸ1€gþSAA`p ¥·3 _âT+åsjyõ516}1œ¤¤LƉœ¢Â0í¹œÎiÐy?ÒI�Ö™\g¥�‘Éûä�¢žN žä9ž$•4Z£êIìÙ¡ï ŸÜ#ŸƒEŸ¨eŸ÷™Ÿû¹›  ÿÙŸú?X`ºu `� S. NJ>JU*ªšLÚL)Ú¡¢0¢ÓY¢&Š¢aéW�Ä¢‘â¢0£3Z£4z£9Úž;Ê£Kã£^¤ˆ%¤¦H¤Eº~¡‡¤ß KÿJ>ZOŠ �§ U:W:Y:U[ê]š_z&ÊÄ *=Pª¦Ê0sWg 5ÑY’ÔY��`¢hå¦Â +š&ß ž*æ1wЧ ƒÀ¬Ê}ê§Hc#DR„º„†z¨‰êŸ‹ª¤t0 ç㤚¥Rz/TÚau©™ú›Ú© ð©fª£ú(¦zªç’ª«z­:“tðªlš\´êHÝ™&*㢻ª0¼‡§4ú«Á ¬ÃZ¬©QÚyó2.[{ßãµ`«¥"Ë¥$ë¥Ìq&ƹR ¥¶kÛ¶o›rq˪"d�tK³6{³°�ÅE´S/~û·“ô³£ç¯9 ´Áz¸‰«¸  �;A�H‘Ë? ë¬Í±ë?™‹µ› �ruÿÓµVê±X ²¤+¶¦K¶Â¡ºÍĺ…0… »ë:w³ë®"êªv›»y]ô»ß¼Â+FÄ+zÆ‹¼Àª¼‰»¸Ïë?ÊZ-Ó+>Õ[¤”­–«½¡¹¥÷½· ;¾_[¾a;¶¨[¶fbœêÕºðûº+»(W¿ï*a3›¿6»¿¶ê»jc0ÀzL¸k+ƒ´·¼ üdŽ›°ÜK’k½•Û¨C°½›µ¼­<RÞj¾šZºœzºžšº%ÜL'ü¾÷¿+<¿p»Thª¦°ª¿»›¢KÑ¿7 ¼Àc´Ã ×ÃÓR¸@…K[Ncƒ#D,þ£[Ÿ$¤²¡Ú&«r*‘ÙhèVf-¦0 ôRe¤’ÚFÐAv…ó¡O5·KP+K¸5ZðÐ=^í ­Í2´¥z&ÐþóF˜³B2ð"ý'¹Ä~fVâlK(Ð�9kUÙl&{Gÿk´àü@)MÎkkÎMƒÎ¤ÎåÃΟôÎñœ&óLϵzöÌpø¼dú\?ü,þÜŸ-ÐMÐýeÐí•ж»Ð´ÒÐZÑ�Z]Ñm0­ÑKÀÑåãÑý7"ý$�`&]F(-Î+Ð-ý5/�Í÷Š&3]Ó~zÓú“ÓäSÎKuÎ5˜Î°ÎšÕÎD­Lò¬)H�Ô±Ô0×Ô‚öÔÜÕ„ÿÌFV}ÕüSÐ5°Õ\ Q^³`Mb-­ýI ­½TlÝÖÝÑrÐÒr=Ò~RÒëwÒ •Ò{m}í5�ûl±L0„Í£† >ˆ=ŠýRŒ�Žÿ Ùy%Ù¤RÔhrÔôl‰ó-õ5fæÙoÚú#ÚTMÚ¥�Ò)�ÚªÝÕN¥Ð ­„[3Ûˆö7·�Û»ýR½íÖä×ÒÄ­Æ­È-PÊ­„,ÝÜϽE¶$ÝõâÍE»¼pÝß“ÝÛms>­?@M>B=G“]J•�(—�ÞéÍë 5#ä1ûQeÚ£}¥mö-Îø½Õú}üÖþ­5¾–�9ài]/k­Ñ> ¾Cs]מ–w-y­ÒÎ×¾0�á9c0~†þá9ŽÓãœØ;½Ø=ÝØ?ýØAÙC=Þ”mÔ–�Ô0žÞ3~5îÞKßà#ß1PÕVýã6ÿä=äEÛG.Û˜£@¹äh­ÛjÍÛlåSÒU^Üv}Üx�ÜzÝåÌýåDæð'þ-e>ƒgþ6áâ?¾„ÁÊÓqóÝåCHT%Þ“BÞgbÞ§’V¾§}>BýU.7Qi>è;^A�èŠþ¡CþTª·5K˜äœIé· 'üy ×ÛÀ-ÜaÓé‘Â2vxè.NˆÞãâ.!�êª>æn„Õm´±¾ˆNëÀjëNƒëä£ëSA+¾GP ¥áFÖÍ+Ãn0ÌI[*µàsìäx°ìßCèmäì íY]¦¼T¤¶Ö®„ØŽV�IÛNÑÝQ¡îoÜq=î ÿ¾ð\pîéNë^Úíþî€�ê~²êÞÒêLùêpïù®„µîæ·çþð/ ðv^J �ð ïéGÓðKõðñüU.oñ[€ñl¤ñ>þã¨ýñ/ò#¯%V'ŸòÜYIãí½ÇÖáó N×¢bîFˆî7 î?ÎîzÏóÐÍEñN0~o�õî§F?ëH¿ïJßïLŸëƒDU„€8õ`Põd ÂŽõľõ\oì_?ñ,%èßìçóìhßñj?íNUíZsí‘>él)÷+o-�÷/ßîäNó6ø8?ø:_ø\qø>¯@_óôÞá¯þøö­ïH`‡ ¦’'>NŸùšÿozœïù Ø™Aóߢõ/ÅõLü@Oa/ÕiÈúXàúö�öô òÊödm�ð’' ¤QÐ „ �,dØÂ¡ˆ $.¡X±âŒCäÈ ÔÑ£ �_Dª Y’ËI”T®¼ÑrÊK1e YSËMœ eüà¹ÂçOA…%ZÔèQ¤I�"`Z’ÊS¨(S®TYÁêÕYµn媵Á×-aeÊTPÉYª*ó¬e‹ÇíÛ2áP÷Å]yõÂàÛ×/_0�Ó!\'N‰g`ÜX¨I©R™L†XÙB Ì™ÃnÞòÁ3ÐE·°,DÈÛ·™�¬ÆÒºæØ˜ž=רQÄöÿmË/ìæm‘¢àe¾9p Áƒ 2lø0âDß3nôø1äÈ’$#sI«¡å�—S`Û¨i“¸Nž?~UÚÞýû¢ äÏPßþöÉù™àߟ7ïðÂ;k@$’0ð@Ó"À—V;b<07 $bà­èêÒ�Ú:¬¡;B±»ï*¯°ÍPPqÅ=Ztq»í,´0º j´ÑA%4°; ßÚ,3š64N â´ áH8’Ô1‰«®Šn<W[qEÅDú",³œaË&º„ ª&­Ê,³¸Ê, <šîRó+­ÄO?&°ÊÊÂÍ"°óÎŒÈÐsJuJàÏ,³„oPB…š�>ûê{ÿS¿þüûï§ ð¬%4-R!œfI {t+à 9è®»0+èªDŠN$,E>]|F©d„Î"oŒrI%ò1, rÈ"�$!I8–,õIØ¢<‚Oª)P,·œ¡Ë&¾|ªÔ1133.4 Xó®6EZ4?9 3¬;ñÄHO2˜õPh •÷½CåKTÑÈàܯÑ…”ÁI ÔÑÒÌ4B;ÕõSßBuTªJ=µ%aC1,f]mÖXe¥±Ö ”Å5-Oñø³ 5ò„`‘TRÇc}ƒ2Jf�½Zi©µ– l³ÝöL4¿e3Üq'+÷Ü-Òµ3Ï=ù|7h˜wê¤ê]ÿ€c”@Óš~à,¬H®ÔRLWÓ”ÓÜJŽNÄ!^Ib®P]BU:X�ò¼óÞ®»è¢N8‘uÌõB·NŽ!åºVÖI'a‰56LdÇR¶æÄ¬Œ:g/­íyÌŸ»ší·£ðh‰êTšév�éO¨ã¥úu¢¬Æú¤­A‹îë-[G½ô*ûA„%T˜p<Ö�ÔRÜø†ŠÇºx fóÖ;2¾û¶èï²—pð]·èõWã©ñ—%ŒÙ¢™q¤ÜËqæ2ó/7's[Ï¿ÝÑs#�ÓÓEÝÝÕÁ+P°#`Pd7»Úàv_Óݤ–Ô»¼üîl ƒˆVÔæ›û!/yåÒŠÜèfÿ·Io{K‹õ®‡=}¥#Ó€f2^¡ÌW*’ød@¾bÁ r2‹‰†¤¦õµ/ "æªõ”ÉO[ô šý@—?Ëì¯ê»(ÖE­€œ�´8&š.�3ÞA B(oªàœ^XÄ1ƒiÙ`“–÷�·È¤0…‰žIH–©Œ)TáW´Ïpˆã€GbCa kg"ºJ‚šçÃÕ�J•{–ˆˆiI *RB)¯’­tM·¹Íý X™®ÈŠxwb—U·8!nv]ÜÒFßàŽŒØëA1� A¤qk4,ÝH<8Êñxt¬£UîØ’<ÿÆd�„ÙH7å Â;üq%�ŒË WSHCîH%‰ìÞ÷4äH�@2’$˜dˆ*išKÖå‡ßÚ$û:9Ä"†r£4P)•ÀÁ¬¨²<¬´ÍýÐf™XÊê-´¬%€sQ1Ø0—º¤/gàËÓ" U�yL4ÌljÄ-sÁ%ÄsŒX5M·ï`Ó-zܦ77Nqª„œ0'ŽTxH’½p‘3¬ K+¹ÓÞ¥ŸBÔRW_kÊØn%§-YRmA÷PgnE­n¡h-}«Ñà W^Ä…‘q·†Ü°(W8ÌEæsWÝ;¸´20-ì4kZÍíîT›=õéwá4ÙèŒp—Mçy“ªHõ2Ò³ð�§T©jÕ˜`U¿ZU-WCéUßTÀÿ.0Cm+â6*X¢ fkE×KX)‡"ÉB`Ô—Ê$(½aÙêpæ3cAYenkcÛ*Ù�µ;¨q‹…´r¿®¬+5(…è\<Š8HCD t rs¿Í†¥"a`´pê’H§`E81C¥-}?¯|%:ÊŠt¤W$Pd £ÞYwúƒÊÌ Í+HcðjX{”9 YRWº·­tÍ_ë:€»ÂhˆÃö´Šj DZÞò|ºì„/ó%̦óʬê!(`Í kó6ß çÈ9- ´sVðÌ/‚…@Ýëæs)ýL犺.„&‚¡-ƒh¥*š"Œƒ£9ÐéIßÄÒ—]ÿ¦°é(uÒŸuAF½†R§åÔ¨Ž�ªÏÌj�¸Ö¯–õ¬kmë­àZ+º~¸?Ðkt›0Â&öÂ�-d+›ÙUs¶ ¼¼0CDÌ0$3ÈT�…!l»VÝÞã·á,nª�["w]ž-µnv·ûݨ‰÷j]èCƒ.Ñ[Xt£Ëòèb£€Ò7¦³¢B„ãHá’VQÌNjk™š?¯¸Å1~�o¼ãÌù8ȳ"ò¬�ü?&Gy!UN–ó!ìÇn8 –=ó£pÙæÐÆ¹´uNmž[Ûçgê t½0F�3C»£t0�m]ÃÔÕÝn%L}°K�7èmïÊàÇ\ß·×ÿv—‹]àd7ûÐîN+œáÉ~;Äã.ñ¹SÜâu¸{Þc-iÍÚ }÷;à xÞ˜|.ñõá¿x˜7þñ��OÍo™œ[`眹vš‡P‡µÛPô„!½g�¾ÔS=a½¯q½€=ÙcÚ³ºyÃ:Ë@/žëº~ûº »±¸â;>‹H>€k»Æ{¸ˆ£Š‰Cµé«>ÆØ8ŽÃ¾-Ñ>î9ïëšH¿ñó-ó«‹aS¼àc<æs<ö3 É{?©ˆ¿ùÛŒúë¼3Ë?ñÙ?:è¿p3½q«�r€sk”Ös=Ì�?«º#¸ºzË Ü ô·>- »²+¸³Ó4äK8åóÀÿÁçÁè#A»Ã8ëKÁÈ>�Ó¿ÓŠä—·ñüš`³Á–c;ÐA™ëÁØq?ʃ?Ë“?Ì£¿ÍS€ûÃ?…Ó¿Šr³Š29œ¸�Ó«�[ ä ÔƒÒ�(›½Šp܃ˆ/Ô·%à71 »)#”‘®Ð@ÕX áÀEAŽ‚¥§È�•èÌø™@³‹º;+¹>É˨FkìÿS®€A‘Á¹ð­Ær˜D¿p;tÄ¡øÁH ÂIž«•:0Â#ÜD,k“ ¸G|l+¡ ņ�*Å&9ÅÍHEé3ÜÊ W¤XôÂëž0¤À1ÌEìÙÅéE5\‚ÿ_<‚` ¾!F0F*@F•PÆ`ƘpFà€F‘�Æš£Fk¬Fl€?l”@„³AÇmÇD\F,ˆõCGPÇhƒ�i;�Ì»6LD3$.{ÄÇ{ÔÇoáDzòGRäŠRȰ Èi0H´€„\‚…|À†³‡ü½ äHÑÅ“àE®ðEÌp��TÄŽ$F�I I“´”•ü–”�ì ‰—„IlœÉþ¨Iٸɷ ÇPÇL¿üItÊÊ#ÊË3JÎP–:ð<¥¤G¦´§|ÊŠÚÇ›h%ªÜ€t’`*@×SEw;H¯TÀW •X´€Yä½Zô=à“Ë´œÈµ¬È¶¼ÈÿŒŒKfñȺœŒdä—eä•f<³gĸhÄÖ,‰Á�˜ô¾HALÏPLŒbÌ qLEìÉsÊ „Ä¡,ÊjS–²Pµ¥Ô‰pù‚Ð ÅP ÒÔÓd›´Ê)Ö„:׌=Øüʰ¬ŒÛ,ËÝdµä¶Ü ·Œ¸, aDãܨ°K¼dΓtΔ„Ε”NÀ Ìêôµ®°�)™ÊÎnÄ\ÌœlÌ�|¹rT?ò4 ó¬LôÌ¡T �ÔöˆKÅTkÑÔ%Ë©N…ÕñUÛèŽQ­*ß0UŒ@U=PÕÜ`UW¥{ÅYE-ŨU’A\ÕÕ#àÕ+úÕÖÿ“Vþ(V}Z d5öðAf•ge´Ÿ19ij�’2»V�ÉÖoÙVÆèÖAøVt W©W~5TAÔs•F¥TvU w%¢K}‚L…Ͱz¥ƒOU·P¥Š}�€XË Øƒó�ƒ‚„²Ôr†U‡Ó\•Í@‹XŒèÕ)Ñ ŠµX.ÀØÐXp�Ž]WeÙ<¨‘ ƒ’·“­•”Å‘•… l%mnõV, T�Ôv+Ôr�‹žõÙt¥T-ZhyW£�W¤Í ]Ú¦ �§E$­ ÕŠ˜Úª�Ue‹‚]‚­íÚ Õ‚°Õ/‘»²´ DÛ ›Ø‚V†ÖÿI$V²c­Û�m¿¼mÖ‘í[8ÛÛ Ø�ç •j�–­—]˜Í™¥YG´Y”ÀÙŠˆÜŒ˜ÜŸmÔËMСŀ¢=Ú®LZz5Äm ÝÑ]§ÒÍÙÓÕ“SMUÕXÖÍZ‹x]>˜U"ÛÙmØ[%[ˆ•X_íÝŠýÝ‹ ÞŒÞâíÒd]¤°šé$ æ• ç…ÞÀu�Áí�Â=ŒÃ]œÄ�ÙÅׯ×Ç%×�5מ-_d;_¤Hߢ½á§�(s_N…ß=’ß|ÕúUŠ@]ý%€Õ]‹Ö`þÚ°=²�ÉþHà<½¨>‰¶uà·…`~¹¯ nà ޸GÄ`7Ý`Ïè` ‰Þÿ ™Þ굑ëU“ìÝÞ®Ù¾Ùv‹ñÅò­\óuôÍ\¢½axÕa H,нW§µ ƒ"ݬ ˜"Æß=âʸ ¬-$ƒeÚŒ€]Ù¥�’€bý Ûþ0ѳýF+F¶e`·…ÛFñâ�=Öµsßc¼Í`p�2194® 56Vuaœ(a��Y™�Ñ ØÇå3<~á¹`f!fÅ Ì ÍÅa* dCf PY;|-‚E¦ßF¶”G&ƒü ØýµJîßè`b…MŒ'6ÆO¾Ë.^CRŽ+–�,~?U^™øâ cX[Öi, [Ž \Ù]¦^â†nhRWI}O¡‘Tÿhcdfaeö�<g擊¦á£°axýyåá–È+ áæDöæRbä0Ýq.g«Mg%ößWÅd„ àv&`N6àÚ…¾U¦ç´å]ð]}æb¹¥[ öØ»½àzqÓ‚.€ƒvÖÖ‹†vhñ�èG•èo¡hhvÄ{y©_‹ŽA¬ŽŽ�aP i?®a@Vß’† ÁÊ-Ø[‡aiÑUä—瘶ߙŽdsFbˆ°éVÅéKŽUžöÚ…-`±=`yêÜUàµÅbTÖb¸]jŽmj»µàfh’˜êªæ·«Î‹¬fè‡Ú®—ôH°&f±¾—²‘³ö�´Vk¶–·–æ?¦æÿ@Þ\“Î »ÆëmV¸nþæª_©…dª•ä¶ ¬]g�æÚÅŽÝÛ±�lá�ì¢^à£nशL Øî|šÛÍæM¨àö°©^�[7çd:mHíF�hÖnmõxÔŠŽíD™m¨m‹¸íêÈíÝæÞ‘Žëõå\Ëî‘ÍkãniäŽÚ~eîÔ%lt†nuÖÚéÖäëvììî„£ì9åïNe¥–àV6Þ§hZmøFhù^èÓ¶ï þ‰÷Ôïý^�þîAøq ߺ†ˆŒ”‹ò7@­~ŠåWÛ¢xr=”Šip~qH…t˜Ä+Øò‡/ýŠð°�,‹©ëy¶ÿ“ó­µÛ6oóí ­`ÕµH;;¿s;_E}¸í( �¶B3œhèåS¶&§—z‰/µ„µf ue¸ŽÞ¾h¡ò �Œ!ï94òà À$÷Ú%÷‰€. 'ï€(§H*o+K,瀕Ùr+èòKî4l€0¯‘U€2ן#¥ˆ4«5os6s‡ð;¥óÕÈs5ÙóQëó0ùó—ô3t†.tŸ Z]Â}»'\rqáÂB Æh¸å!D'R”xâ"F+×pdâÑ  �Ðàä””Vi©àe�˜ V¨i“ΜvòãógŠ B•-J�`ɤJo0mºä)Ô–R�Œóâê )Z9®!ÒæÉ)ÇN!cvÚ:jµ°Eáö­„¸4æ¨k÷.Þ¼zëèëWàÀ‚dø°_¿{ÿ3nìøñâ’›P®L°æ™rŽ1VêK?±b�kZŠԪ!³ÐáõŒØNz=˜páÎ#V$}Uðà­põȤȤaÇ®œ¦LÍ6oæÄɳçOŸ"·k(Z7n¥â4u õéÔ–UIk•µ¶ °(É–=›vmÛ·nMÏ¥Ñrb}6à`‡!à *˜ d TfÙ@˜µ ™�5ô™K/�æÛiq©¶Ú‚‹½ÖAl3Ìv”A3á¦Ûn[TÄ�o/'ÜF}dPr%-§K*S NWSuÖ]÷AvÚq×�wJ€·ÐxK•wÃy襷Ví½7ÐW5íH–Yd 5ÿ„Zu°¥…~ûÉEWˆ{�q ` ao¶y'žv5ø e—e¦™…ž¥ôœh>ÅØ!j®�'^#–xbm*2äP‹/Æ8#pÃwcH#é8ßÍ ¤�CÉÀ”7$±*«K2éÝ“D™TªU.‘UVe¹GðÉ'}aŽYæ™i¢À›Œò œÒ9ˆ�ÊJÛÚž|ú9! bxDh’†¨¢‹Në¨l´qiB+Rº›¥¾a*ƒ¦6‡£§$})ª�¤Jgj‘©²Úê’M:ùä¬%ÕZ%®X^¥e¯çÆç%¨c {Ÿ™ù釬Ó¾Ùì€ÏF;-È�Uûൺm·†rØa¸ “kÿ¢¹¡«Ð¤1´èboîbïÆ!W¯I âË-tAî;Ý©þþ›„«ÇZ0IŸ—°® óڕÿÒWŸ˜›&Æ oÌq�t~2Úv�øÛTÅ…„ 1÷Xp·TXèm1 aôà�9Ö á…çUø*(¾øQ0À°]Is ÑÔGè�…™_¥_px^â }TÐHN¹•D+@ë¸þ:…P�íµÛNû©[K.9…=øŽú­-µËžV:|Éßf˜/ õ–ÑKߟbi[=Úk·ývÜI^÷Cw�÷Þh¾å÷E€!¸ÈˆŽâ‹3N�ã�“túC•_žÿ¹›¿ÕùçJ$:.�N)øÛBT|Ä:"¼vš‘Ýí"˜‡ÜÑW½û]þR7¼]IáxÈS^‹˜gçzÒ‹õú‚½²OÚ{‚ÛŽÒ= |/%vÃ[K.Ç7ô�@}ìcŒûÞw—øÉO�{\ŽL77àoš{ç€ã9 €n€Lʨº6Ðu±ƒšoGA²XP3¾ëð¤²A«uЃ:H^–'B¦À„'LaZ¨Ç=²æ…1,™÷èfÃðáÐråÓ}˜Á±A‡+\�H?$Ö+‹ tbÿ ø?)06V$Jé,¼-¶®‹_,Xm7ÆmáJ*gL£ðrF¼6zÿŽrdí8½¹T��¾üå]üȽ?ÑP�S¸áørxÈó¡O‘`d# ‚iR“ˆò;¢ý”8¹ Z “þs ©(À&䊑["7 ÅES>Œ©¤ÝÖ¶ÖÊô¼2�±¤HŒÚãÆ7&O|â!ré–¢�—*&B})L³†Ç$d2 ‰…63p‹l_4©YMH›IeõÆ¿o¢ œU$çè@i@t"0u¡YgO9«wÂ3ždœ§+1ØÒQ®1+Ås#ýy·1�I ( ¨ð˜Ð¥êq¡¡�C‘y9©Pô¦! 4Ä®htšÖœß@ê÷Q–êO¤OŒ¢ ¦xÒrª‹dÿuéK˜ƒ¹ÒU¦Q¢ilzSœáŒgÄÕ‹Œ¥O öS¨DEK`Ó$=õ��©ŽÍÞkØ÷AÕ˜RÕUÍçŒ\u0Y•ÌV9ÒU4’­ä[»iÖL¢U­ãd«B™Zu²Ž®um'*og+½²rž~õÕªRÁþ´–…õça‡ ”ç)6zŒEÐc£2§¤²BßÄ7Õ–Tµ³‚ùìB»†Ñ–¶£“Ì&H•‰¹³n2­� J ØÖsns§´%‚mçj×ñDp·¼�_[òÛW¸Ä¥åC Ôt¹%l®ž›éRXZÔå‚u±«]ÌrW³}»ˆw™Â‰—¼"„#ÿOK_&ªw¤š''ÅéÉøšó~³U`mó �󂺭ÒÖ’à¾þ¶ÀÃMÓ`�«`¡6ØÁÆZ,à[á)+èÂdvï¶Ý#t7.X…_áøÔ„w (NžŠm\ß²®—µíuíŒa+Û5Ãuu9¶-�y–=óykþ%‹�<`#�áÀû *“Eèà:BX½¤2¤ÿceÍD¢[î²¾<Ä0ó‰Ì5ó™Ó¬MKÔÅ­}ï'c»R:�ò¥w¦kžwÌçY‹,K ù:è+ ÷ÈúIr‚Üäå>Ù¹Q†n¤“í `@q$s˜xvL–P{"Ra*�pûoш˜ÿ-n ¼� T87ºc P‡ , IRpr’ÝP;F嬇RÂ}—HBê"v7·æ4Ç?¸°E¸à$‰�8®’›\‚S¼âÍYô»ÞÕŸþŒöà�‘±Õín+»ä­a¶³!$3DÓ®¶D®ýàlÇeäßwÆÍìr£;ݱfwXd*ïÐæÁ6¾µ‚}³ ßþnÀ.„Š{Üà gÞ“TuD\âDµ8Ø/îàŒcjãɲËÖA¶�œÛ&û²›­‚g¯¼å/·wÌ[‚to»Û7·ÎÉý¶žŸ[Ý@?‰Ð0oˆÔûÞ|W:Ó�îï¨ œêU¿z˜²ž�ÿ­wÝëh {Ø1Nöà˜=cwI»oBÎö¶Ã½õ{AùÜUo¥H{,�Ïûö®m›ç(w¹Oeø'/è¸ÀЋŽ÷£Ï<骉|lžõ.JÝòǼY4ÿΧÇóc=ØE?zH9\j¿X‡\¯~ÆÀžî³OJíSr{ÈœÑ4ï;·ÿ>¢r ìT· ßLÄ›âãÝDèži<¿EßÓÜÍXÂ%Ö ÃqßTx€n ½ øM€øa”Ÿ¢ÄHœ JÙú­`ûÉžA”ÄÄ`üMÁüÕ3ížßõÎñ_“ø__»!Þñ%ß._6ßã1`Ó9àäuÿQRÜÖahŸO` Tl ¢�‚_Ç"›]˜Ÿo ` ‚á ža ÐûÅàÌ` êâ`þõň̆ÆLJy‡îÆÄ A á–>Äü¡ý9Ÿ¾5à H¶ÈÐ\Îú@-˜ T¢%n]½Õj`bŠú¨OÛý@ÊÀN^„ a�á ªàº^Æ×Ê ËÙžÑÙàfñï@Þ!Ê—É-�É6@â-!" D(`¾-�"2¢:b�HÔÁ=ÜÃM¢PYâ%V]&RÛ&z@'ÎÈ'N(†¢*&@)>Z] â`”#+¶"ܽ"|Ø-.Ÿ-Þ_.îÿâòà/VG0¢Å0££&c.`".á">à3îÆ#êÍ4R#X£?ac%bâ6vã7G8~Á8¶]9žãAÝ…: ;š¡;º¢Ü¹ß ÒÞ,Ê_-Âá!âbêâkðb/ö0þ`×øañbB 1nA!dLjä)¢x©Û:‡z=$5J¤øP¤ Xd&b¤zb8väÈ}ä`�à‡¤¢*¶ãI–]ö$1ÚeP%(ãQ"d_æÙ_6¥ÁA$fa*ÀajãE*æU‚cV:æ@f`HfjPfšâe¶Þ<'W ›q…à\ç€mÝ¢‘wv§˜¸ŠÔmM½•Ir-P¤§uIÎ6FÀO„Ä'ý�E @ƒ,è`Ö‘lÝ‹$úe`(‚€è¢ÅR! ¢d€‚.¨¦5§ƒ"Ôs>@tžÛt…xX'vþ–v:Xwz'Ÿ€§x yR›yzª'¥ \{¾çKÄ'ÌgúÔç}*N~bÁìgÕõ”ê¨ (�:˜�‚¦ßƒé”Eè„RA…*ÿÁ….ÄuâAvVÝvv( |'á…èîŒh”(Q�h¬çܬ¨OÀ§|¨3ͨ Ôè�^ÊVìh`ø¨€¨oè�š†‘æ©t!)GH§GE“À“F©ÇMi‡ZiÏa©CÍ#—މ—‚©ˆ©�鋚©ŒJ~–ˆ~²iŽº)I© �æÅ³é !Šeê)ª²Ÿ®�Ÿ2 *†B©†J©ƒ-MˆÙ�T€¢£ªÅy²Nz~iŠîޤR*ŒöÐ¥&�jª�IÅéèÚ…*^< Ǽɩ¦*¶¦Íª¶ê«&E¬êÁ-š­âê�ìêuÑGyúª‰+ŠÎ„Ôk‹–é|ž)¦.ÿkll*O<«§¾\xÙEݵ6‹µšd¶ìõlë¹ L â¸\¬Øª«äª«ÜÌÖ” ±œ [,ÐQH7¶gʈÁ±:S` Žš:+ÅáfŒldƒÖEÀÊÉÀ2§ÁƬõ ,(,¬>IÃÀÃ.MÄÉ“>éͼˆÅâÆj,ë XÇnãdžl}Žlá”ìuTÊú†ÊzÖ´ÒIµ¾lHÊ,ׂ ÍÚ¬·âì¬zÜÎþKÏNÇÏ^gÐVÄÐVLÑ-Òn¢ÇjˆO0íú É2ëšæëÉBdʆãÊ@ËÆ‰Önm×nž|m“,,”(…«”-ÀpG®¦-¬-E´-Æf,ÜþVÒfâÒZÿêÝ FÞÞk³FmßRãß~bà.�n!.ìâ‰âzãÊŠã. ä®ÊÙÚåZîD`næ-Ä-^Îå|î¼6-`Œî àëNH­ßR-àZ-Àb­ÀnìfoˆÌn·–ÄÓÜ.wä.Ó,É䦭ïJð¾­Æï¯Þ o")¯}>­Þš,ÁM-iTíw]­�d­Öj/CšŽ…D�ìÈN¬Ìš­Ü ®ì¦äS{h…É”ûbAŒÄï'‚×F¾‹�žFà°#ÔwUßÎCMóÙ·®d®@pOð‘T¯) VðеâEc Rí𱕰F�°í¤pÁ¬ÿðžµðn¼pæÊp{ÐðuØð g0ú±]ôðŒü0Á ±ûS“×ÏŠ‡…­äZfa,KðnR0÷ZŒLÑaq]hqp¸îï1 ׫ °fp�ÇŸD–³±o„‹óD ×Ó1Ø1¸®ó1&ïQOÓÓÎ ò“(p•¨q‡)2i0ò×°ÝpÕ`…$Or3†%co&×ò !N9òÿ,Ø'×®(Ÿ)sÙ/²¢¼ ¯rûÆ+Sò,ÿ¯-?sÚà²*êræðr/‡-xÌš‹ºhrQ0 ÇH¸¼ ¢<2_Å2Çòb4óËB3;ƒŒ4“!5Ë�5_ÿ3Irls|vó‘|31ˆ8w9·²9K23«³µ¶3B3Ê;£`ó�>_?Ÿr1¢Ä+G2´A£sB�4xå25;tÚFЩÌZ7J4>W4OÀp¸„³FwGßp(ž3ÌHH‹4Iÿ´^,ô 6´PQ®J Ko¢Ko3Lï„LÏ´?×ôiÜt¯å4Aût^ô4V5W3†jX‡5‡Y—u P0¿È{sæ²ò‚2(õÚÅ›¼2¢”%w5^WØW‡5X�uY“5¶`£õ‘¨µû²5ƺõ[g@7Æ›ØõVçµdëujðu_É_¶`6a_ö‡a/bŸ‰b¿ucËr€@öNO¶j'Û^óµ_ÿõfsvZOļHgÇtæ¢6:*È]¯¶oSXk‹5fgvlÓZSÄmw6 ë¶áòvdÿ6twe[ök—uqw3r'7Z/·Ùõö]xwt‡wB=‹iðD{^÷aÕ6mkwh³s¿n›€·xÏ7‘w\˜÷6¢7Q©·D°7oä{ã‰|Ó7�¯�}K~gbqû7ƒ€w÷s»I„8…·Ð�'x½-xƒ£5¢<øÆ ø€W¸ˆKË…ïÄyÇö†sx‡x8ív‚„øˆÇø�”øœøf§8wx8ø�À¸Œ«v@!ù4, ²ÿ[¤A° Áƒ*\Ȱ¡Ã‡#ØB¢Å‹3jÜȱ£Ç� Cb¬(²¤É“I¢\ɲ¥Ë—0c6T)³¦Lš6sêÜɳgHœ>ƒr*´¨Ñ£HWMÊ4áÒ¦P£J…útjÒªV³jÝê+WŸ^¿ŠK6"ŲBÏ¢]˶­Û·pãÊ�K·®Ý»x1ØË7€ß¿€ÿåK¸°áÈ+^̸±ãÇ�#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ(à€hà�&¨à‚ 6èàƒF(á„Vhá…f¨á†vèᇠ†(âˆ$–hâ‰(¦¨âŠ,¶èâ‹0Æ(ãŒ4Öhã�8æ¨ãŽ<öèã�@)ä�Diä‘H&©ä’LN(À“PFù¤`Tie“MJ©¥TZY%–Ln)e—^‚¹¤˜Q’y¥™I¢ ¥š_²‰¤›SæeœrI'—vÞ™ç‘{"è w"ð§žtJ¨Ÿ‡©e �Fª¨ GTjé˜fºÀ¦œ6Ê¢–„*ê ¤–©¤“Zzi¦˜rÚ©§*‚ÿ*j¨¥šzj “¢j¥¬¶êê°’˜À°ÄÊ`ì±<$«lÌ6kijÐ6 í´!Tk­Øf«Â¶¯"±Åk¬²Ë6Ëìè¦;-µÖV›­¶Ünê­ˆà+î¸äò`î¹é¢»®´íºû®ÛªÐí¼Ö›À½2ä˃ GÜ/ºJTlqÀ! Lp¼À"ü¡Â ß òÈK<±Å¬qÁ{¼!È÷ŽLrÉ&L<Êc¼2Ç.'\oÈ2ß@sÍ'ãüÆÑÖŠ¡ôÒÌÂÓ=k³¸A M³Í8+qôI/­tÓÛ>ÍBÔN}lÕCcm4ÒÕzý5Øb“�á t× ´Ìi�òÖ]{ÿ ¶ qË !„^wÝ $®8ÚWëm1ßm»ýwà‚;X¸á‡Ÿ øâAçÝoÖ�‡à¶“C]¹ƒ+¤®: ¬·ŽÇë&÷kÁì´gMEÐB Åî¼Çá{Áßrc‚iYü˜}–y:uª¯Þ:ë¯ã{º´×Žóíåþ,ï½ÿ¾mð ÏØñif|òk./]ó©?=ìÛ\ýì¶c¯½Üïî{À /odä{“ù�˜B©o:ì[�ûP½é¡k~¨ßí"@Á æ ûë_øþ™Ö 0ç+ £�.°�ñ›³vÁ Z0üžÿ:ÖÁ–„ü‹IXBö�~D“ÝüÿX˜?Rð‚1TøÄ·ò ‡7Ôáy¨b™Ð}žK×Ö¶FDî1üÛ¯hh˜…8ñŒèÓC¬Ì�pŒãÐ\@Ç:nñhÈ£[hDøñ�büUbCH¿h)WÜÕv¸F6Ë�q”#ÍêhÇ;êq�EìãýHW ²�NDdþÉÈF§�™‹$çHIÜñ —Ì#]¸IN‚mŒŸ$ä¬BåFQrO‘C¦0MéÈ@R•¬¤ä+c9�YV°– è$Ê]f —“J䮄)Lxó›b£1sƒÊéɬä™éL BSš4L5w‰MEiSUÜ æ7Áÿα�Ó6ø�@�Õ…‚v!1¸Í4 emZÌ$ƒD'j€ŠZtûë' :ÀÑŽf ©@Gú†Má¤(µ�JWú¯\à¥0mifJÓ}zždü'k:Pcô  ]hCÕ ÑXN”¢­(F}§QÆ„T¤$-é½PŠÒXõª6³™Li:S›ê§:} O¥*ƒŸ"T¡%c¨CßPÔKU¢IUêR›º˜§‚4ªd=UOzU¬fµ_[åªWÁÖÖŒ• =«P×ÚV=¾• q5ÀRã@WÅØux5é^ûjÕ¿ ±zH­h1FØÂ®æ°>MlPÓ:T:n­±y|¬FKé˜Ëÿ.�aCã씹y ƒz½ú\åA&¤ˆï…@ßúV·¯×µ»Ýàvדß%îH[PŲ–±è�€zÃÀÞ~Ò¶1ð•¯ûêk_šé6¿ûÕ.w›†Ë£&¼Ç]ìr Ç78œv*Hãë€ùRX÷õ+o3üÛ ³Ì»6 ˆ <^ˆ)×µç%qz×kÓö¦ï1nñ„_ãÎ^—ÆÀmW>‡ð·ŸfÇ@E®�ËûÚ›¸È†îa“dS¸É»}rvk°)WÙÿÊ¥Á²�É‹`!+˜Èû4²CæKøy/†±…­«fÐj¸Íù|3~“À˦x@—#ÜO Ç«2ôÒ€�¦‹Àé•®´ õ‚Œ±Éj¯ntØÐ’ÀêVg­°Žu cëVº@´¡Vd¯v Îü0š}Ž3�"M�Iw¡ÒVÅ4C5 NÁÓ* µ¨G†RϵŸ¨ÎœªiÖjWãŒÖ°ž5¸m�kPëºW½^t`m×G ˆØÆFö”�éMwÚÒ5µ«0Sc;ª©Îת»�„Wƒ[Ü´&whs½«]§û>¿n^°Ý{ xOZÞôf¶³¡mƒ|÷aßÖÆè©ž¹Í%nàÝÿΚÇ^ëV–»çfÕÃíqÕMüȲøO1®l�ßÛÓ9ÆæÕlÎä @¹·Q¶òƒ» GÃUåpÓí§æ©»ùž ¤sƒÊ»Ž—öù³ñ�o¡ÝZE'ùÑM®tV«<ßKˆ»ÜŸõ©¯JæV×ÖWàñw‚íê~1ŒÎݺ@Ó—vöÆÉ.mÒîì!H;I݈ô¶'c—ûÜa]÷|ß=SýþØ÷Z*ZÝ0 ÃT[xΉWüØ==4ÇÏò^5s}‘Îlfüò˼æ—ÐrJ¾|껽FoÄÒoòô|aVÏãÖ÷•Þ²ŸýJko{ÜÛT÷ôå}ÿïað{Ìçá�—öç1¥üûdö^¤Ï·ß›øh‰ú@µ¾¥•�ý¡qßñÞ·Oà'â×{÷c~Ò†~.·pžÇ+½Ò~öñ~âÒ67`óñ÷w/¬§[Ø'{þG3¶gøMX€Ìv€Áw~NÇy (u xÉÇQú!�ÇB�¡f�3Mì¡�R‚„ç�ü‚!1#X‚Þt‚&7~0 ‚íÒtV|ut|ææ€¬�ã! sYxµ@„G`HoSdX†ÓQX(NBƒQ…R(Ö´@÷U“_6ótôfk÷YExq42±Öj¯'vtR�uTç¤[Yƒ1£s†hÿØâ¡…õÂ…Qå…† †S†f80�‰Ç±†9$}„ñ†w‡î3‡uh‡ý‚‡Ê¦‡ÚÇå‡pˆ°&ˆãçl…8‡8Q‰ÈY‹0�è‰�‰�±…vÕ…îó…a¨lcȉ%àˆhˆ¢E¤È¦è%¨ø<ª4¬ØŠà–‡­´‡qÕ‡õ‡"ˆ¬6ˆöV»Ø‹õ‹}Œí2Œïò‰ÆÈøTÊø<̘‰Ê–5Ð�Ä8�¡hCh"†‘�V²�­Ó�2ó�é⊘‹¹óEæèxê˜ìØlœöŽðè$Y’Š˜58c�Ù‚�á!‰àB‰$e‰1€‰ô&�Ð(�iÿÕ(@€±� ‰É:&‘YE‘—f‘Ђ‘³x޵˜Ž·¸Ž¹’dˆ#Y’$y’(i1*‰-, .I,09R2I“‰3‰“4x�P”��á“ ”(0”D91Fùcut?JI´¶X¸Ø{º8•¼X•V‰•Y©[)]ù_9,Ì„1™’IxAŒ8sie¸oUçOÃáDÌtÔö“@¹K­Sr9—ޝ8ŽÚ“—{Ù—µ•î(˜ðHVI’”‰Pjƒ20µ4 /OÛ!,Æb�0’9™¹i˜ƒ™d¨™è–w:µB*ŸYvûš§Hš¬cš„†š©IkâÿHIÌäšLÉ—N™p²)’5e·é¹»i1½©4¿‰-�Ę�Qœñuœí’œ‘ŸÌ©ÎYЉwœ©†ÔY�×)mÙ©�ÚÈ�(à�øžákãYGåiD¹‘t·ž´9Qîy›ñ9ŸSŸbpŸœ9¥ÄÉŸþi-új™(S š)3×gУ>Z�/РÓö ê5eÌTš/ušàikwФNYêBÚ”9n TÙžùôž%ê8'úR¾©^Ày�Ó!x%hš¦üé1Z-3Z£óx™ •™Ô¶™¿‘@>ú£ K I¤a`¤±„¤ ¤E nYäNÚ¤PKæÿ©‘Tú¡€)•X:˜ZÊM\š›&ª(ª¢ù)fUiª¦0K�  pzUYƒ£u� ºxš§g¤Bªo~ú§ùt¤Ý™¤ßéYOw¨­”¨ŠWQZASŠžUªž‘:›“zT#j•]ú98³©bŠŸÿuZ‚Wk:¬ÔRôviÓÂq” G‚Fg`ÇPÐ"™�®:�ØZBln4‡-¥[„tçÔПHAºÅc—¯”®Ë3úXûYsÈs”ô{_dQÙN_ð†[P±ÓÒWëHG­öR.dQß4 +6<Ø×UÙʨFĭݪßš¯´8®[FI—v®‘)°ëÿŠwíÊïiñ:|YôWt¯.K™û:?ýú¯\vG_T°ou°q•°p´ Kp [Q+6;±»{Uë{[Q²O3²¼Q²$u²—ôE*Û­-ëiá 0kv9³Ï‚®êÊ®hK;{9=«y?›UA«Jø*·¹Y´Õs´ý°JkDL{TN›TP R[G kD‹-+±JÆ:[ÛµVõµa;¶P¶3 ²Â)j;Rl«Gnû/+˲Ò®/+bt„·F ·p³:Ê9»‹9‡3‡ƒ+?C„3‡»RújrüÊYþÚ¸I»EK  Km;| ‹¹T«¹V˹Xÿë¹ÏºÒ‚±©±¬Æ±ä±Þ²©{¶«­+P¯›Gƒ;»q˼·{`åª4û6Ë·ñ›ÃK8nT„D¸É‹2Ë«RÍ»9ÏÛWÑ›.ŽK½�k½M‹½O«½Q›l啹¦{µO“µŸK±[¾^{¾`›¾b»¾dÛ¾f ¼üóûõ;÷»²ùëÀûK®¹k®y[³{‹³};LŒÀAäY+¤¼CKxŠK;ŒKÁÓ»5Õ›œ×;jÙ«yÛ‹¾ÝVµ Â,@Âã{ `¾Ü›êKAì«-ꪣ%[»µŒƒÀ6vˆÇPÓR’úË”u{·@¼»BÜ»Ç:fHRÿRÇ[yJŒa l1 l¬8|UŒ.l-W,™Y¼`‘ePr'„S›ÍâÂa<0�«µfŒÆ^¼ÆÐÆo,�¡:nÄÈ[pÇE˜Ç˶ǴÛ~ÌÀŒ». »¼ë»˜¿3LÁ0¸ìÈx\hÖÃÀІ1YpÍØ As˜É°ÉÕÒÉ‘ùXA0Î伦¢w¤œÆ§ÌÆßû.«\Âä{Æ)œÆ°,Ë1|¶œ9¸¬Ë!ÈËõ{|,-ÁLÉ=³ýû¿LÄË<Í|/ÏÌv�,ÍôãÄžfÍØ|ÍÚ<|ÜìÍ!Î Îä<Îæ\P£ÌYvÙjëËí,ÆdÜ:ñìÊ+¬Æ-ÌΧÿ ÃïÛªµœ:·ÌÈüìþÌlÞ*Ð$ùÇŽÈåeÌ…ŒÌ¼&à - -.½9J¼Ä@É3É}Ñ|°Õ\½ÍH»VœlDSFd]Ö!-ÒüyÎK�Î^œÒ›ëÎáËÊ\‹Â£«Â¥‹Ê¨»£r¬ÓúÌÓ�ÑÒûÏA ÌC-ÌEMÌH ÀCü»®²wZ²O},Q­8S ÉÕ“5X0}Í\ÝÕýÕêÖ.4ÖeMÖg#Ý%}}Ìjn½Òà;ÂâëÒ­<ϯ<Ó*]Ón|ÏÆ‘χ³ÏÍ� ÔMØ@ÔâŠØƒ|̇ìØRÙ~áÌŒ Í»,ÑDÑ+•ÕØÜÙ[íÕÒÿ Öß,ÖùTÚ¦}Ö©½Ú—ÛÖÌ‚ÊóÎe<×ò\×ôŒÛö|Ó¾!Ödl0•Àwn<;Q'ÚDxõ•.‚X®ûR^EÞ$°¦¹2:ФQc4F¶å>[{UO÷{Q'ZÔ 1QG—à þE+UàS1SZ ^ßéR¢ò<É"wû 1£Ng)yý4ªó⬣,0S¶f1Îæq3ˆ†ˆ,V�‘ß“6ãT]¨´ößàáíBN_þµÅ¬ ¾àäíà“á»"áî*þÞnÞJŸéDG¢âÐ&âûBâ*eâ7ƒân®âûÂâ´ìâ¡ã< ã/15dopã•ÿ’ã,°ãÞãÉòã/ä3äùVäuä®�ß»¤ßƒžB¼õtP.åmDU.W®ÂY¾å6Åà^®(`®*b>æ›Ræ´½gNkiNIkž›m~k¡çž&çæBç6`ç…îëH°â/¼Ûö]~ž€.èÈuì[ƒèG èŒíŽÎ�~’®”.m–ÎQ˜nXI¾éKÞéMÞßO^„þ‚NA¥~ê2«åûÂå¥Ýêƒòê–ë²Në [±·Þ‘®ëÃæ“ô‚À¾RžÒTâV~âJ�âɾçË>Ë8ýìÑwLNíGcíØž:<Ž>é»î¡6îPî;uî³ÂéÈ•_ ÿîîQïS>àeçŸê _¬ÎŸî6Šäq^EáÒeáoUNp¶¶ë”ÙëoG!ÞóÄnìxŽìÊ®ÛÿQ 5ò$è¯îè1ò+0ò%ÿã'ÏiÖn)îë¾,Z./*0Ïßtéß4ß/yÞ_!»òžó?;ÏPÕ#ç?_œAï5CŸoEÿ+o¶®ôhÎôj~ð¹I“pȾð*ÕóPõ�ì¢UøÀçý´ß:1öÓ~õ[S=Uxí6-6Ù®úÉ‚Ëk_m_)o²q^s*Æv¼wßî!8;z�ìÖâ÷0ïè2ø@ú ~NkJ¯#8;DoSp?ëGÿÿ<ºµôÝÖô–?·«dšõ°R–âù oêck¤oúá„ú]ßèŽ.í½û0—è³,X¬ ˜Á „<naØpÀCˆJ$NÄQ±ÏÅ#5ÎàØq�!EŽ$YÒäI”T®DØÅ ˜1M̤ ¢œ9+ìäÃçOš&,X°é¤!”N`ÁéO!Q!&¡jÔ¨ C‡àÚ•+°aŒ%{ÀìY­iÕ^dÛGÇ[¸,�Q×®K„gÏòäùÆï_§�#(%âçϰfò5ŠIX‘5z¥ÜU°ÓÈ6¢ ±ùЪմ\ ŒŽËQài� ­6˜Á¥Â%±/Ì:ó³ÿÑ´3–žqšàŠÖ-òhè°óDŠuk<ÒÑ#JèÑ¥Ÿ\ÉoL™µ;È©“o…Ã>ƒ½}4©ÒË J}H5Ég¬•+'K¶¬Þjõ[h{.ï¹è²«.¼PÀï€ï*ø °Ë S*¼j3¡<Ç “,#ù(K/³Í¶+¯²Ñ àí4’V$8áxˆm‰Ù.�°¼þúÐhD�~C…áZlq;ä$ª¶˜ËÈ9Ž>šîH$OjíÆ–°ƒéÅÛºÃI *«„p< ( È,“>4PsM­btS8¬kNüê´O¯¬MËÇþ¼ðˆA 5´Ðá†ã�½¢n‘´M{Km$™„M6Ú¶½-ÓÝÚõÍS× UTR‘3u¹�ˆ\µU„¥{µ_—œ¼aVj½•JmgÚµÏ-�!ØaÅ,ÖØÌLvYfùkÓÍh¥¥V/kͰŠiâÖB 7ŽqÉ-—‡s¿L÷³uEÔ÷]‘â…u^ë Æþ4…–Ó�øM‘Q/ÿ89 Òà„»&I°Ãþbl²»0û옘…am¶ïpûíô*‹±<8ê¶Û¼ó> ,¥MÀŠX |Å7¼�í$ÜN«‰¬r,Æ›ã(crÊ‹cH¿–Œ Î;‡Ðp´.ž¨Ò!èœó!RßauZïàu b·ëìÂÐ + ¬š¨ÅÓ9tõÕO �$ÙïB¨¡úÈ‚w«xÊ3ÄÅ�~zË·Ø,XˆìQ Ò‹èÊÑ·Z_¯[l²Ç>m˜Ôf{í·á¾Lîþè¶»î¼õF ‚¾ÿö8ðÁn ‡\â´ÓÆIÄqH�ÜÍ(W9Ëaî6vzCzzG†Ï .tY2ÊèJ×ÿ»Ô xâ{]bG�Ù™­v·óŸ v7› þx› ñPh< ïLÊ{óŒâ<Ao4Ó£žå®‡®ì}g{Ýû»t0¾Ö•aç[úÔ·¾.¤mMïƒ_üî7ÊÌí6÷Ã_þ<°7þ¹ˆ&-tî 'ÀЀAYÜP×ö'rœ\õ$ø Z°w´�Y´¢;‰tÏt§ á]»âÉ€v±ÑàY|èB‰ð®w2 ž@†7’HÊ %:´ÏòZÄÂÑD”^õŽè³$òe‰¤k¢ÐžE)¶ŠŠ°â°˜Åöm‘‹é£Wbd&óËd¦ϸ¿þåîo`‚æXÿÚQ�xDBÃÅÇ2øQ-™»Óe.HÈ "’{d¤êX÷HFr’qd¡41©MžŽ“; áÁ@ÊQ2$yc1¥=QIU²R âLËv´×#&ŠÆ‰P$_.“´Ë�ñà•ZäàgŒðQ�s~aìO2•ÉÌeV�ÑœáfÍÎ(.›¸£yº©Ç›Á1Y´ŠH77Èð€Î�¢K$;;×Èwª „'LaVhɾð1ŒðøéÉ‚ò†:ž@wHОr'Ï¢B%¤‡*¢´”¨-)jÑ‹R1£ fG­Ò�úÔ)•á@_ýjRd¢4¥”Y©gÂF7 î¥ß¹æLêHÓmÚÔÿ›ƒÒ)šxj½:åœA­d~ˆºÎ",ò¨îÜ !¹Õyvö—”jçüºÏ~†$³hW·0P´yc bYYyVµ¤U–kõ^[áòV¸)l­™ë/ë¼~4³à«_û Ø0ö*…¦aýfÏ6bÅ¥N‚©Mdj“?:ÆplÁneísÈò`6³¬žP=ÛQ†„¤5m;·åUgµÕ_èm¿šÛ ËºÌø93ÿ–ÒRµ\ïúÃB qœ;ðë“{g¯$v^ƒldçÌÇdöŸ�-ã4B»¥7ÆN‚ʃñcc»Ç6Ýv·Wôm«„{Ü䂹ç€îtvpÝœ&RßípPK’ʪ%0> ¬ÏT_5ßþ€«# ëX œÖö±õP¾æ�P0¢ ‡^ÃKq“H¼\_ù]õ|”×Aã7i³½RX‘O“ä11ùmÒ®ò´, -‡´�-{1™_†æ577·Šß�?Ù‘@�÷S\j£ŸéV�­VÔo1\à˜:Yªn�«#(ëvÚ:ˆÃ'b°WG%à„zg(B9Ä>h!ÚCímÿÜç~bR¸ *Áÿ{9ìh;jÖK‚p‡;?$_ù»OÖcßæö®Ø÷±ÉB p}(xE) B÷ðýïS =çÀPì¢ÊÉàÿù |ÃIˆ/TñK ì_‚Ìd&D‚àÿ‘~|à{% !¿á€Ñ4H@T¨dQ@Ä>ìÃ.þ ¦û5Õ Ö«á{½Ô¾Ù Û³½ ܽޢߋ=á+À4¾ãÓåS¾Êh¾™z>�ó é›)ê³>ìÓ¾à>ïc?ñ» ò3¿ºA?ÊP¿#c¿ïs¿ €?Á‘?ž ¿7¸?üË?Ø¿þ›Žÿ@9À¤#|ˆT L@…Ê“2D¼> ÿ ;‘¸À ¸ ´Ø“½F¢¬½œ˜„ž ¾Q ÃácÁã{Áä‹A4q>·�>®¸A³€„@ôÁ P Œ!´€ó�ôSŠõSB&t€Â��B*´Â+ þÿ#.ìÂ#úB0 Ã1L‹4¿¨>J4ÇDÇ¿L ŒMìDHÈPd¿QŒ½ø«�ùK‚úÛG+ìÇW\�XÔ®�t¬‚üŽƒ\Ä$Œ…¬ lÈÔS½9TÁ‰ÄÊ¢‹ÄÈêÐÈÙâÈŽTJÄ�Œº� Él¬Á®8ɇР•,lI|I¼¾J¤Iu´Iv¬EwÔIž¤GŸ´G |B¡ŒB¢œB£Ì?¤üG´@¦lJj4H”CHyTH¸ä †Ô7‡T‰ß œiÌË7¸C”É‘t K±T ²L³ìHà+Í�ì ½ÄFm DÉ´à\IÿÊǹ räK™´DL$›ÀJ‚,Îp+Ì9°½öCL9pNšÊ¢´?~dEþ³½#YJÁÊ,D¨ÌL©ÜLªìÌH&$»JÐÌÊÍɱMßü Ô¤H„�ÖTÂ×\‰ØœM�´Ï§T�ܼÆÝ¨E àá¼KsÉ7€ÉräŠs<‚þ´Iæt çä±èÜL$£Î%´Nì\ ÆÜÎ*„LïðœñD)òlǼ¨ŒIäÌo¤ ÷<2ø¬À9[ ú,uGIô‹üôÊý4€ ¿ÿ„M²P€üȵ¬F�P’LЯZP hÐ�>¼ŒÄã̾äôË囿TÌçL2’NÿE€Ÿ¼N4ÍÎuLî<ÊmQéxQfŠQÁœQš«Ñ UÍõÌQ¯ØÑ9èÑ`FÑ$ÒTK =R9PMÖ¬I&mÒU½³œÌ!UAÜ´RÝdOÞ¤CßÔ .µK/�PÓ¤Pä´Ð™ÄPJE ØÐèP”üÐ ÑÚ«N°y¿Ä,ÅÅ<ÅÆLE;5€VÄÓèÈTíÊ“mдCD? Qô´QAUŠª ƒ÷tC¬„8 eÔútTÓ„TIåÏWmFK}RL=ËÚœ ¹4Ï*uK,-Fý(ÕíÎ/½O½”Ö ]RX•UZ…N2¢BûCÂéÌÕÝÕ&ìÕCËÇ`½¿^ìGc…dOYVàlVÿD„VŒÓÌÔ.õLdºV` Æm]�FÉáG#í@. W%×& €K­ŽLM× XWáÊÁO%ÔcÉÒ™"Õà4ÕG¬×â,R+Å×VÕ×X5SESýW€Ø6}Óñ*¹9¥Â†½ÓÚKÊßHÖ‰¥X‹}AŒE6��Ö¨V�ÍÖ%›+XÛÙ÷x…Ê Â@6}E€[‰Ö½ÝŒ1Å·õ¢©ÌˆÝHš Ã}›‡aÄ;¸ ÇÝÃL­¾Å�íHÃÊH¦V¤ÀøD 'mÌÕ]]ÖUÝʸ …Ú½ÝS(!9‚VlÅD%‰P[¶õÜÎøÛÿ;ˆÛȘÛc«Û»U‰¼ÝÛ¨èÛ_Þ· Ü#ÜY¬ Ã%€Æ- Åõ<Æu›<ÉÜ”ܱ¡\'±\ÌíÈÝ\*é\½øÜ2 ]d]Ò=’Óå£Ôm]û}ÝÞ‰]Ù½Ú’Ü…ŽÝ›µ½‚¶ý]ª€[V’[¥ Ûq=ÞHÞPß³ðÛ\õ܉!Ü™¨Þë%Œì Sì`¥ðÞ6¿É½¾Ê�A·)ßÓ9ß³äÜåõ]›]}ß-Ý“˜ßª_ûe]ü=ýÝ_*é_æøß”à]–ᩨààMàá]àâmàäÂ[ƒÐÛŽa½ à$ð¢;€^é½ á`îu�f€ã aÿ‚e¿†‚îÆfaÎqᎄa!(ànßø ÙèÐaÊááv]Ê€]V"ÝØ%…bF#¦$Æã%Þb·^ Þ:0Þ)FÞ*VÞ;Æ-æb/Îàé 1¾ƒÄ¥Œ‚“Ó áPãÈUÂ6~cß|9žcÍ}áôÅâ³`_t_>¾a- @žAäî…Bä]º@Fnä’à/`HInb"Rà`à¿?†` 6 -®ƒ¾zÞ Ž^Qcê=\4ö`T®µí5eÇ5ß=ß/_ì ßZ¦ãß°ãi.TÆV?†Ža.ƒbîácæœd&ÝeV½fvæ‘€fiVbÿjFàk~âlŽâmþ>^ +¶bæ ÆL86rÞØŒ •^i 6�ê­ÞSöŠT6Q¾è^yþ^X¶"YZ­¨e2Ðg‚ؽ~vôådZi´`Õ;èû-äü=d†¦"fVBˆÖÝG¦haabJ¶dL†« üh½ iUv�’®ƒ“Ô”^i•f ¶ž€0~i  ù |½¹ Ú¥g²Ùi"EÙ»î"lÁFß[jª(ê=>j•Nê”P½]ªŒAöa§>�tLGe–j‡¦êªŽÃ«^_®æ­†âK–b¯V=°±¦içuèUëµnk·Nç—–kÊ0“º®Ò¿Àk!Ñë±ákÿý   ìÁÆåÂÆj¢N@£F&¤Æa¥®ŽÇ¦ŒÈ^Ý„&ƒÊî¾Ë>Ÿ©f¿Íælî]϶ à íŒí�¶ÛL®ŽÓNmiP.g×&ØŽmR†kÚö ÛþÕNÍíÞÉëœNßV àlá&®ÃNÄh“Zî`¦Ǧ¢:¡è&d¯°¹ê‚ë›ìææíF$þ¥W^ýÀfmND.Ÿ¯ë_2öö¢ª)Œ´VëøÎ(¸Žk;ù‘1UL ªñÚ ò^qçp;Ñ�'«Z�Ý[qú8n4Ðìbpäjlç†ð§ Ør.ïò-·9 ¯î › çèÿ‰^["¿W ×h�_¯Iñ�vòÄhñøyqˆñ•žñ�©q ÂñŠÐq+äq;ñq! r!·¢5Ç3#_$ð%ß�&Ç"3�r),*Ç¥æ^‰]Êr-÷rQss»ð1€27ïF€Ø9W?�_j²p¶ «›�F6àI•Óàp¸bBXÿ¥.Сj«õƒ»ÂPeç� ·b„öŸ¸€´ ÷øÃakÉŒw÷à‰^qU„£ª‘:¹ ±öè:¸H�Îiˆ–`kÇpŒíù� ‘ O•ÈwÆ–_Y�ÜË=P/!�ø?sVau xõ`_Y Z_[=ÿ\_[]_^_·(`öa÷ªb‡øcOöeo—f×Ûgÿ¥hŸv£¨öЏv¦ÈöÈØvnOoßÂw÷Ú(÷Ï8÷–O÷7ÓvçwGx�w$˜÷Ѝ÷Ѹw"É÷Øw„yYƒF„WøXgˆY§ŠZÇ�[¿€\?¶]'’^7ó_/±…Ç"bç £0v­˜ ‘WfrgGh÷ i?>j§ tolm‡ë™§ù�øöÂÀyÂÑù àyDÂqÁQ÷·z2(z8úxWz`zpzç€z©oª¯z°»úWÏú-Øú$èzxû‰¿‚Šß�‹g�ŒÏ¥�öµß‰¶yÖ�ûÿ¹�º¿ûÈûKbypù €y�yn¯y$ÈįQ!÷j1w%p| w"¡‚vgˆwg ¤OúRYú�²w Çw}gî® }Ñÿ5ÒwuÓG}Õg}°§x±·x²Çx³×x´çøÛˆ .\À(èÂB .„h¨à¡Žˆ3&Ѝ8â" ]6rìãã "Et‘ä$Ž” VNhùñe 2 Ьyòf’ :‘ðlè3„Ì 6-ªä(RJ—hê´dÉ£)U60`Õ@ĈC†�éºåkF-'ð,‹)Ò©FÖ^­(b"Üæ.¨ à.Þ¼z÷ò½à/àÀû.lø0âÄ}ÿP pâñ‰Ž¿na`ùfA%.¼pås�Ð;FÇ�Èâ4‚ÔŠ h- C†È’'…A§ÎÌ*dè¢DŠ1jœý2äH %oN]Ù`,Ì�AkÚÄ™sgÏŸ@…-JíÑ¥L�6…:PjóªW³êØÚ• å°cÍò¯D-[«nKË¥kw5b‚ €x aŒ9Ùl”YÆ€nñ†Ðg^1†;Àu ©yˆ‚„¹öZl³Ñ¶…m¸UáAœùÂC ðçÖE#ddâqÉ)7sT=çRt/ÙAMÞ¥¢Nâ)¹”‘Ø·$y噇UWa••{^�•Ñ|ôÙ·˜F´Uÿs=P×!ö5 `jºù&b B&[GZ! Z`ág’fj‚'^#ÂF§d”¥ˆ‹¼-äSŒ3gcq’å˜Ür(ù]� Y¤‘HV°ä’M>©d”˜ç•8¬d%{Y·¥X-ÑwxaægÀ~¥™‰&¡x±X°Å+'ƒ‰~õ žzòy¡Ÿú¡±†–h¢¢·á6Pf-"ôèo2–F#q8‚¤c¦I¤÷ã�zj¨Þ‰Jª’¦‚e”«¶úêzXr¥åòÙêe®ºŽù–¯þ¥Yì°€û°›È>Öà²wFè,Ÿ~jh‡‚VëÚ¡&v‘­ŠÜîæ"¤I*B�7wÿ.¦´ªtL¦}äLh0š|4ÑF; •�†´gm!8£C𬠮p•ë\ëúûzò ÔkN�¸Óõ ¶·o"ìl ÛEZ"Ö– Ã¥* jFÈ2U¡z¢l1-+Q“,³–YÉǼ Z°R§Žu¡H{HI0‚q­h« \ûVØÆ”‰ëÔXcâ» 9!p”=¬§_QéÛýþ¶mòëˆp©›/63±Ç=jr“ºKæòÀ¹‚n¥‹Ù‰j¶¢œÕ£g§ùÕ?†›cÕfY¹ÉÄñ’÷¥,ÿŠS¬�¨·Å`/]Ý;S?ÉWus:A}“˜Û'ú Må/�mçßW²~²n@‹;ÐÅžæÇŽ]0sÌÃQÂWÍ,37ÛÙ®~öƒÜëhÉZZL’˜¼'N1ŠWìbõÂ8² �k|cо<Äo†|ÜØ ó¹0ÒĨd†4¤ß„À`t‹ ­hÆ&6ŽÎÀllŸçêjªV¶V+¬U‹f·ËÕü²‡Ã â1�ø†%6±%Ñœfí¬Ùµmn(: ëY×x¾�É1ú×YÏZÏ î3°ùòçZÐ ôI m`E/ºÉH}4l"ÍÜI?¸Ò•�ŽU1�eëršÉ\Öðv9ÿ,Ú’�Ö¬¥¶Ò©ÏŒf5·z½LœëKa]^˺ÖsƵ®QIïø:Øþ&̰§YlA#{ÀÄ-°q™�hFïÚ�–Œ¤ÁCé0YÛ—½2…³lá-k×Ëâ3¹ÅlnñšºÄêV1«ÛÝÒwÃ[ÞqÙ·½oŒïaîšÞýþ7ÎóòƒÈ ç2`�sjrd;LnY²€¡ô¥ÏyŽ ¸Iò\ # ¡êq \�èg䡚GëZ?X¬e]@@‚D4éªn%†µ³= nûXÆâÎ1ÀÞ9xÏ{V£½"eø;àÊ¡ÁÞ×Ú9âPë}ï;çŽGÌÎ}þsem!è4z¡›bôÿ¾ó'éKWzÓ�¹¨“d S¯z®Þ¼èh}è%ñ:ýÀ>o±�ìeÏÈÙ™vú°½íow{Ü[2÷ºÃï]ÑûÞÐw>ð½$<ôYP =¾úмÏ�~MÌ'[ókY~çóyÐߨé¤ß‘Ôu„zÕ·Ë]­ÿg×a/û—Óþ ¶¿}î]¸{³ô~í¿~ð ß[Ù�ñ‘òíÝò5ßß ^ô Þôµ‰õEàj`_Ïi_‡qŸÁÀæ]øÆø Bèu„sœ_È%ÇúÁÖ±ž?­ ì ÁüÁŬ�ÝíáÞQÒþ•Eÿ‰Áÿ…AðM€šßò]ßbÍJ Nÿ^�|…åÝ÷q^ixÞç… GŒàIDÝéY ®L¼×AE ¾àDÄ`íÍ ‘ š‡ÚõŸÆôàJRâÝ>Äò!±0L.! êEZ ÐÁÑyŸ€ßŠßøiáFpax¡ú�a¤à®`üy΀Úºá Ý Oäà ;ß\`*_êõùa¢,Æ R^N!"*b\ÈíÍYªXGd“OT\§8Ç8á†ÖUˆ.*Z'Þ_Ù�¢•¬ÊT±�Æ`žâŸña7vcãé: ,Š£,"-ò\öÙâöbæi`rà"F/ÞØ/Z‡06ÿ1ZV£N$ãg,c¢5ã'Öà aÒ4®]5ŽÆ,$CÖa$ÙD¤Dv£7ÒÛ^„£Ö a,–㞣äâå±c÷¹c"Zá. Æ<ÎI=âÄ=†@>ZÜ>²Ö@ #ý(£I2cý9£Ù¤•äCQcB2dCb#›DN$EbÀ7æFšŽF’#G*¡G¦ãVÞ:–a;‚ %ñ‡t¥WÞžs8ÇJÞDK¾$L£LºM �MÂã àdÈà BãUød1e5 åBÖZ­í�_þåQFdR*¥E‚£+þ᛼bTJå_ÔbUÞ¢Hf VÞP)yåW–]X®ÄXžDY^[1®?Vÿ€?^@ª€@Î%OÖ%¤$äèåðe�ý%`æ`.%^4%û æb>ÞTV :^`dR¡çXIeZ¦€efnf0~Ø0z¦>†æh–æiâ_jZ…]Æ^j lʦ|Ѧ_&Üfa2åan$œ(fo:ž€è¤ñÏ,ÉÔ¥Jf6ÀЉIéIÑ EiQRöàŠ­ŠI�(š(•äõÜíMÕŠ¹œÙpÈ^´ÏzN(εgÙ½çBÈ§ŽˆJ}Þgtäç„ì'Rôç ýgð¨y h‰h¢ýX‚ÊÀ‚>TƒÓ–A(…Þ(GZ(ah|*ÉÔqhfz(L€èt�x�¨•˜hÜ¡ÿ(T¨(y±¨ ¸h‚Æh1ͨÕèiਖš£`¸'߀D�ŠGô¨H‡rÇ’é„EÅ‘†”€jǪ”A©”J•Æ‘•:l)Ÿ–£ŽFЗÂg©ŽŠ4Éô˜šbœšò'›–¨›ž¨v œê�"Õ‹Þ)åiíiŸv*c†—vLdh½*nêô$ª¶A…} éU(éXl…¬VÎ{LêTj‚]jÙ1¨v8èDx*°Z`8Z¨Rƨ†)â…¨ êá Ýª˜ÇT•–[¼ªñ!P¬Î*­v%ÉN\ÜœÎ%Þ`j�'¯«¹Jà°ÂF±~űª¼ ³ò ž¬JvÂÿ{DÄ´Z…BYkK`k¶’Á¶úɾy+^€k¸–l’ë¬�+Ãúæ_ë…žH»–껪‘꼚G½FÀ½ê@¾À¾ÐX¬˜¤Þ�Æ ¬ží…ÁÞ^Â&%n6,ÌöYºfÀºnÁÄŠ©©êD¼ÒKÆBÅÆvìÇ†ì Œl¤_ÀfÊú˜Ê‚«Rµ,E¾lÌFí~ÍlÍë \-ÖŽé©^ìôôlIüì½mÈíO”¬•œ¬Í¥¬ 2í.9mE–«ÔÆíÔ>¬ºFìȰëq\ÖfmÎVÀÎ’Š×ز‡Øî+Ùú„Ù^ÚòÁÞ…Á6­^*¬¬É-å `�®fD ¤@�øDg¸ÿkQ#zቫZ…¿îÖ¬�¬îœõ`)-ŸÂ™fyV.íâèåPæ¢ÀævnC|.ņ®uŒn„”®œn~E‘ê²î�¹®%Á®ÂAmíFoTÞî äîîF‡ç’*Îz‡è¦eI�n£Z‰ñfÈ_%¯´nð½nßÅ.ôJ¯û"õZ/çboïjo²E÷rTÀñŽ/†\‘Ú¬îù.oú6oß½/óiüNiX\/Ld/²*E“äÿ†ïU@_ã€ùÎÙí$­“%°çè_`.kîü>pýF0õ Ei]p!Q’«m^tð�}pÚ*í÷ðb ˆüêÕŠ�Úïš’ £ÿ ž ãÅíŒHkè0ã6±WqG FËÓ—Ø:å`´Zð[5TìÖ0ßpÛ@±Hq¯Q±·qõñ ën ±vœZ÷ß#qÓ3q;ñC±ËÚ»±!ÿÛiϱ×1k’?T ï±õñàmð rÛ€ðž²'™€Üm.ÿ„C2K2›“+ÿX&�È ó²-óW(·Í(3²(m1yÝqïå1 ÁU+3Û+#U,»Æ,ò-7sŸ¹FÀ)TbR›ÙjC-_û:³6K-4›45³Ü\Yó01ó6Ÿ³ÜvóŸ}sÜ…sÙ9»‘9£®3=ì:K;�…;ó<—y5Ô<׳@«kH>·Ä>«P?[‰xrò¯ 4DkA ÆAO@BÀB_ECïpG´Gwª€ ñ4'tF[ÅFOñ´Jƒ´` 1×Z5ßÐI¯qJ¯´MÛnK»ôˆÀ´8Ã%Í4!×òMõç´N·†wz'xîPÓrM5Tû©QuRËæR7u@GµV¿ñTëtUóåU¦Co5YóY@!ù, Âÿ7H° A& *\Ȱ¡Ã‡#Jœ(!Š3jÜȱ£Ç� CŠÉñ"É“(SšLɲ¥Ë—0cÊ ¹r¦Í™5oêÜɳ§O�9 ít¨Ñ£H“ -ª´©B¦N£J�J"ÔªI¯bÝʵëO­^}‚ K¶¬Yš Ï~M«¶­Û·pãÊ�K·®Ý»xóêm  ¯ß¿€ L¸°áÈ+^̸±ãÇ�#KžL¹²å˘3kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°cËžM»¶íÛ¸sëÞÍ»·ïßÀƒ N¼¸ñãÈ“+_μ¹óçУKŸN½ºõëØ³kßν»÷ïàËÿO¾¼ùóèÓ«_Ͼ½û÷ðãËŸO¿¾ýûøóëßÏ¿¿ÿÿ(à€hà�&¨à‚ 6èàƒF(á„Vhá…f¨á†vèᇠ†(âˆ$–hâ‰(¦¨âŠ,¶èâ‹0Æ(ãŒ4Öhã�8æ¨ãŽ<öèã�@)ä�Diä‘H&©ä’ã!àä“D)% TV)¥” d©%“\ð$”WbP¥•aj¹e—K~éd˜bŽÉ›ff‰fšj²éæ›eÆ9§’j"`§›pê¹'’}þ9f fJh�aމ虊Yh£€†Ç¥˜Fjä¤W:j)¦—jZä ¤–ŠÆ©¨ê¡êª=´ê*¨¡ŠÿÚc´ÖZª©¨žº*«®¶ k+¬¬7Öjë­3äªë®zôê+¬ÂKl�_TkíØf»Å¶Üv»mà†{øä¾aî¹N¤«îºéީ»ðƹÀ´Z{m¶Øz«ïáŠKî¸ç¢ËîÀîÂû®¼ôZhoµøæ»o·ý‚û/À¿10Án|°  O¸ð �ð0ÄO|CÅ_¼nÁ#Ü±Ç ‡<2·7`2Ê*¯œ±Æ.¿áÇ2ÏÌoÉãœs»;|«œ>;(ÂÓ@7,ôÐýÞ\ñÑéR¡5Tj¬²3$Út‚O‹`ÁÙh öÚl·½6pÇ}ÄÜtÛ`÷Ýuä­·¼wöÿ¹ô¼c3X6Úi»m8ÛqËM÷Üwã­wÞ|»ÙgÏ�“ý4ág®ù‰Ã½8ã�Ûð8äqö­&å•88æ›Þ9Ÿºè£G>æä§®ú嬷îöë±Ï>z¶W‰»Øº÷ Ì7ÇóD?ÀôÓ›à¶ØgüçtÿÁ÷„/~ä'`~è[Æ)›Xæž ¾ñ•ï|é«Ìú؇Ô½O;ñ“ý쇿X¯mûãŸÿú@ï�¯€ _Ì—ô@}Œb`”ø@ìDÐyГþ.ȶ aƒäž B’Є(ü’ ÿÛ‡¼BP~ó‹áýf¨¿ýáP à èCžP�)T! �X�&±~2¤ ×fÃ'Fq€ áK˜@Ê,�}[äât"¸6ûQ�‰jóßðžè¬ �áË€ IHÂ̼ñQL“£ ›WG;.QŒkÓãèøè¬?NQ� ¤ù2ó«!FI  eÙʦÈ92RmŽ|dþòØ¿=â°�–äá0©ÉpVžÄ@(E9J”R:tD¥#+HCI>Ž’½Š¥øh©ÉÉìà™ÐüUì @ÍjA´‚õËåó©$f$[9ÉWVÒ’Ëd3Ã&hFVÓ¬&5¯©€lnóÝTÎ7ÉÿÇSoÈt•2©NB6¦�îÜ�4?'Ïy^ÓžÛÌçp€ˆŠZ´5�F+H€Žz”Ã+€HGšÆ˜ô¤H©JWÀÒ–¦OAˆ©L³I?úá¦8Å�Nwz�žútv5pÖ¯˜w%‰ò†¢­(Fk Qpô£ éHEZÒ“šT¥+m)K_ª&™Î´—5U¢ývºÓT’U§AíÕPIPT£ê©I]jSŸ U©NµªVÅjJµºUÃÀÔ«A iXÍzVÂ’5­¯‚Q¥äÖ·&U©Ý(þ ÕÑM•ª ´êUõÊ×põK€ ,X;Ì v§ˆíc«¥Ææ®�¬S'KY»ÿ’4³š5!óW¯ò¿¥ÞiѪÚ^±®Å l!ËTÉR�² µìeñzRݶQ1½•ip§·Ý ©Uíq“{¸ú´©s�ìðrÀÞöŽ4ð­‚|çË&ë^1µêæ,ÐÝþ:ò¬à-®«ÆKÞÚ˜·§èuîô¢û¸öºW¤ðMÄ|é&û*¦VwȰ†÷ë_;Vлÿ=kxûHàÏæÀHðlŸ»^çà½ñ�pêkÝ ÓJÃÆ\‡ïÜVÀ«e+cM|b‹ž7Ám±ƒa,aÓX·6îŽ3ÌáÒöØÃ¦õ1j�܃;H^q<ŠUœäѹøÅŽñ„Ÿ¼[üÞxÿÊUÆò•y,\-È^n˜Ý· 1#Y½fv1“e<ã ×81†³Ž­\g97z¬"ærž$¯{þ*¡;0­ dBÿ½îÃÔË‚¨j€>ÒSÔ¨ÎBì0-¯'�àÕ—B‚¬‘ÐÝ×½Îmd¦+ vMê‘VSÀv�*½ÍK'TÓà4ú<Ý9POÕ¤6õ5S-êU'´ÕNz5b=kgãÏÖ�#u®iK€]¢×"ýu°�=ì8YV˜F¶²ÀìÄyÚ •ö.©­êϱ:N®†uf�oS܉÷ŸÉmnt@Ýën·™Þ ªxkzÞõŽÛ½G�og˜ßÖv'¶ mnËÚàÓÿ{ÝŽÞ{´á õ55×ÍnÉkÊwø•O}*ouºŸv6¾å©�¢ÀŽ]–Îô‘—|àÝF¹ÊqÈòô2œ×1O÷Ìi.qhâ\ç;¿@Ïôs1ÔC¯¦Ñ�~Ö¤ŽéMx¶Npo7uꬺ‚ÜQ˜ËSæ ¹ºþLœS6ì õ¼Mˆpo'áñ�_{Ñ‘^A¥Ã=òÒöÓëîì»Ã  _yCÇý\¨Ò¯š—-€à… -y}ʇ;©éùûOãΆ|ä%Où9Gïò! ƒð‡¯yºGÔžgè! zyáùÐw¹éŸ‡úË>‘õ”Ž“á¡ŠøÙ_³öÖ½=ÿܯû$H^½ôï/?|âßä—úçCOõ†B?útõèé©™úë×<ûf²}Õ} E{þa{£ƒ{ V~æÇ{m—ev|í'|Å·mPwrò§|ô—wöwF }µÐ8„}óq<{¶èQ(Oôfï�€�£€Æ€ç—~ÜåH8�(7q³|ÍWMh*FY"H‚d‚ò�‚{¶‚Õ‚ÖtM0è2¨74XA6è€dõa©´ƒí׃„è?¤V„G8}pP}Såƒ×ò’KåN-L—=WtÏÃ~ÈàbÕ$SÃQ�µµ¸*a¶b;RþóXˆàë& »©¤³ui²²†²)›+[´-+k/+R1K3{h¯a³&‡¬¤7=>û³´�3´�ò v´£CO›:Eâã´OvQKµUë,W›µe°µ]k¹_«*b;¶"U¶�…¶ ²m+yÜ ·H ·)[·Ë].Ë—µ·} e5û)(¸õ½¾£K¾b`¾Í‘¶c’¾Ë�ະ{f²;«P»#x»2‹¿~ë€Û»%üaƒÛ¸’™zg6Àq㉞h´75< ³ ü¼ ºÓ[½Ö«¹ØË¹žû=œƒ,ºâëÁ Ì"\%$lš&ŒÂî;·+,¿Þå©w¿ˆ�¿4¼¿²Ö¿V'Ä^ÉÃ.æÃpÄ—ÇD\ÄG BÐ;SìrL<ÁܹÜ+ÅJÜhLºÿ`ºIu¾, a]¬¡&<=Àú¾íUÀe,¡g\ÄjÜRr³êÆ{§Ãq|Yg6;ziÇ?˜Ç ¼Ç„I˜ôÇÅÄtã*›«½„¼µ+ðÇ©$¾ã{YY¼" É’§¾(WÉ–œ˜Üš à ÜÉ‚�i˜–Ÿ m|Ã;ë¿gœrì`¨ÌšªŒr¬¬À—¥Y) ­°,H²`äüýß|ZKn—èõ:O.OQjSnUnåXÞl„6nI¾æ„!æ^æàkÅ£›æ¤Þmžâp=rÞ+t^vx” ÆèDÀ‰¾ãçGè‚îã‹ä»ÔÚ¤è¼îèEÔ�±3´ëŒ~»t¾‘ N} µé~˜Yê\.ê^Žá`¾á~êv{egÎê\Çænë0ë®Rë·¹.¥èÅëœHj!ÞØ¶|ðmGÄN7ÆJÈî{Àë©—ä^éÝÙT¼Ní¡díPŽíR®íòÄíWî힎?à]^¯_α®~îdžîˆ¬êbËî5úêïòÞ*ôÿX2+4ñŒ¾ï â÷ç.ð;>g?7J¯~ Ïè ÿèJíLžïÓ^í×n¦ÙÞ†ÛîbV¾ñPùí[òâ.òäNò`ê'�¼"®ò$Þ^&Þî~áòÖ+Aßh1ß3ïU5*7¯Qú>�¤¶|ñÚóGðáì%¼ö߃N?oè×tôTl?F×ßE¯òòìÔšÍ8oäJoé�épJåXŸõ±tRô�þ阣7tá°œ†Aöð}ñšJœæzÄ Soï,þ›Jç2ï.F72õ$önóyõF®óòä÷d<€/ÛË7ì8€øDY”Åø†=�Ïß‘ÿ?ùM_ùÑŽüý�ù p©wé–éÚJúßcú¶_ªÿ=¬ßŸ¯oò±ÿ|³ïHµ9ŠSÇ „*Äa"ˆ=$ö`À`ÀEŒ4n|Óq¢@�9ŽŒtÁÉ…)U®dÙÒåK˜+ã̤‰ÑæM9uáÙ“ÌO „…PôÀÑ›F.=R`Q¨’n¬€¬K låJÀëW aÅRÕ8•¬Øž\¹*`ÛvÁ[¸%K~ýšTçΞ<¯ìå«vkÀG$ňÎСNsD`ÜØÁcÈ)$  µ¢Å›4o6X‡ò�CçŒF(¦€? B4ÒZ°Yªzd‡¡’`ÿçÒ*>„xù2lŽ%*^Zò$‚˜É•/wI“&Ù I Î[Ý'Пˆ…BÜÚ»¦#G- ܪá¥Ô¯§ëUìX²À5¢åé·@[·pß6Üž@ÒÐ:¾úò °^#lô3»Ÿ¢�pBÈ"›¬²¢~Ël3Í:û,4¡F›#·—PSm5ï´ :Ùô - Û :(¡”v b5ß*’¯‚ŽÞøÈ©â:Ž9"‹ŒÉ¹™ “nº¬³B2äî¨ïZ ¯)§È“ê&ªÎËj¤õØkï½°”äò¬°Òò ?¶ôÛ�?8üPÀ ,ð ûT1©µƒrB +t@²>³LÇ 9ôÿ�2 ‘D—L\-‘‘:3¶Ùjé¶M«±$sܱÇC Ò$”ŒTuU…�ŒÃL›˜lÒɼ ”Ò(*«¼r<òÌ»êË#ÂTÏ?25€5#45PS-6ps8ãloN:í,0ÏÀ,%¬OÄþ4 A½ðƒC1³‰Ã úP ÑH£1ÒÔ&­t°K7jñÅq{—!P{µ^�HH’„L•U„™Cca†­r‡¤rd€Î›ýì³12ÖøbÊ^|ñJû&yälµÅh³,RVÙat-XRÖéîÊédÍ(.$:r&agžG*âç"Ž­¨†:«ÃbŽ5Ö˜+!š^p‡‘@ ªÁ°ÿ� 1 `ë­K›p5¨d6#‡Ñéj‚Q›k®WòZ‰&’¶C°ûn]Ýao¾¥ö »d&Û*ë@ Ä?nÈ„O‰a†ŸÆHb£ Š["Ž?P:ãÌ=¦ d¿F&9Á=/BYå”–ü"˜™›f lÆYgžwöhɇ.º3ÏÃÈ|ó1˜vzÁ¨§®í¬Ic;€·£»¨×/*XäÕFdùÜFhÂË{˜ûÒºï¶;o$[^}€è¡&¼:ÃJ\ñÅ‘s|~È>ŸòÊ»ÿ}óÎ=]-щ¬dô:—fP—:«œ¯u1œéjF±ÙÑ¡v¶;Њ�;Íh½ÛŸÒ„'ÿ„§¯jVó ִƶæ=é›´R´­myÚ÷.÷½i$|â#ŸsÌ·:®//í#Ãû?ùͯqõCÃýrT¹:è/iüãØ¬xE,Z1d`RN‡:Õ­n�‚Ißfd'�œIp‚·û5È;Ïupi[i‰g©�y'äZ !¶ªïW.< Å`=ìÑІqÃ!²*°C¼iÇUY¤äw—Áá p9œ‘¨DÇ1щ¾�¢/¼ÌUR•W ຘ¨f!Œ’ãQÊø@:EÐAl¼àÓt·Á8NуtaDx3 ¢²Š+Í">Ig2rèa \ÐzdÕ»ôÁN@ilÔPx鯅֡¡�CW3ðU°Úç|yD¦4 ¢Læ•!ÅäMÌv„ê�´mÖTkì*·’¬ÅrÐRq°RrÎì&~»@"ÓÅÑTU6]N¤ÓŠð4ÿ>¥ PGðÌf6•ö$¡Œ:/¢Ë¯O[OWM+¨Rª¢*»´sÕ„¾‘¡ÁäªWÁúU±®Ž¬MæEû¨V°µœn¥ž!©Rº–Æ®eÀ+hõZ¬bù°-m«MË 6<ëT,‘‹Ç² �l<)ûËfV³Cgg%óÙÒ  e£mªzNÛÕÔVwµ%hm jA¬ÓcŸ1ímqë—±R”„fMÞˆ–Üàþzª½È[ãz½jÖ¸Ëmn|¡]2Iמ�Û`¥VXí2…»Ý]ÎwÃ{É�ޤ§qû)PÕ‹Y äXÇ+uo •OØm†¾„)í}ó;\}N5gUÿ lôK8˜26pn%·Û{ô¬¾]¦Z…+X›XظrÝ •{W‰hiG ~�_ha] ª¹.²+Ä2ŽÅ-vÈMËòØœÄø3žH�/{cëø‹ftæzüã£0ÈšrRŠ|ÚÞÅ9´åï’]‹'ʳ•rmå`à ØGbIÁ2”LÈå´zYÂX5q y¬å:†ˆ€°™Âá4“GlfsXÜŒ.K Ëf6«OŒÝŸ¤x)Ö³Þž™ãâ?‹7Б•ñdi\Y#:Ñ`t£9öhA9©B^*iíkdÏi:QJ¦“ êˆ)TÀ/"°mo«êYWÁ®Þ²ÿƒ1*ëD”KCa–®sm½^'÷×hî�–†�,6›Cɳ›mb$ Ïá¡¶Ú¬¤\åý¼‰¬ ®ÜW:.Í\pã/È@ç;ç¹Îq¾ KAèñM‰ùbÖ1én`z[`~ H'Åa*‹¦SŒ0%I_Ä?»rŠÐ½. ‡}ËýŒS‘*_¦Œ|P v˜.×”$ ŠžÎþÅ¥@‰é8.L`YËf̃·Á?ÅvxÄë$Î·ŠŠÄ^´÷hʼï'‰ÊWÎT¸¼rO/€ÌiŽ›c¯ç£—Áσ>tŠ\ÆèçKút–Þt¶pž+ê$Õ Y«c=)[�b¾ÿ.t±�ì”1{ÖѾOµ³�+nç;†Ë¼¹Óý'v7>ÞG¢÷·ƒÔï€ê_øZ&^ü2[¼Ÿ Ô½Ç3=ò÷�<å[bù”³Þc ßû½à;»*;õˆ¯/Z»¶ŠìC.…ˆ> ©»’Ù4Û;ìk>çÛ>î<Â3¼ñ«Áòë–ó»œôûƒõ;­ös¿•€?�?ŒÐ<£á<Ï˱š{>Àì�°ÿ ÀÔ«ˆÕc=Yy½?H@2À̤äŠÜ›ÀÝk® ‰ß»à¾(>L¾ÿü‰´90Á(@Á£jÃ,È;Ù»d‰ @ Dü¾ï“•´Aaq(A?Ú€¼Û“<íB–B"l=Á¨¿-ÜŠ$”€%Ì…pÂ.ì ;),:,B¥;@ØSÙû‹¨» ÌÃÛ Cˆ¯ \Š üº TC6„%7\>l>œÃ¹;ÁéKA_”EÜÃì{Á—øÃ@ÄA$ÄÁ3ÄC?QÄŒ›ìAÓêCITJļ—¹ÄÍSÀÎÃ?%=&ŃëD®!EÔ3ÅS€+TÅ,Œ=tœ½Wl@«øÂ­ E[$ÃÞë: Là $¾¼»´ËF8F9¤C;ôÀ†ÔCÿæsA9ôÃh”Fï£Æt�kL¼l4?ì`Ä0pD¸ÒDö‹Äpž± 6ZÁ¸(‚H™‹¸”pÇßR«Q<=)@*$Àš �½»(y(Ú‹E #Цø †ÁE§ ¯ƒÇ­áÅ…¬¾†|È­`>¸ƒ¾b¬ÃŸ€Ê/‚’`üƒDzÆŽ¤�i¤FkI¸’’ÄÁ“ÔAϱÓJ�XË—ŒI™ô§£(C�€H 8LÄÔÉ…àÉ.ÃÊ�Ç œB¨BÁ<€+9J»IÊŒáÇ.”ž|ÀYŒ@¨”Ê…¡Ê�°J¡sL­¼‹D>‡T¾¯ ư,Á± ³lH´ŒHµÌ°–€Æh|KB´¸ÿñ³ºÔÅXD¼ô½ì*¾ôËpL£ÉÁ,È�0LÄO¤Mé#ƒÛtÍÜ$ƒ½sNŽìHàü>á?â 9ÎmœˆÞYN9hNÞ”DèD¨ÌÏùë¼ÎìlÂíÅå�L¡œL¢ôБ OóäÌøbÊÐtÊÑôŠ©�ªü‰úÔ¿åÁO†tÍýìÏa¤È²|OØQ™=Ð ] ßÄ�IÐ’%˜R*Ý+½ÒeŠÍÑ»äÆ¼ô‹½L  �ɵLê,ÌØ$ƒÿëÄNàbÒõÉÊ¥LéDÓñd:¤„¥ìG/\O0tÏôŒÏE'MMûäåJ …Mþ”MÿŒ»Ú,Òô<ËÜTÒaLÐß|R�”R*�Ò+ÅR¿(NÄ�Ð.¥Ð/U‹0íË%u¿2í¥3%L]Ó6¥€eÌXsL•L;�U£ÔÓÌäÓÍDÏýLe T5R­³ÑÒÄÑÓæ¶Þœ·îˆ¸æàÚ¥k�Þ]‘ÎkjÞkéíkmnìåì� ÜÂ^ ÄNì’CI¦î¿}lÖ-[Éžlv®lƼl¡ZÍÞlRnbϦÐm6mµ‚‰ÔÎÛª†ÜÈÕØ×ÎÝØöÛ®îå¯ë™ë(ëñmàvcáÞ]·.îã®ãýUîܵë¿Åk« iáåkéþëÆ~áë&ì�ÖéîþnðîñFònSó>ïà³læÀlöno£ÖÛøžo¦îgÒ>ûh©XÕ®]Ö`×FZ­Vh®žm¯m�WpÂ`ðaFݵ~p×%n ×hf®ðÊ©ë�–fžpîͨfÿïkl×9ì.qˆu“ÄÞ�îÜgqñFµòŽñ@ožTo|ÍlÍÎñ¼Ýq¥¦ïò}‘å©ÖïÕ6èþNrXòP%cñih‡†ÛÆí#˜*O +bnã`kçò·žpŽs£sæ&s"0sÍ@óèþp‘¡î6—�7gg�–sî.9;_ñ×sçó>Ÿñô®ñõ~‚öö_ΆoÏæqÍÍõÀUtOq‰ü^ƒývï[–tJ¿RK¿LW`(¿íÏíßíOë+/æ,·èáVšâ~UŸë0_nÞ…uY·Z·ZéNi\·n7'q^�sý˜ó:GÛ;vÛó÷óx&ÿ�uÜöv‹×XÛöëÊwÀ>�ÿxþø�W˜ØÉm‚ön\�åÓ¼ÒÐnlÖ-ƒÊ)tñmߦەß·\mJáý\jÔ-‘˜èZªb ‹Hú<¶Ü­¾Rq÷Übù©±íMVðn]“�tÖ1¨WViKTy�7 @5ˆ7â—œxþ­ø‹ÏØŒ×æ‘áxåû3y±'ù—0y�EyÍVùŒeyguyêŽù™¯y›Wœÿ{�GwžWVŸ^ N¡�Ф(ú‡9z HúXzfr§·›Ï�z©§ú°¶úÁgݬßúëz¶!*×_¥°{²Çû—l µçb¶wŒkÿ�¹ï]º·{‘§ý–ÐûŒå{¢öû|,ÉÁ‡y�y£¡y9|ÄŸÛœß��÷XÇÿyÏ úɇŠÊ1£?zÍç|1®t¿ýüÎ…z2‘z$ ýÛ6}èG�Ô·d®_ž×ßÿ,ˆ ž)hP„2àð!Ĉ'R¬h1⌌T6réèñcG'"3Îa’Ê *W¢hÙå%L˜ ¶¬‰bfA† /JdÁ‚äŒ& ‡n¤BrÒ#Js0Ýâ”G̨-ËÔ©Zµˆ…¬Y•píêñhR¥=ÆÆ({à,ÚjÕ&�á6 \ rçB¨kw-Þ¼sçâèëw/à¹7—-lØ)â-0ÿ‡h 7I`$’'›¬,"™Ì™ÇŒ‰*µeB6m&¤¡3À†ÔªW³níúµÄÓ²gó¬mû¶D’E‡é„de”V²téù%Î3£oâ”�Û¡O By{, v‡Ò#Ls †z¼ËT«WµníÊõkF¤ØÅ’5‹ölÞ¶oã&Ÿ5/þ�ýþ xð † ˜˜S‹9ÕX�E6™d–™„™fdpöÝK5…¶h™¦ÓkzØal³‰¸Ðs%š˜›FQç‘oÀ�”qÔDarË%çÜsÑ‘4ÝŠÖ¥–vM=EaxâaEžyçut]vcõPØ{ðá% Ög_~zÆ__þýG˜€…¨ÿØKŒ9Fß^ 6è „šMHd†ˆ†ai§}x'ž!ŽHÛ‰}ÞæÓO)RÑãF@eŒð°(�8-w¤­0)ޏé˜�Ôù8ƒzÙmלTiŸW 1ÉÞ“eÙ•Ö”nU‰æ\öY�%^�…éå^a†9¦�[ ˆ``;¬U•µ¹Yg&t!�Ú‰'´°E´§ˆ~ZË º©ÈÛ¦.Š ÜJ‹zw\�£Az‚¤”žf(»3ô(¦+v´i§K ¹Å¸žiÕ‘Z•úÑ©G8YتR®E¥•{ÉJëZ¶ ˆë\ºH`¯¿6ì°Âû`„&ûݲ͹\�F{òjzR«Óµ-S”ÿ­ „e(¢Ã©$n£3=iA“® [»†¾+�¼\Ð ä§C~·ïxH* ð�ë Ü^ Ÿ« ÇŠ%Ãúv+ÄH|Åeh1Æo|YÇo‚òÈ£•ÌÊuo òÊ$º¼÷C0ϰ›¦…Òü¢ÍŠ2ú]¹6�›î 8þxÐ@ ½cÑGK�4¾¡ŠWG¿å)1TÀ«Z«g «\ wm—]a²þzë†1;í¼ší«Åbè¾{ÆWelÛƒ'7Ü¢0÷Bv£ŒwÞ|;ï7àÜ TÍáN®£æò|†Ï�CyF*ˆ?þ¥A�Äúé[îé½ù~&*¿¤>�§@Š^5é³uÿ:dW’×õ`ç:ؽ.L´£Ý¨ÀŠånwºë]Öv,�Å„dÅk–6D7åE‹y+sß ·-¢LÏ[àºÙõ<“¸š,®g“òžãÀ¾ñ‰¯|™âBúÔ7½z‰;J;Ó8'¿Ï™*jM¢šÕ°6Ÿþ)Œk  €X@Ù0 \àí,>°w ^‰·¬¸‘ÆY&ã`ž¦•7–�ÐZ~k ©Ó"’( Žv¬£Û>#ƒ=ò±�{t „A’]k8$"eX¹ÊU�)Bˆ I"8HÖs_Lø(…M"ˆK8p o|S«Ø ”¦ €”$%È*0x%,£t€%вÿ–¶¤e˜LiJ.òR WL`MF L³˜#Cv²‡e2S˜ÎAMø˜œ� Ä�28×¹ Ím¶±›Þ,ÑãÊ‘ÐQÌc­¹œ@ ’�ƒ ")ÃJV žö|d$'YÅ0\’Bšädc< ÊÞˆd”UÑe)Q™Ê¬²•€�%,jƒ[Rt ¹Dh/¹h<8³˜ÆìX2•ÂÌf>š-‘fölbMŸùì›.}éŸ.Ç¢…„œ©ã9…—N?®“�pç;AÏC*’žö¬'>'I„}öó;ÿ”B'¹4P�ˆÒ$¤D¨BSÙPû¸¢�hEoyQ]fÔ�í¨G pÌ�a¤Ëÿ,©IQ€R��f¥,]Lóª×wÁk¦4�ãMÍÙ;tÂä¤<�OP”èyd¨kP$쎊TÀ@R©LE!&aòÔ¨ògª©ª®ªË¬ª2IÝ‹DÁÖZŽu—eÕÝY‡™Öµ†Ô­q€k4÷¸ÑÜöñ®xÝ+póNšr°3Àé`uZX¹Ö&‰]ìç]ȾN²Hª>«ØÔãl6 R…Á8�`Ð:Htl…a«¬R«^S®–µ’èkak<´z”¶É pkX2bÈ®, .€]:Ü¿Úô¸‚Ía+t‘é±>…î @aê²ÎºØ•äe —Ù—t7/AÅkÕƒbÕ¼1@¯ÿ}Ö»Þöâò½�olG�Vµ‚4¤øõ‰~™Ëßåø·¥þ1\4ã"ÁÊUphìÜC—„‹•'P„YÉ^x©ÚŬ?÷¸I¨6¦^ö‹gYTÐ×�v§41[¡ æ5«X½,¶¨€ØÊËйλmÉŒí›�³®|¼³Jýè[ zoB–‘<¬/Éü}n“% ](“DÊÕ¥2eó‰á+k8Ë2Ø2‚¼Ü0ƒ˜ªcmUÌœP4‡tÍln³jÛ&9s±Îv¾³gô¬>ûöÏ€Þ/]èaûéÐ+JtN—¦c_/™�vrQ(�KWÓ{©lv¸]ÏtXÔ¤ïxUÿmŸ¸Õ®†¬c½ÚY‡tζ~ s]ãûÞ¸×Jt�'Eì}›ÈØr,p‘}äá©ÓÁÎŽôG ,íPÛ.δe9�3§j !ðv_Â\S£ºÌ³;³yÓ|ît#”­¿üCÈ$@k¾Þ¸ŽJËÙÊë»2ß‚¾+¿sÓ¾Š3Ä@ ¸° ì{·äF?ú³%ýd¢ªáu±î*±½imc™âŸ¶8Æ?YêÏžÚ*⻓ynt“Ü”&ÿeÊÙ*.qµ<Þ0·ogÎÒšß™v¿»°u®÷Šø;¼?WtÐ>tþé¯Î¤™e”Lù¨Q×´•©Þi«ƒºË_ÎøÖÅÌqÿ¯¼”`�³¹]]v³‡ôäiéÚÕö—Ǥåq¯7͉¾Û»ãç{¿}D0@Dö<ÄOx‚†0:±|Lú ½‘ß3ÿ l¥¨]`‰Ÿ7P¿úcáÌœ4• NÌ9 # þ¨ ðT<c4ÏŒI8Â� [? ÿù§ þöÇ&¤�ÿX3±ÔHbMÓÿíÄDlÓ6%GÊ}�.`¥àžæÞîRüžð Ÿ€ŸO\$ŸÒEóýÞóÝRô½ÒôUõ]gh_p_�(Û÷…ßøÍØù=–)…ú±�¸JÀ_HÍýÙ_ýíŸþá_ÿùÔÿe@âDnÿ�Ý$à*`> ê^Fðq—HX ðß�_ï ú(„ ó…ôÕ…ôå ¦`` º ™QK„ Š úIFEûñ &ÊŸ!þ!6!;%áÎD&�ò@aN!: Î—opaðyán%–'‰!�¡Ž -• œ ª`öiŸzŸ:ÀøEÀŒÒJMÆÄº_ fÇ ~@!¦ÞÙþ)b Ɇ$£2Þˆˆp%V"4JÄ%f"�U ðuaÞYù…bŽánÄØ½*®R¾+Æát Æâ,Ö¢¡@Yúňg$r@/*ÿÅ/ã0îV1ú‘2*#2þ£¬j(Ï3F#BÀ4J`nâ5vb6îÖ6r‰(’a8²Ø8&I9bß ºb:¾ Æ ,Î`ZÙ¢ Ö.ÊcTÐ# öNü ¢>"1¡? d@þ#A:ãi$$OBÄB®Áò'b aÀÎrL$<ÆcXä¹QbÔRFšÇFr$:RˆLàÄÒbIÊP<Ç<úÔr¸Þ] 6Å$6!â¹X“@äi¬åÊ QjdOVaezÄP륚p£RÅŒ]¤-=%-EeWL%z¤U"VŽ$n%øð�ùQb…%Ü�%Yšå¹ %¤¬¥[¶¥MRÿ \n€\Î¥%ÖePE^FÑëð%ƒøåR‚D`6å-æ&W”# Våb&GVºcdÉdöQeކX²Y&€fæßLb“g†¦N|枌fišæíýdj‚ÄjåëÈRú…RÂE9Φ«9¥S@¥¾Ò*…Én*fo6f;BfäHf]Q&Xçe"'YÒög&!íÙ]r>'N‚f�N'\V§uêvÞeG ¥¨‰ìxg_RdxŽgZ f-Ù&n*{¶çö­ß{ÎÄoÊgÐÐg ç}ÚÄqúLrö§þ'5( (�&ãM¤h&èN.h46¨ƒBh„6À„FÉwöEx&†zÿ”†Ò‡¦'¬§€€hˆ.fø¦cj¥G)Šò'‹æ§‹î'ŒÒ€ŒÎh€Úè�æ(Žî()¨�ÚÌéã8–ƒ¢ �WÀBÝÀ˜˜gb,/ ‡fü"[±•ýmTÊõ;©‡zÐ�øÀÐ4ê¯5[ ý€¦àC܉trjœ†êíÍéÔéPÝ)äé^ìi×ôé› *b*jf j¢&Ó¢�¥b* A*RHª Pê®^* $–¦þ¨Šª².+D�ª©Æªªê\°*øê«&�ȪÑ*Øê­*E®bPB8j ùê«°† ±Ö„±nªÞ0+¼2«³Æ�¡Dÿ«žRk–Xëµ:i¶ŽF¡¢Ä¡â·fG¸Zв�k¯ú*ºÂÐZ®kK´+²¾k¼NlœÎë°‹Ê žú�Và«Zè뾎‰¶î·zë·¬�«Áãi«D4¬ÃBl²R,Íò¤Åbljlªrì}x,È^«Èúë¬l­ ìÀA¸&Ö°>¬OɆËFÌ®«ÌJlÍV-B’*©âló鬴¦ŽQ+„­Øîë†ök³íÎ1™ì­"¬h ;)èZ–) Zr©ÕÞ-¿aíœj-óq-ÏÎŠÇŠíØ’íX–:ÚvÌ/R*[±­Û²,YDÜ–érøVÝö(Þf®êíðíïùÿmýOà .náúÑá&n„,. 5®Ã²-Ü ¤ÜV.f Ýj.îçzî€îÖˆ.^0€ð/E‘n鲨pÎU,"®îÓÕ¥®Ð¥&Ö§RíDL.Œú–å’åíæ®÷æÕîŠÂùfÊÆ†nÇæÅðï-ï›%ï¥nóvÌó*@ô¦±R/tÎ,ÔÊn™joínS÷~/{SøÅø–¯ùî,úölð®//é¾o}ö‘üŠ�ó>ïýÒ•ÔúTõO`o°~Ú.æ0 ×GNÆ‚D’–G°éÞR0¦\bµÜþE�ï0ô°wqZ“á2áÿ­e 'ÿñ÷®pдðG¼°šÌ¢øÍ0 ¢ ûãßï0O 1[psœ°�qî2q»8±G@1ƒHqP±-ÕpÈÜð»åðGAÿ߃ñL 0÷ñÄ" 2»r s®o#»q-Áñ²È±­Ññ—H+oNˆ±_ræ2 K„&#€!ß"Kñ>™îŒíg16Õ±?‡lñ[2&ÇrÍv2'kò'³T(Ïâ(n)W³1$s1+Ÿ†+Ë22Ï%-GD'ß²ÏäòøíÓŒ±U=öòý²Ó(äˆ$³7Sì2CD3ëí!"KsZQ3Z3í`ó,j3,_7WÿË7×ó²†óCŒ3Ö–³žsMsHUsZ™²·;„>“*?ÛŸ?@'“@{AÏ¢Aè6+t<7´HCãC@DÏéD×_EÓÎEgGFÓF�_GÓÞGƒ4ÿŽ4N;`IŸô¤t ¬ôì´´R¼41Å´øÍôÝÕ´MƒpN75 'aËc0r$UW5ö)mÈä�So5W÷ITKµZµX_µO¥œVw5Z§õE|5X×ßX�5V/ËY«5]×5ÈF[Ûß[‹u\+DHÛ5`75^çu ìµU'Ö¶bwõ`çµaW5bSËbO¶S¯ÌTï5�^îžP6g�Nôʬ¥oÉmfs¯dw¶i×óg dh—éh›ðfŸ6l#sjÿãjÃhk piǶnûñl+cm÷çmkSbï6q+qo'ãoógp'Àp·sZ@!ùA, NÎØÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹1ØÈÑ Ç� 3ŠI²¤É“(Sª\ɲåJ�< 鲦͛8sêÜɳ'C˜2gvôI´¨Ñ£H“*Í´ Ð�K£J�JµªU¦4 >zµ«×¯`ÃælªukL±hÓª]Ë!Ù�f϶�K·®]£oƽ˷¯ß¿$óØ ¸°áÈõ‚<øñ‰Ç�%Hžœ¸²åËTãNžÜØ1äÇ›%¯M³éÓ¨]jÝ™ñgСI—NM»¶íŠrë–»·‡ßÀ—Ž¢¸ñãÅCKÀ¼¹àÛУ_Ö½»7oàÁ‡ GÎ…òæÎ³JÿOÞ0õÜÖ¯c÷ }{÷ãßÁ x^¾¾}¶ç7¤—²ž}ûøÞqòÍ'Þ}&V~ûõ×Þ 8`q­�AŸ‚f¨ƒé9ø_„1LHakjhâ‰;qh�‡Ú�0ÆÈ]…²m„â�8ÖÂŽ<úàã�7)$Dù ‹1ʈ\…%æèä“ñØã�> 9d‘D b’0ÎHâ�P†)&DRîHe•VÞ€%‘´é&’\zÙY“cÖi'e‚p¦iª¹¦›onç’_Bu硈 ”çž}®É m™¤œ�Ñ™è¥ä! é¦tê© † é”jê©¥ êªErI°ÿ!k ´¾vB¸r•a˜öêÕ¦œzÚi¨¡V`챨&;Àª¬é*¬Èz­)ØŠkº¢Ä«¯ÜR¬¦ÂK¬Ç"«ì©ÌªÚ*—ÐJK­µ¹Úø’YÝÖ;Õ·„ÛÁ¸ä–[Á¹è¦»n’íÎZëk×f{Ò¶ö6l¾ú&!ñÄþþ pª;Ën¬W‹p¼ríJ¯Ã$q¸SìïÅ3;pŒO{ðg Ë«Ã%猾kôìsÊWÌò²éºê*µï>æÆÒ–^„³ÎP·Ä³Ï=�„Ð,£¡õÖFs‰ôÌK»Ñ´EOGm6JSSm5ÖoÍu×1~íñ a�]QÙgç=RÚ?ÿÍ6Ànk wÜ_CV7˜&ál·ÞŒ4Ãã�S]µßþ: Æå˜ŽÆà0Êm8ÓˆGT ¤—®Üµ×þ úê‹7Î8ä‘K¾våkbžyàœ“á¹Ò jÑ襓~:ê¬Îzè®»ÎwÏ-´ Áó${ÀôÔ7`ýõVd¯½ ÜwÂ÷àk!þø&`þù(ÛhÊÉàþû"vGÃüô¯¿B�ÉŸ½üÍC=ªÔ«Þõ¬§½íu�{à ßøÄW¾ó™/}ò±_ûÞç¾øÅÏ~øË_Ôö×?èI/€  h…"0�!X [ãÀŠ.‚ë› -(" ÊGƒü–äøç<„a¢ÿQÚ€ˆ*ÔBCÙÈ~4� ÁƒC¨q°‡ÏK¶ÈE!…FD¢ —X‘õàŒhÜÖÈFEÑ8¶"cvEÿi‘‹[ôb‰F&QŽ1#ϨF6®Ñ�oDAo8Ç’mê�ôY&ÙÁ,¢ �yÔ#MHD˜‚à$!ÏdÈCºDñ³Õd²Frë‘‘ìÙ$›PÉÿ� “Ðc6yÀN‚ä“/ ¥( iÈSSBÇQ¥dXéJ{Áò’¤$mi*\ê’—ÞC¡'ÉDa’˜m<¦1¹£Ìå0GaͼÔ3£IËiÞ�×£ ó³M*^ÄøÌ§({ÿNSŠ‘É|Í*Ïi3¨µîN딥4ý×'kj…eˆ¨DéùKn&_ ȨFó©Ïa’²”ÿ<%9ºL‚¶2gµSB×0ËZ6“ñL D'zžz6‡!ÕhF9ŠÏ}ö!(IjN�4Q01žêÂ6¥þ€~ôCè·ž@Õª2áªÐ«˜›$-(xõ«”b Tç×Â8_ H«ZIÀÖ¶–à­píÓÐ’5ª´ÇˆbÈë€&ƒNL%U©L]šSÇJ©«ªVÅêó´Ú&®Êê«`%Tg[Ö³~K­km+[á ×¹²Ì  ­]µƒW½¾‡¯åÖ_�X7 v¬†Ýb©zU&ÿdÕ_[mOW! …°ž�²-´,°0›VÍn–³%ðìÅB+Ú»š0¯bØ«dúz©Õ®ŽØÍ.wÍö µ½m¹r«�ÝBÖ·ñ»ã’€¹ U.Ààk‚ѧ´Ñ=ítSë+˜ô'»ÚEwU:ÕÙ†w±¸m¬nË[ôŠH½šboº@_ùž‹¾ö~¥+ê"$ÿ0¶ [ÖÀŠÕc/àØ#|õ0vð„ Œ §«ÂN†�{@èrØÃˆrUˆ<ÒÐï¦bÚäk[ÿ©ØX䎴¤ã*¿@Æ‚Ìê6¥‚.ßáË`ž0Žs|ª“–{Ðò±dSj"HºùÿB^�ˆGŒÈ™9cRòã˜ìä'W Ê™2ƒ¡Pe# õ=ZV—½ æ/‹¾Cƒ�¤'­„J[ÚÌ÷E3¬Ô|œJ!oLo†dœ±3ç"ßYyÖÔ’i›bñz ‚v1o �J%ú‹VA£}cH³lÒ”¶t¥1­aMs€ÓÆñ´ïj8siȨ‘ç‡ä0éy|vò±^kÞB�ÖJåc¶¬©.ëz×�fn²¬lI {ØðÍðº—fÓvš1l–LðÕìQ§Ôu~Ì©S�€Uƒ·Õþ³‚Ë+hoƒ™Y·¢ËÍèF§;´ëZ»aðn%{ÞÆFöˆ,ôé íû[ýÿ~¶œEljjã9ɪÞ3«›ì¿m/\Ê Ÿµ Ý�[çz×w¸x|QÅîvwüãôÞ´½“�ƦbNk+”'=èÁX·@)�jÌ[ùt_këR ¸”½¢Q¯ö@ò´ñ>‡6PÚúÖq‰K#~ýr öžp‹�ªO}‚Vÿ£Ue=ëÇÒƒºG寵ËN Ô£>õÖTýê‡Ïü1½neîŒ�.gßJè9’v{„íív;há ­Ó—û×óª½ã ïÉêS¬Ox>ó‰Òâ¹×øÎ'g¿‘:ÚK_ùÎ\>óšïºWïîùÀ’]>fÇþòÓnÔ[õ&`=ÿ€\_ØãQöV¦½l�{Té^мÏAáUýàß`ø6(~•�| WfòÒ|�‘X€V}‡·yÓçxÈñys1zB�Pzj§(e2*à'~1@_X~±gBw§~ìçg~g*ï7eñ7PÆ¢x<¦1v|æt‰€ò!€ŒQ€ˆyh} _å*ÕÇT×Ùg„ÛuÝw��’�m’P…8…&Pw&ÄS ‚|G‚¹—&»+ƒ'¾GÀׂÂ÷‚²B}2˜owaƒà�ƒg ƒx€=èƒi„^%„ h} §}¢ç‡¤G�¨Vy‚�NövO…PH…h…ÿ„…Zx{\è~^`Ø{>ð{‡gøƒW¶†4ˆnØPЦX!r˜t؃?((“òaS�h!�j8!‚8ˆAD£¢c𥈋ȈôE=\dD�ø5¶7‚åÒ…Vka†{‚ãµpŒ'+в{(6üu“—ЦhŠ.’Š«ˆ€­!zرørkQ °ŽìX‹QHº)¼È\¾˜ÀŒÓ3ŒWÈSrsŒ[˜Œ”¸Œ‚ÖŒ˜ø#Ðhs,VlùG�°b�Çq8GeÛ(‡ÝXŠß(‡á}ã å8„²(êÈŽëèŽ4�(´‹¨B_õx�ð%Œ[DŒühŒþØ~W‰SF�bÿH% eÒH| Éiy0qwÜX‘©ƒ™y y�!)’$iA"¹Ž:•Qñ(óZ+É’¡å’-ÐRŒHã�’�§òlÙ–ÌH�{2;ј� ·�GP�1ø�½s„uwFI‘H "àȃâx‡®¨$æ¸4QYNÅŽù˜WéU?‘™• °•nÒ• õ•`ibI–°‚…"ÔhÙw£Ò–n9�py&r‰�™f—xù‰z‰�y}é—Vv”ݘ”;X‡vh%’‚˜‰Ž_ј�阑9™"R™Y‰™m¢™&À™`ù™ )š"Tš$xš¨ùoÙŒqI9sùšÒÿ›Cèj¡/²}”@£)@òrS6†ª~áwxà\S&>Ý1?àtlØìµ: $TBF´s ò Â>u&Có7¥R�Ðg5t ÉÞ¶'âE_}‚…Þ ¢Y0¢$zU–uˆØ"‚…Aé>¸bz|�žò¡žœ„Bí9=×3|ñ™‰«BŸmrŸg–ŸZ°Ÿ’ÑŸÉæy: Z Š ¢ íÁ E%º2¨"¡™G¡ït®’¡g²¡ðÕ¡<õ¡! ¢$Z¢Lp¢X—¢Ã ,š—(ࢣw!£àA£½d£"äž:*-òI>jŸø)-úÉü韡hKÿʤNú¤Ýã"RªTúMÊ2:Zzx\*l^Ê%`J%bÊ\dÊQfz¦i:¢&ji(ºzt !+ÊS-*/º˜m�§Í¡§Ù”@BÖ󧲨ƒ ¤™&¤D*FêÿÉ�J $©‘š “ª�ݳOÐw¥ji*›šuVS‘ÞZ_Ê[špôõ Ê[g ¢;´ª•Öªõ©¢1§²9§´Z§¶ÊúRúº¯ºÊ=õØ«9Z¨ÁÊ£óyˆˆH¬Åf¬ˆZ¤Šz¤%ѬMJB tõ(©ÓZ—Õ*J׊©Xz*ÛŠu®ò­®�Õvä _æZ¦¼5,۲뺦¬Ú¦® ¯òztÿj§v‘¯ûª¯ýjÿúC¾úž>9°Ì2¬{‡Š‰ê°eÁ´#±{P [±Ò:­Fd­™‡­æâ±¾}!+²¦H²_e²~V®íQ–øäm-벒îJà®7§²*§7{¯ká)в³ú:±Éò³§â§G+¬ëª Ÿ†:¤ ‹¬ ›¤ŒšV5*õ8µõè‹‹±ÜƒF㱓©õ¸�ðµ` ® Ê[d{,ˆøªÂÁ;•¶ øk˲/˦à¦Â!·5«µJœwÚ)y«·|›¥¾°¿¸+¨ƒ[Ÿ…;´H‹¸J˰N«Ï›jõ¸�¹ 4¹¾8±ø—±=�¹Y˱ÙÿZ*[ç¹  ¶bëU¥k,§û ª«ùÄy¯;±³³;³o«·K·õгu�·°¢·5ð»\«ˆÂ+´vy‚ë?Ìõ£G›´ðá¼Êº¨1½¹Ù{½Ø…ÚËcÜ뽇§µÆ’,ã»�å+²ç é[ëÛçJh0¿óÛ®2û®÷¯s;¯u«»9Ë»ÿë» Ô·Á ´¤€Z¼FKIJâÀü§¸Ñ»¬ AÁ `ÁŠ(¹œ;šW{FœuCÓ<^ƒx!|.Óg}}îé"V·Ð }xþƒubÉ›˜¸“A<0�щ„ÁC:4Ð=£¹Ð }×qÉEÃ#d9a$ýnûšuN8Ë®bDWÿPÓ6�'jåf@°ÓNÐÓÍ“2åB$ë�ù$DÙ«ãfµµÔq¬£é"Ý“O5me_PÕV L]Òk Ð%ˆ*mÐ�y "±ŽaÑ‚)‡-�Ñ�HMjý½ÊB_-]Ò–vÒ[”Ò¯-,�yDôÒXÓ2Ó&dÓ7]&9 I; =í?­2Æ"ÔÕødÔy‰Ôªãfßå¶ÕÜ#ÕW`e‹ôËYM×!�u[›,_ Ö¢,Ö„Ü.RÖ„yÖù¸Eµ=ei°ÖÐÖn=×sýfuýÁ_y­×JÀ×à×+�.Ð7Øú ÓƒûjŽ‹bÿäÐÚ^í/° =ÀÑNÖ‚¶ä éÀEI~þÀ›åÁMåSjåÆƒåÆ½ÚÈ}×ÊÝå^ÞÜ`.æK@æ°¢á¢ÄážÈ Îæ"¾ÝŠ-ç Þ�-Þä]Ù.~Ù£�Ùê½ÙìÝÙî�b8î/‚NÚ¦ýXM,pínF¿¾¹Žþèé0Ö^é·M๠›ÞéÆÑ T"å¢N©¤NnÀâf“&Ò¨R$xÍêÂÖg®Ù²Î´>H¶^Ø×}s‘Ýw§¾ì*~ç,Nì/>ßš-›œýžíì€~,ÑNè¥mßÔnQ^qí,�ír¼íüÝí�îâîääîÐæžéºMéÒÿ’Pó6Ïî?âî¥Tå3vå(Iõ¾å÷N$Xˆ…}Âï`~Ø=ëf^ëh^ÝÿáñâøD  OçÁnçÞçÅ~Þ|®ì4Îì6Žñ•–ã²ãßã�ÚÖŽí�¤íXÂàí—.ÛH.óJ^îL~îénó7_¥9ê;?ê=_ê?ÿAŸêÉR$EÏSG¯mIïïKðM/ðOßáQ�ëS¯ëUõ›‘õ(^ç+~5-ñÇnÏtcoñÍŽX  íò�ú…~èb!ò$ŸËŒ_*ôÀzÐx=›~–Žéš®÷œø5�óhb%ï>©E¦¾ø&?ô ðøù57ùÚÿñï�F¯æ/Ïmú�Ç'žâÂŽçzNÔÈ.ãbïçfïê�>ûƒNßkoèm�ßJ,> ¨Ä „ ,dhÂáÃ%r X±ÁEŒ àˆÏG�GDŽÔ£G£”r<Á%H�idΜPÓfœ9}ìäyÃçO˜— %Zt( ¤IO,eúÅéS‚`LÕˆ�áÕ… ´àÚÕ+ן?S¦¬PöÂY£KÈ�©Èaí[29s† [WbBƒy•<<{!(¸k_ &,Áðá‰/`Èc'‘[´HR9IÙ²Z/µÑ¹kЄ“ž!ýÃtÔ'©U3a¢3æ¾};Ûèzå ÿáL™’æ}F±bÁ…'^ÜøqäÉ� d5oU X<„(1b[Š3Veé1èH’&Ž]ÉÑ%„¿3iÚ¬)'ÏžaoüM›6©RÝ'žB%8téÒŠ�¯ 4@¾ÆB 6´ŒZ«­Àâr¯.»"ÂK¯½êë¯qì0Ä~ €±ƒL2Ê,{M³8óŒ+Р)ÞLû5ÕRc͵×*ˆí¬Ùj»�°üNè�4PnI&›(£\cJ*Õ°òÊ+`‰¥/O¤)¤ :è¾<;xPA Vdà¢âŒAÌàÛ Á±¢Î¡¿ä” @g¼O Bï04ÇÔØÿp@ькˆ,³L#[JÎÅÐ4NcŒqPC} ˆÈœ`­µƒÊ; /9g‹Ñ¶!_¸OV°õÖá0À@^UCq2èÉÏ8a…õ>¤h•Áƨ¢*µT6ó�ö¼´fÓT eEê°[quò[p‰‹RJ*§dSº-9êÒÌÚu—N2«2M5µbÓM8å¤ÓNòôwº=û$P(MŠP) ½C%¤[T« Ò$­ŒÒ77»4ÎL7íÔÓ0BõDSwLÕ.Ïjµ³Wm3˜ÖnmÍu×^Sûµ…`µ–XcmCe™mö�g#‹vZ—ªíìÚl“â6æp£w\(Ë5ÿWAtÓ]÷Kwß3^�æÅ®^îÅŒE?÷µóß<÷4A`? 6)„fØá‡#ÆîQH-NcŒˆÂ´k9Mä�EžaÔRO}NUVãt4X_®játåU_�˜ ت„ýˆØz¾âç Oºh'ŽÎƒZ£¬Õ´ém ‹y©sg’j¬^ã\¬Ò= @v».^yÍü2æ›'ÛìÌ2N[LàÙÖ3à H—{°Ÿë6ôn¬f@o'îÛbÀ5^bð0 ÿØSÅ'Ùñ“S¾`eZŽuÖË»�yóÎ}g¡ÓÙèxÖ3ÔÑJhÍBB˜%i½.i±[Úì<ä4ÛaNw4ï|Wÿ=†�x\3òÂF®5Ïy;Y“‚ðÕ€éQ„Ö[ˆÛħ½@qYÞ[†ð¶(òU„oÖñ[ú,µ>ŽÎc)ø™�lĸÈÐO Q—Ê$Ç2ʹL‡Éꟷ‚£¹š=áf9cÀÎüdº.Ku t`!ˆ4(ÍL»`í$p;æQ\Tû Ö‚—®‚ÇxÇûZòi<2ïy.<›ôôE=?Ò°!{ºáÀr¨­Aê{> _Þ#1¸P¬ˆ ©”à’Ø¾%6щ?€bÉP5EÈY1“ Cå¶´.Ê,s4ãœÍ<÷92šQNhDVên4´6º±G„�‹æhAÜ`ðŽÔc£*ÿ}n†`‰œ9’AÒiã$gñR˜H~A¯h{dpðÎmZφ3#Á6|L“=ÔËAB¾½E”è#eÆŽÈ>÷1Y«dåüLK�Dn–³éŒ-1‰Ë§án—ô¥'…�Jž�ÅT­†ö€d"á�̃gC»ûౚz¼&A²9™mv3NŠÐ ÛðS ’³œ(tW"s�NFF/_qªË;qO¶ÍsQõ´'ð9}&l“ýìd?Ѐ’Ac%ë(AjPSÆ cb0œ*�ØJ)BG¢­¨/J«Œþ/Œ7û¨B:Ì‘ò¯¤îéAJWA—v¦I‘éL9XÓÜ´ÿ9åˆ7¿ÒSã5¨BÝ�9‹ŠN;©“�L¥‹S¡ú/©ŠªêU³j7N^Eµ` (YËJгncjU"[9åÖ':ô•r•%]m`Qþåu£{ýådúú×b6)%¥a »L–¶”‚],RëXÝAV²”=€e½‚Ù®iö§œí,QÛeT~ùÇ?/Œ¡i#)ÉÈw*⣪=]K·}‚O¶Ì')ò–1$XÁ¶ë©NeÄ´®µ­ ]%\JÜû]‘¢È�® ”ûE^ðsÏ¥göˆuÕ«RWÖMæa¥Õ%ãV iTx %lNI›÷]ˆNcÀÓÀøT½ìõì{A ý€¾íÿ´ïX¬Ç°$ó×€1�ñQÀC ˆÀ´Uð‚ì`Ö@x·þ-…ß*ÜÇE´¸tå0? 0öRŒÍMÑßÎ:Uû ÅøT1‹Ûèâ<À˜®2¦1­phDÛxj8¶©ŽqÊcnVv§— rf‡ÌÙ"¾vJò’IëNxBZ:PÖ¯”W§*çÀZåg^üùU»e-]N0ƒuf&ˆ‰¼E¥oz†Zx¸U™+›íšÜ jÄ�³G/vgÕ 3N{AŸÝsÝ×d7Ð?ŠqU -D'ZÑNŠß©TT-/*ëf7š<ðnxÉ7"Õ¨â'|ç[½m0šðïÏA!]"@ÿÁ žµ-‰Ï g8›ÈR–ó4s �9BUëbð”$ÄmêS˃ïAä£Âµ¢Lº#æg¼¹•®0ªÕ°†MïKZ—Ƨ$‰D› U©¸‘³ÑÎE¤ã6è #³‘ÓH~Æ¿ d Üã&·âÌ]̤{@ìn7vàï#%©Þ�¹w¾ñ½ï~ÿ» 'ö�¬'<…3|á_Ä#G¢`Ñž/xƲñ#vœ-‡KÈGþ˜’+Hµ¤ã \VNš–ë æ:’¹‚hÞ ¢Üœ¤2ȹˆvΫžGæçU ºÐ'JQm}OI—ÏÒ;Ót‘<½ÃQŸ:Õ™TnÖœ»Z× ××ÿíî¯{@Þb{ÙÍŽv‚ŒJílWslÞž®¸Ë�îm²{Ä]…”Œïð»_”·äÔùHf“{õÔ~b‹Þòø3Dþå Š9f^ðšEó‚íüo>¯‚Ðs‚ÑÓˆÒ:ãJ½ë¡Ö ׳Ø;Ùã"Ú7ÛSÜcÝã=𽾯>Ï#Æ0¾|ÁÆH¾ÇX¾É8 @À3‰�éÃŒ»Ã»¡è ( í£ ŒC �ÛŽ ?Â{ Ã3?ÄC?Å;9b!ƒ÷C–³—›¼'8•û#€üË<�Á9§Ð9Æà9Pñ9 ›„0=?9ÀìR=¬ 6iÀÿ$& ”: ¬@ä¸À ÌŠ‡á@»ÞðB$A|3ÁAA¸¬ ôü¤;¼»ë#ƒŠ”íë¾ï# !”µÂ#¿Ã‚Ä‹Å[B1ÐDø“?*´BËÃ?Ì#Šýë0ÎëÂ\0œ1Ô 2D3”mKÄZ=6T7Œ“‘€C\šÀC£C ´ºÜÃ:tÃCuó½=|7ô?DÄ´3Ä`A^ �E�Ft¸G´¾¼³@9‚0 Dì;ü; ¼LŒ�"(�Du ƒƒ¾8‹ ô8M$ c*?z<ÿH èÂG2ƒ”#ƒ Cy›Â¬BÖˆJ”¸¼ h&ÄAW4¦Å¨FÅa˜†¬ ·q›ˆd)5|¹›;`¼HŠû’�”�ŽüÈâÉÉ+É®:ÉßÕ|7–, —ŒE˜¤™4Ál\»CÔˆn”�dDž¼ˆé Ä>2€‚í3Êw?¥| ¦äD#Dy°Ô€©| tÄÊ2ÓÊ#áʨ¿×Ëf2*³mäFœô—ÌÇÍl€ÎL—ÏÊÑtËÒÄÄÓŒÁ˜ÇÇhÍ׌͵°JÚüµ­ôÇÜÈÝTűœ %ðMB9KjÌQK‘)Γ!Mät唿4ç„NéÔKéâH9ÿ<-Ñ=UÖêôKf“¢,Q-›‰Š + à”µ=ØœÍ)•×L‰½ö�Dð�1õ�‰$ƒ–‰´(ƒëAê«Q帡(�Ÿa HZ– £«“”„�¸‚˜Šº 8©úó¹€´ “la ª 7ýÖøa�é+[³M‰œ(£¢Š£2Ãy³fíØ‡úX Y‘Y@)Ù9Ù”¥º•]Z—ÝW˜�H‡�Y› Ù‘°Ù›ÍYîàž5 ŸýYî«;¡=\¢]£E¤UÚ¥½ZÜ‚Ú%@œ©�:«H¬5 ‚\®õ¯íȰ ŽÛ¢9[Û¥»´ýе“¶ Œ·…Ûÿ�Û?¥ÛW²[õÃÛ3¡’M0“•”¥•]Z\‚…4À›Ù/a\õp\�ØY¡�ܯ ÜÊ Ú¡ ¼¢ýŠ£]Ф¥é]§EÑ%Ý:Bª=ÝYM]YÝÖÅ�×íÓØ€ÙU²½]F[œPÛDb[÷pÛDÞàM¶fâÍ ã äÕ[(àÛ8Œç�^Á�Œ—E‰˜mì­ÙªºÙ4à^*:€È-ŠÉýÙ‡»\Ð-F_ÎU_ÏeY÷í«ø•Úù­ß¡ÙafÌ_­5Šý%’¥øZ°MÏø‰Ÿ~âÜõŠÝ¥�Þ…‹ß…[á]Ñ 6ˆ þˆ VÞ½eÞ¾uÞ¿·ÀeYêݦÿëMÜì=á›mM�…Üï­a¯ß.ßžµáûè\ Ø?þc!¶3 ]Ò)ݪ bÔµ˜¬ÝZ1éÚ$†]?ýVÞ‰Ÿ±‚'.Ûœ¤)®‹*~‹+Ž[ŽààØb%èb<øbXÞ1hÞç­=Ç:ã–aÂaÃ�afc¶'†ãÇeá9&ŠZÌÀcðõŠô=�õýc@Nä÷dM+91dûmZÝËÂr´�ºpäPbW–ÝIVœJ¾äéËdDJ`Þ]`ßm`àͨߘ[¦­ÛÙšY0Î`1Þ`¿¥�n®&ø?ÖyͬëEy½åšP\‘ÐÞ™hMXèf‰f ®‰Úÿ”¼ƒš4HØ"Qf?nͦ]@h>¥¹QXÉ‘¦Í’,tÀ9¡‹®@bÝxŠ9ào™JΛ¾éK&,M6g*Fg+Vg¸½�vÞw.Þx¾ÛyÎÛzÖ`FÙ}¦).€nF€è^\7V…fhUqh…h�h0 h”°è´ê �ÎŽÞ�^FANˆŸi^ie)i÷EiÌSéºhéÁ(˜þߥJ»›¾éA$öh÷Øi¢³Ã7öúdNjà j9óØ£>Þ¤NÞTãUãܨ~–©Þ=�Ú«>è¬NhDYhhhóøê ë‰fDZ0ëÝBë EŠ�æèÿ¶ÆÀgÓˆ¸Þ-ö¡k“"ˆßÖ½E :áëÜÈ�¿Ždolp&ìÂ΂Ã6žÄž�.çÆ“Ç�ÈjÃù.w¾lxvÍžzîl{þl|&cèí/ä•Þ×€®jÔÆe¬Öå7nm®F™tyèÙk²ÖÜÞ5Ý>SÞVkßF”�®Šá޵⾥ƒ´kfÆë"f]1qn¿vŠ˜ìqìz»nìÎnwÙîî>§ï¦�ðf/ˆq¿ó¦Cæ`R†;¤fo¥vo¦Îg•í4¶\†(:ŒHí#È–ðÞê×îêØ¶A°6pÛ®èw¼è㊴Ö�µNîà†kŸ�ë1nÀðûâåæpÿ ñpèqÀžé‘)ñëFñOìw„A[{qÎ’ñ§qÿ±Îˆ‡¾ooUfå2V´~®ïé•jü¦j#GÜ‚þ%l&‡í–�mÚˆèÚ_*h+_püÐò7i·iâi 'iä†p·Öp¢hn®pé¦`sé–iê¦ië.l9o_lã¹sBÉódžq>?ÿs¿,iµË‹Âf®@“¦[IðJ‘ËÐYm ¡Ÿ áÎh –¦mŸ<S‚o?JlW ž8ðFêNÓ« 6¸w|ïa/ ~�(ÔØ®„M ¨ˆ)Q»&P÷Û>J<ˆ�/Ñ-Øãÿ¥€i©aŽ&VÈx�1A:‰�y—s9é=)Aåã`ösvZ†vù�v ö³v[ÁvÇÒö=àöt_w‡wõ÷Š(w;:÷Üù…×�±Ü.xß y�z:{Ç÷{×÷;ï÷’�i��ßíû(xŠ8øfçy8‹†çŒ‡�øQ§ø¨±ø‹�ßø¯ �“�ùâ(ù¡Ay&Qù„7ˆg�öó�yì¨v;ºvÉv!ú5úO7Ÿ?" §¡G�ÃP|€ôö£û¤w¦¥÷�¦_'­0è—zªG«÷w…Èú€w¦�G ¯ç°_y±'{‡ˆ—xýñŠˆÿ¶wû·Wާ�¹§�ºù»_Ú“Òû%á{–׆|Í�öÁŸùÂ×%ªÃy�w±ür$÷›5÷œGwíÏü³h÷‰ÓÓxŸrËѧ ©Ÿúö,±ö—“­gð® ƒ_„%4aÐÄ… x–0dhãDˆZ´ ¨ˆâÆ/èèñ#H�,FÎ(iòdI*Whé2̘afÒ\`ófÈœ:wòìéó§ÎBŸmbT R‚–Þhê´¡KR§Ž©jQÖZ�rÍà+Ø={Neb–‰@‚šhÚàmC6¦rHc÷îU¬bÉ>9‹VíÚƒ !4t(7¢�ÄÿÖPá1ƒÈ1&S¦“ æÌ-Jéìù1è KG“™AåÂKäÚð¼¹â‹ØS׬1z0Û„ ?ŒxdâfŒ'4~áØÕãH(—Ïêü¹óäÉ1P¯~çñìÚ·ïtNô‰m¤i5Œvú”aTºªŽÉ+Aë î\Á†k²ìÙñº…k˜î]xU„•{Ý×W~¸ va¼Qb>,F@c �V†—e†Ùk(xöYh¢•6â…”©Æšk¯ÅöÂlµ…§ Aº�èÛoY$qÆe—s(A÷ãÒ�T�u×- ’Irå]QG!5ây…¥W—]Ÿ’=Ñ÷•�%ág–~�Ôÿ”j«Í5•€›Øå _þ¥Vn žøàNXaˆ%b¸çdøù§yM…(∤�vᜭu6£­Ø¢mM„çnqÑÜ�m”¥GË ��,I�‘Grzê©L‚ç¤P’©Ú”iº‡%ª!m›nNÊß eÊ`•¯­iŸ—‚ #Br:Ø[�Š1Ø zò‰áŸ€:h¡¥*Y¢ž1:‚£²IE[¤»Æ¨ÐŒ¾aZŽ›žŠ¼ñ~ú\¨£bPj­ù"©jxO–%T-¡¬šYm¥¯G·æjì›±õªƒÀ¦a¥^Ķɰ¹É6�v>«V´’M»gµ~z¶Ùš¶m Ý.Úÿ(lâr@î‹p.X©C—ÚÈ®¦Å¡¯¼ó Uï¨ø"|tWü²êj¯° ,•¬Ò [¬+²s,1Å^�1²ƒ%Š˜³B›§È#WV2'§¬òÛ¢æ²߆Ëâ¸.Þfó¹8¯¦sp=ë˜%Ðð =´�ö�4ã Ž€Ò’úKÀè=MåÄÂN]«�{.è¡/ìWÆZÿ7pæ{Íéa+Ë1³› 2Ú¨©½vÉn‡8¢xâÉÝò²ÞΣy—ëºßÌJ´óE‚ÿ\øáA&^´‘�[ïÑã‘‹Çt™±<ëÁ§zþyè �ž ßm51ê]Ÿlúb/K¶„²í·÷™ÿûµ»—Ö;R~G7»Å o3Ó›¤�—®ˆ¬«yÃq§²w8¢iq×c\©Lb›pÐal1Á[»ˆ¸dE R–ì”J,.ÜCù@ס †`¸acr€ò°LPø!×C|å$@B¤ðô˜^`d.qIÙî˜塊Vü ³ÈC6Æ^ü¢Â(Æ?Õ°êáÀ¡°¢uæˆH4Jâ(G1Æ„FGHc;ºð1ü# ·“Á’l°ƒûaKG‘Ææ„I! Vxœ¾†1œalÊxC0äp [Ü¡�¸¼� ±ˆ&9b϶Ä4qZOlIí7*Z±ÿŠY¼åA>y€.~Ñ‹b£ŸÊxÆ4®‘�n´�çÆ:Ò�?Ô#èø˜?²šÖäÉ gPÈx‘þ1³ùGž’’ì %_8DL¾@“8ì¤.C … ’2†¦, *m£Ä 0щ¯Œåì”RšZÚ—·Ô%/{ùË0’±†Ãüa1?tL8&3 t„‰� hÊ@šÔ¼&HCšÍmvó ‰4L8[bBGšó+,4R%÷°'vº““ðü¤<éi‘RÀˆo4Ê>ûéÊÖoB�å@ jЃ~ò•è¥/ÚP3ª‡˜±a£&Ú„ŠZt™m¦39êÑ�’õš#5 ¹yH“~“5$ÿTi#YªB—N¦•ÜSòªWÚð�9Œ§jÒ¨ÓŠðÔ§©¤Ý*[É'§´“j!h–ªÅ¦¾ª.X¨¦úP5^Õ˜ùÜjE/‚Œ†õ5{ìcYS ȳ6!­%5ÈIÁùV¬ô„-ý(WÒéB¼ê5¯|-À&«Ëj1D°£Ü©={zÊŸ¶ÖµŽ�PKT£Ê2‡�•,uéTËbV³U…hg%úY®Š–´x+jU«ÞÆÝDƒ‘jBcØ*BÕØqEµõÜ­–$”R…0„¼ímËèXèî�m ŠHM º0øž3øls šè>¡«�ëb—-v´p„|€Ù×°·¾µïÿ °êF7r5&1a k¬ú‚Is¬ë½1ÂÚKÈ÷ƶßlH}Q,ünI¿Ð’“Üß·üW¯$.À€Wy3ÁÏT° üC8­j�0+ýùÄÄ`¸º�á°A7¹É5Äx3œŸlâ øËYñiBÃÆr‘q-è§dž>•޵ÉcÅÈ4ªó�;—_ 8'ÉJ^r“óúä(ó³À~*“•7Še-s™¹A óPÇ|á·dرhÆ¥šoÈfU»Îo–³‰ë|g<ëy&|�ŸmhAšÐÓ<4²³”è÷—Ñ?®ò£…Œ"ÓÇÈ–Fò’�élº“žò§éÿ ‘o&t¤V.>M­ÊN+¶ÂD-óQs@%`qÞ±ì¡bØúÖ$ž³®Q‚g ô: ¿ö°‰mlÜ&»á/]€{ÛÍFCÛ7�ž¶¤‹Li¡\[ÙÞv·søí?�zÜW.÷‚Œî«±ì³¾á­á�Ì6¿¹½c�oXî»ßÀuoîÓüà~Nø  Íp‡3ý'Ë^4ß(¾„ Û7Òn˜ôO*}í�chÎ!W"I.î;ž¹YV¹aõ¹n cÈÂ2ŸyÍonóœ«yçØ7¿û ô½¢x×DïµÑaŒôb+½é†ÿ x´ã&ä')k•Ñü Ò™¡ tð��2¯ùÿÇé óžÍh°˜� ¼ØÏv=fÅ(·2|E9ì!yÐ~ÅF1K21{š˜ì‰ ¾ÿý“ï]‚á³H8>òŸ¬Ñßÿ^£N=£'"}-;СêÑIÎxÆ2p¿ûÆ><ø»’x’,¾ñã¡ÔØ$/Ê[þò+Ðüæ çùÏ?&ô}éa|ú„¤>Œ«WMëÅÆëÅ^ Í^íMî)Ó/íLôó‘AðÅñßB!_ò‘Øò= ó½ôéÌôU_Ü ö™„ö©G÷y¡…Ÿ úÄø)Gù�‰ã‰I²$�LG¹ßûÁŸpÞüéè-…è%Dþ¹� ^ÿý_aàŒUì�ÿ�ìÙí©€í1äÞB1`8 óE šMàðŸ"�ò9Ó’Á>QªËôQ_õ‰àÎ@ ÒÅ rß÷­ æD Fœù•ä)ÒØ –á î üõà@’^Ÿ™^òßn ëõšë1!Ò€J!V¡ª^dð†”!n’–€ÜâQž¡KDaFß‚ Ž`¨œÖÝ¡-â¡â)¢E ¢_äýáúÝ û bÇ Ê!&"3ùƯaê!aC(á:aBáæSÆ‘îuâWù(’Ø|#8Žb)öÚ)¦Q*:S¨°"íÙK-vD,b_¨ Z ‰:ªÀZžSÂlÉãi”N)•n@‡&LJf)˜º#zri‰žh˜Z© IM‘¶¤M™ì‰|*¨þÚÉ`d�ŒÝiÔ¤ªª¥›S]Ü i™–u­Fár€ã&‘dù\��œæ2G£I¥kÃ]*žeªZ�§ª†§‚ê§þP~P©Ê©:“ª®*«Z€«¾¬ Ç­ÐjØ*Jàê éêñ*ŠÝ °+Jœ¦±Æ+Ó!ëFÿXc0kþt*†@k´òÙ´²EµšÇµâQ¶¦ê¶r«Ÿ½ª´�P¸Ö*íÝê7æª:“ºÚ»ª£»¾«:Ê+Ç"½j•s-ë¦æ«³î+¿BÖ¿DÀ:ÅÀ¦QÁÞÁÁvë}+F4ì¸>l¹Fì¹N,UìŠPêãt¬Ð‚ßÇ~VÈ ”¡4kaì‰.¡li�*AÙQËþÐËÆlÂz+Š-Ü–ˆ+¹ž„¹‚ºB�Ï "ÐÎОí¼ ¦¢•!‰lÒ’ìÒbHÓTÊdI-�8ªìÁÚ]�i-}p-Îz­Î‚-Ïîj¿‘í£â¡Ù¢­ãÚM¬m¤„¬~.…32„.Ím-Õ­ 8•ÿ[ „®èRhÕ.Ԝ͚f®�.X® @lG†-Oj^ÙÍãÞî�íO-R½íidWæn‘Ó’y.�€®è†.éò­éšên¥êbë~…ëÂ.8Êî0ê`íÆ îvoj鮲"íÊ ðï ¯`„ñúò&ïòf+f͙̦nl¬®Òm­Ã¾nÎÆîáþÐìfÞö‹÷0H�/Ûª•†ÉMùš/ú'[¬oD´ïèrçr8•ü^­Ðï Øo�Ùlך„„Â¥�ü¯00 ’ÛëÌ)ð™/5ðŒÞèA0DH°òR0JX°‰Í/ôÖ¯ôÞoàæïi†0J„ ›ÿp /ñõ¬0ïæ� ³ Ÿ/Ý– '„ §…Vð+]0Œ¹„s°GáïÍž¦ ñI qöŸ31[uø�Ô1WÍ?WhPï+iÔœ%oèú*Vˆ+öIè¯]�"/2{°q¥–ÊiþHÐÆ±%¯à ÜÕ±ÜqkØ ðqÁé­3² Ûì!{e"/²"×á%¿2,wD&'{ò'{[ˆˆr¯‘2™rò¢r� 2Ÿ±r+§`,³%ÏòrA-WÔ-sh貞ñrÍ3s³‹ó¸223 +sº1³;ó3‹\.SWÁ!\)›Ø5›q*wd¨ÜÿŠ7ƒ³=ã®8³9w²9Ÿóº=†4Ó;÷²;»6[ï7Îó–Ôó=7ôÙæóÀÙ²?Ľ•á:�3Q€Foô;±¸vBï€BÓC;´IË+Dãm¬ôL4`Tô^´àeôFktG·îGƒôþ‚ãHƒEIŸ4P‡iJ¯KÓ†K«L3ŸLÇM×ôMSoN‡tOÅOµUÃ$uät \Q¯�SùsRÿÞRÿYSs´A›±¸†„VOuTõU¿õfuNsuQ;ÛàÝœ…µï�µ ÌaÔ´MŸµG§5H¬µ�г1õbÓ£\4]³´]— ^›˜^“_û5`SÀS€V«ÿuN³µ[/¶hž½´ëIPhÁmdýÚ(¿R¼6lâh϶h›¶I v¯©v ±ö.»6l¿¶lÓ¶p_µm—në™noO³oÿvp7t›tqÏÀqÓDr/7M8¥F7w7ôrPèi^7ŸµömwwŸ727w†÷>vÏ„v/.zÏ7Pƒ7ƾá{‡ˆÒ7[õãL÷rL2tìw¸Cÿ÷}� €?�¸ƒ3‚³b°.¸s4øƒ_ø+Gø÷… ……c8ˆ3±†.öuø|xˆ§ø=?Ž©¸‹¿8ŒÇ¸ŒÏ8�׸�ß8Žç¸Žï8�÷¸�ÿ8�¹�9‘¹‘ 9’'¹’/¹Œ!ù,NÅÍÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹ ØÈ�Ç�ØBŠüø1£É“(Sª\ɲ¥Ë—0cšäØ‘$‘#mÊÜɳ§ÏŸ@ƒ J�æF›7qbCJ´©Ó§P£J�Ñh¤J—ê¤Êµ«×¯`Ã>´ŠU)S±hÓª]Ëö%Y›Y϶�K·®ÝºoIÆÝz·¯ß¿€‡æi–oàÈ+®8Øã^’‹#KžÜתe£2kÎÊ­³gÊ C‹öz™f™Ó¨5k6Àºµç×°;Èž=º¶íÛ+KsD�Z5‡Ö®a ŸM·ñãÈ®XÎüŒóçd¢KA½z«ëØ«W߯½»wîÄe'ÿO7óæÏ�KŸ®=öìí¿Ëß¾Cùûø'Ÿ_ž^ýz2í¹÷^+Î÷]}ù%¨ `û­ÐßÿØÞ€­´cá…ʇà‚vÈVƒFhˆ$2bâ‰b8 |Âyèâ‹_�ØŸˆ$Žx"Š)¶“áw-Âèã�Nɘž4DY£�72’£ŽJ×Ýpâ)å”2±cå•Åd©e‘F™¤’9Rè$wPÚGå™h¦t%–ZfÉ%‘Gšðå’bF÷dlQ¦©çž­ie›n¾çœa6i'™xšÉç¢|Z•Á£�úɠż)Í IÒi(w¾V£ ¢é(¤�JJ©¥˜Þ¨é{cnSf¨°RÿIì´JêÍ­¸£ë¼öêë¯8+¬<ÄÛñȲ¢l§³•ë³>ÒZ«Ÿ¸æºë¯Øö*ì°Å‹l²Ë"ÊM³Ak®‹ÒÎjkµÞèJL¶ðnl·Þ~Ûƒ²¬0+›³çö›`º4¬[­»ðf+/ôÊcï½áºÚ¹ø+1~wcñÅ–\ð¯¦tìñ ‡¼0¾úvÀïÄ(WñÅg|íÆ½züqÈ �ܰg§¬³q+³l)ÌÙÊÜ1Í5Û«ax;'�›¤,·ü&ÐBGm Ñ,|4qJg=ÓMÿ ³ÔBSmõ�Hkmöd\ûüô¯å´í6Ø2‹m4ÙXŸm÷_ ä­wÚ¯ÿí«ÛoÃ=4Ñø’L÷§Œé@6Œ7®Íã�GþxVwWî�Þ{ûÙt7^ÿ x9‚Nsá w·¡EŠ/Þ8ã’·® å–ÇžPƒÔnûæä®ûÁûôî{€/úQŒE$c•Á%¥ñ�™À %w27ú ŽœcïêxÇêäñ‹{4ŠÿHAl‰†D¤ÉFF–Ë‘ƒ¤ @Ç,V’:—¤ 9²É>òž”(s$ÊQ^o‘‘k$*Í¥JJr”üÏÕf£G‹<¨–l¸e.·…­Pö2‘¿,e0Oi®Æ àtX1‹¤»Vö0BË”M3"¤ç@Sšd²’]+eÝ*ÔËö*³›-Vg�ú¨îG´¤m['ŸÔ 6„]Su‡Xw$,j>È®v7ÁÝîR²�ËíšØZÙ·úvÀ=RfÍ×»îv·£Œ ­Ÿ’«Ü,2÷;Î]-t[+ݦÁV¥×šv·ëÞM|¼Ùï•ÈË[¢ž7½5Z/{ ¼ ø. =g@nrëxÈæö¹É\»ñŽ›ø`–Ù€³Ka ²}­Óéd{ZÞÞ>X®q’°ù(Ü*áˆdOÖ0i9œF_Äñ•.fâË+Å[±Z< #/Æjïn-{㣲Ë:ö�å°×ü£üáï•èk";ÑÿÈXM“U”l%&7ù(¦vWLå÷XyuXžq[¹ìÛÌ~9Ìí-p�asæ4y¾ôuó½#¹ühÎyKÛ�ñüd= ˜Ïvq�hÝÒ¸Áç!VÍêCË•½û3§Äå™Fÿ¨}�^›%­F(zÆÒ>Ât4}ç/%+âÁ. VÃ]ÂòÝ’´£,ÓjãÈtI]jëƒ`÷Y°ÿäÍiðÀò–oºK&ø†ÌgŽšÛ¢XÐä.î‚ŠÞØ{çsèƒvˆ‡zH„}ø‡%ˆJ8ˆLH�›`�…¢±p¸bèDYø-[Ø…ËØŒíðŒë�d8�ÿQ�íq�È“�Wµ�ÜH ß‘üŽ<8x¬áŠå‹B8‹{˜Ž·ˆIØKx~M�O8�¾°’,ÙEp�–�1´�ÈÒ�Éh~ÿ)�bH�j¡>ù“Ôh/Ö¸‡®(Ñã�Ü(‘I LÙ”ið”P9Ž?ÈV–2Vy•çX„˧ŽïÀŽ"éŽ$ �òˆ�Ü �wÑ ,Ù’]“Ú%“0D“Çb“7‰&X‰)u‰éÇvÐRjá~ù—? ”)” I”th”ă”ݨ”8—Žù˜H™’Ù”N •O)•˜‘\r•XÉ‘èh‹Î’¹øŽ…Ø‹Ø÷‹g¹i¹’.É–Ùå–™—= —%è;9‰‰*È—iñ—€˜Z”ß2”DX”°q”µô�ɘqò˜�)™‘I™Li™—i‘H‡šY$œi•Y¹€šë’#iu»ÿhˆe‰šk!_kB5QãC"²ø Õ%[y·iïð%Õ5 øÙ*%#VÑ ¾© Caþ·$KRGQÓ]Z²iÌé˜ÖwØò%ΙÆ#Z¡9p¡jœl`gM–sá  *=•!ÓùâpdbC¥;!êÑS&ˆ“èy%T³ y'í9"5Ÿ›fŸˆ…Ÿ³ Ÿâ£MÑŸûñŸZ`J )b Bƒ Y¢  Ú |÷ IB‹Æã’š¡‰ÙGjb¢"Ês$ 2&ú)Zb+š;- |/š(F*3j%5º 8 /ð‰Xò‰{ôYŸIrŸùIfûHzJj/ÿ |Nú¤Yt Ü• wf£VŠsXz#Zê\Ú¥9 ¡aZbcú¦àp¦�¦(êZ$ƦBÅ¢ ê¢Ä£y¢uÊwÊœyš-{š‡2Ç£`å£w¤^%¤DZfs*F៾¹0¹Ú+qR Y´$RZ TÊœ—Ú¬¼k›ª�Ú¥ j1›6ª¯j¦OY¢¬q¢Ý±¦ïЦ@ª=§žR6çy\~ò öz¯6Š­¾²«3ç«-¬M&¬*E¬†Z¤³êV>µóŸ¨r$‰W#ØRGÒ:©SZ©UŠc¼‡-Úº‡žšÝê¥ÀáG¡úâZ¦¥Z®hz®jªª*Úªn:®�¯8#¯´J¯kÿr¯øŠ§«§:ʧþÊRkb›R;k”ö0{¤F¡°À°‚²³û µ½"±92­Õú˜× µ°æ;´Ø±{¡ßºªz$5G¦#в§ª²©:bÊ®îÊs2‹´u3¯¢fV‚³öš¯R‹|=;mÁ¢RþgM?:¨D+¤ø·åiž@‘° ë´\¢¯úQâé^A˪G¥½²µ½ÓµžúµŸú¥›d¤kb÷:‘f |æjèʈðº°+)›¶C3×sBÚ|�»Âá<é¹v%xû z ±�‹ƒÆË·Ä»1k¹€JŸ—ÿºi›Ë¹žÛ¥ «¡~Dºö`ºöŠºo «ÛºÛ»±ë'³ëAµËs·Ë¹Ë»Û½Û¿{·x;¼»ú°Çû·)¸·7¸Í{"Ï‹¸Òk–AQ½¶s½nxÀ¼2¹¿Ò½Ýu¹ëб5"¾¿²±Dèµ]Ô±èÛGê˾Ïà¾0Ûsñûôûº²{g´+s¶›¸ü«»ÿÀ\1Àì¼Ü· , ì Œw¬†ëн±…Œ{}9aÁµcq×°Ûë¬{›-Ì] œY”B¾b ˆÂéÓ±{ðÆp M-\b§;"eû¾3ì5Œ7Üd9ü ;,ÅпÿË @ì7n›ÿFÄ:ûÅÚ›À8�¼�·¼„ëÄÎ{¸<ž(…ôRWÜF¡S¢lLËÅ@åÅ<ì+c¼ p„pÆw¦±ìU¾ê’4Çq\KsüulwÃ<—ÇݱÇ}lbȸëû{ÈM‘Èu{‹\À�œÊ`œ½~É ¬¼ ̼– Á˜¼¿À!Ó+�LAŸ,E1Ê:UʦŒÊF¼ÁaL¹%ùÁß»i°,ËMFËæcËŠË*§Ëo,Ç¥KÇíkÇŠÇ)˺4\ÃÇ\bɬ¿<<ÈÌÌ�üÉ}Ì#0-«Yaü%–bÊÕ�cBÕ¯ˆ&}Òó�Ò*m) ¸$Æ#Z¡5uÿäÉÒHá@LÛ}Иú+–ÍŘ}"F= HÝEJýÑÚá0Ú¥m§-9©½Yí[íÚíò�±í³]Û´vÖ¹]-»ÝÛøóÛÜÃ�T�$}Ùw6T|­RÏ Ý€ Ò³$QcØ1�Ø2Cµ)ÒØŽm:­°[=Þ/|¥æíA·”Þ&²Þí�>T!ö'ßôí1S}=¨]ªí¬ÍÕ¤ëÕîà~®e�p8][½â¦œ�ãeÃàJ+×M-·²Ñv�$ÑÒ›fáÍÝ×ÏÝ./.4 .ÓÚ­ØÑJOoö­“âàåÕ@ÙÆ=1®wÒ�Ùæ³Ù,å’7þ9ÎçÒðÔôÿÕŽß@®ß«Íß­]ä¯ à`Öc­ä¶Íä"áäO.ÞQž�Tn VN�÷àsá7òåÞdbÞ§^5Û©`Òß’Òg¾-Ó÷á×}Ø"î1$~!èæsÙ*.ÙwNÞúªç€$㌠s½è± èDƒã·'ß:G,ŠÞ1=Ž?^�.ä’Näö€+M¦+Hžé¬»ä�‘žþä -å£^êqMô.0¸a‚-®Èêè]áÌ ë˜.Ö´Ž,¶nÊD’QcØ­¯¿n!ÁÞÞÏáÎ\¬K¤ìbÄìξÐ.í4Cíxgíˆží¦°íÝ>A>äþ]îÄpî´­é´Æîüÿõé ÎÅðîi2S2ÇúAï`ï·‚ïÁB¦ ºïÄæþ¾×25²>ðÇRð\|ð’ð·¼ ÿæUdr.9z3ävnqɇtO<{ÞdD}"ßñ]4èëQèfO$¾7ßò@ò&ïèÞû}ýMéÞÀò.Oà(óäÆ4ÿó£óI[Ááó@f",,D/FHïêÿ5næ�æ9BõxgõaÜðíððÜñ^oì`¯x‹7öÀQö&vö3®ÙìÍÙk?í„^톎èÝB÷ŒÎív�òß®ò|Û—.Ûèn8f¦íþõ@uóǦæ;·¦Þøõ®åÕ"ô80ù•ÿß°�¹3§ùe¾á�¿-i.3ö'úÆMÏ¥?j¾�úáîü!ÍúbAoDÌNã¶oãDlÄSÐ`7„ ¥- ×PÞCˆ³f™¢hÊÀE|µmäØÀÇ�Dº!yÆd?”öTzcIÌåˆûdîsW3ÕÍ‹Xíܶ�ÛOnØ„5y†ÝQ”IûUcÚtÜS¨!V¬ØÓçOŽAnåÚÕëW°`E PöèYv,ÕzkÔÖ­ ¸8䊣[÷È]¼9sÞâÛ÷Ý_Àn¿ ¦J1ÂaÄó/nÚTîcí$O.lÊ Ág™5ÃålbÀgС?OžœÉôi©UgݘÀuQ¥(3í wðÿíožtïÖ{±¯_À2"ÎhæL‰±”ÇêmàÃsè ^Æ“P!C‡RåI¤š3#>ÖÚùèã骟ôÛϤþbS1À§Â$ð>¬XKPÁUÿô£¢ŠÚ² Û*®8p*µ”L35ñ°x:åãS¹J5õÔRQT,V[EåUXI«4Fµº$7K-ÍcW^{Ýõ`ƒudXb±0öX«¬ò`Yf)ôfRâè’ >øÒ°öÚb²ÕöSnùhòpà SrËýî;AÒU÷ Op÷“š$`^zɱ"Ɉuä\3³ä_€ix` Ó¢0ÒFÔQx¦É"q¸ÇÔðûiŠ+~÷];2ÖxÆÌìõ˜œ3ÍTbn²1ùä±RV`€u¹«“OVxfu4¤+×J›l²Óx¸ õˆQ{Cuè1úèk¯…5ÖÉ*E¸Ö'qÅÙWªóÿVX}é²Kg™e6ik£ÜGZˆà$ÆYm·í–-Úv;\qµËÚ´Ó.†]´.6©¾ûFçoÀ=Æ·}›Tu,Ù¸ØÝwüPIž™aÉŽdë…šüð–ÅOÐXãtBýc{s´QE»‹qÛí‚Yþ÷eØ?ŠÙdš¶YœÁÑ9Dž}5h½ˆFõh¤Á^úUYÁyš%[‘:ת}½ع1—¦k¯=; ±É~ÈìºÓ^›íÕµ€Ü0ç_[¼ÏÒûŒ¾ýüoÁÊ—XÃUM¼sLJ\ò…ɤa³žæ>Ô¹ÏeLt£#�éDƒ:»•O ­s]ì`7»lÔ®f6ËÝî‚Óÿ;P…ª`¤ž©ˆg´íÉ[ž7š÷<]E�WÓ;@õ0‡=¯m¯{â� ø(”ºñIð|ŸH_ÖÖ—­öå}ñãÛüèw/û!:Üþ׿ÆATåÚa¹†hsLàCG:�¹èt³I�)È2 ¾ ƒ¼ =ò¡`#Z KuÂ@¤ðx,ŒÔ¤q«ÛäN†3œž ·†Ã¯�m‡=„Ó‹Äò ±ˆú²dÙ±D&:õ“Çý†•?YñbX\�¹èE0b΀¿!ãç̘4:04L›%äºAÄÑes¬]§wÇ¿äq�"¡)È¥ÒB†Dä`¹H«ÿ52kÖƒä²t%ïÉÇkâÚ„x¾M«“íz×ÞBéDRšÒ¨\Œ*ßÅJWJlr¬e)Æ..�v¸e.Õø@6F°|ol™0ELšójÈ|Çø–‰–=dT£~üã ¡É4É8-RÖ«æ7,ålfójŽäÚ³ɤM²l•ti1qSn½K‚ôàiOI©¾š²��îrgüDO)ž’ŠúÃÿ°˜Oüìs¼Ü?ƒ³92dU«½%µj2™Ç¬±1m\¨„а±8”A�™DƒEQ‹^ô(Õ¨5ìzס=ÓxƒlšòFй’ž´-Ts Yº�ðÁôZ2ýMÉ™­›"ÿ§îÚiOyúS#‰C…üÞ9?¤n©©lêŸú?}pªý¬êÖfÙ­jµ2]õ*Xå"Ö¦�uu;ë¿ÒªÖ°°Õv6³#2ã*Wºfô®xžG÷;"Œ¤ÎK¤HAX v›7¬©bÃNΔ=á‹ìdOPYËb–“š½g‹*?ÐB±”I�çhëYÚUžöP¯äçýéZ€þ&¶Y�­½êÛâ·LÑ-ëÌj´Š¸Á�‰{Lã®M®sMîríšWç&M…ÒtËtŸçgvzGú7»ëMI‚—’ã­iy?¥ÓòYö²òêcÓæIPžò•'=cOÆé7Aüÿ]­[Û¥×òeÀd(ðœàW£Ámã-„}+á E¸ÔPqïxÜ‹&w¶FÁôš4 ’¸-&®®_‘b ÝŽÅ.ö±w¹'cñ¾„¼8½1es¬cõª“½@n§g…_r N´Á©"~ï©äÈ¥¶‹ý�%€¯ú¡)WYtW–LX:V…îöÁgˆpÂ,æ óÂÍp·6Ì5³ÙÍ!¾Vœ£û×­Öºx^‹ž�ÄgµhËÏŒ§c“ YBóÇ«Ó1==¬uæ­ÑLìÀQ‰L_##ÎÒIîT�"Uª†ñÓ°¨CGêv˜z— íeYÑÒÛAü6ÌÜ¥!b9Ž=Ã’ìœÿ ~p`v%e¬lœšE)6K�ZŒ Z«ZeÉ$é&L“q‹ûR‰„|a²8«œµ ”§¼Ë�JVOÐøo‡©¨IÙó@Á !.Î "– ¸³bÔ¹¢8NeÀ (l)ÎXOE>`zÓs”;ËuºKEBX“R—¸‚™çÕà·ýý€slàå+øÁ žp®,œáw"Ä+%qhU¼äÏøÆ%ÓñÝ}¼0"—ÉçN¡”«|ÕEiù6^ö˜ÏfæÙ³ùÍ)�s…í¼R=§ÐÏôÆ ½èN?·ƒî“’»Åéž$»·ï:Ó;Uø>rí”<'ü.VNø–~ö‰oÌâ½Öø›C^’å×bù÷�Aè*Ûüü:ŽÏ‹&ôµ}®Jÿä…P=RV·Ö%¤õWƒ=À‘=ÚÓ ÛsÜ;8á½µK®‡‹’ˆûŒ‰+¾‹c¯Œó„ä[¾Y9¾ó;ã¼ê»>“(<í³™ š?œÓ4�{ž»Ê£ 3‰õK™öœ÷‹¿Ð˜¿Î¨?K¹?ëÑ? á¿´ñ?´À}û¬¬˜‹ó{¶z»½Åyµc¥ßœà¾â @“³ÀºÓŽk �ã 9¬Àµ¨>ë¼Ì>ÿÒiÂ Ž”Ç{<Œ<œ<”­$æÀ"Žr¸g&ÞÕÞ8e(Veží`i�.WS©�-îâεå¤eà26×]†Ý^–Ý_¦Zÿ7f8®Wcžcjnª ávæ†f?f^çuÛ¿(’ÓæëŠ“YÀ”ñÞw¡¹æ˜itÎÍKÆäÃb­"b=1âW“gP–ßzf„{.‡|†’áçüõçþýâ€þ ±�‚.ƒže..Z/ÞÖcpÍe‡†`0öe6¦è`¶àaÆàbÖàcN Žö�nægÆ�‘žæ’îÀ@i¯Rinféd]�¡ƒiw‘išìtþaôuÄNì)S³wF”0j´x”ù-ê£~ޤ~â~–âvêüsƈꇘê¨êd¡å¬>ZÕ]h\nè3Nc^c`~cbÆhµÖh¶‘Žž^êÝã>V^ÿ’n[»>éÚHéCÞf˜á¾‹¿lÁì™.ló=ìÄFìÅN®ÆF�xv�yî†ÉÆgR>ÇËŽTNeÍnj­ö\mymÒ¶ ÓNèÌàj2v݇FãˆVc ®h³¾h9îݶŽÚ<æmömºî»î¼.î•þ‰–ök•1óèœævîš>Ë)«�úP³éFì”dìžöäŸÖî Nâæ!jïΕ� ïÏìýÝìó~êÏŽ©&ׂ¾“Ò¾jÓ=í­Ní1fhúkÍëØ¶èÙîo:þïeÞmæã—f Pa“~¼Îã>nENnV—ðì¡ðç¶éÃð�Ðð ïpëþpÿxñØîî6êï¶Çò÷ej*èÎö ¨–ñЦqª¶q÷ÆqÖq0–ow` WW‰kÚÕï Æ� Þà#Çm·ÖmCÖã%ïm'‡òà–r§rD¶ònÆYO' .÷/¯d0�-1g2Ÿn3§«ëF€ ˜¢x—yT‹Vé ¹ø›�Ä(|àk¼ýfÇõé­Øƒ�ô. �Á¨‹É@…slt  ³��Î�NÑ�E“YÈp7^„a±çƒtç€�T‘–„ ·©¹L)<«@@wÉu]¿c^q�&{“�˜Ù~ ³›æw)˜Ä$@ú†oø–íŠ��xÿ o°°u“Àuõð†]çŒ^ÿõW vŒÈb×Þ­Cv�Pv�Ö…pv_§‹hŸö³vt¡¸v´Èö• n�w‰÷wˆ&÷H1w¾KwˆY÷Ùhwx÷@ÑyÇzï {?|g °ÝwnïwTøw¸h‡*ø'_„Ç…?¡†oxŠ_‹?Œwªg^Ç�–¯ `? ayc/yOöe¯â›ÿŒgwyÉ�v+¡ö<™ùÁöÖvœŸè‡9ž÷yûz z‘#ú1úÆ@z¥/G¦—ˆyú¨Ÿz�×÷]á÷hÏúrx´vYaòúÎ {é{â){†?{ÇMûµÏ÷\xûÿ¸§‹¹�€ºgpofäW3ù�@yóVyi`yh|˜¿hš? ›_þÅïvÇ÷×m’r?’s·üÔÀü¦€ÉÍ“¦'‚§ß†ÐÏøÑïÓ|Ô'WÕ—yÖ�£å¾ØÙ?š_µ}‡ˆAÏè¡âÙg°ÇÍhÙ�†Ûj­±[l³Éf›@¸©x#Ž»WÐAzÃ�q!W‘EiÄ‘G …”£oÛµSkàÝ$ß|?%‡‚ë±7T.ÆwUVÔWÿ˜XdéW–︖€Êœq¸f# æÑ `kºEæ,>gá6jh�d?RÆ×‡™5¢g mé“%±8ij4Þ¶š¥6FºiŽ; ×#¡Å'‘â,×ÜsÑM·$§¦9‰ ÞÍ$%NWUižPDe©Ô£Øt ß”ò…9¦W÷™yfšt2²,³ÎgœŽH;-�vâé�{;áa^訅vˆ(f!.J¢£¡¥)¥”fŠ)�š¶:oožÊaCB’Jä©GB—$7Ôѻҫ±FiS°ïŒ—®â`©¯êºçe W)&Wö•™ß™x$»&³Í-œÓR»¦µ×:”-P|ú¹ÿ ‚†‹¯‡åŠˆ®‰½nÚî¤ïªæsj mš½3¤CCòk¤sHJ§d6C³ä¤Áß!\«Å·^©+Ä'rùžT_Zº�UÏzuU¶2¼õf»z=1°X��±ÎrvÇi®ÍPÛŒÀ‘Üt;bwe Vs<ò,ã²ßÄ ®å¡NF¸¢›1ÚYºL­Ë$ã�Ç ¯mòN.uåÄ�y©ý6ýïÓ³Êd裋^º…²Ò„:•«ŸÇÿõQZ&þkØ*ÆÚ•�o¸C–Úv×»ßÅ�dÂ#^_þ‚¼äémy|{™ów/š‘«pç:Üëǽîýì{% ßjÆ'5Ðà1*Ôñô6¦­ É�”m„&$ øáTdŽ!F¯‘“H! E':$ºÅ- ¥�œ£ŠÄ` ¿bÃp1)[à€1’±&ýè%óŒ5öÎn|ãr<ƒ¶4Mðx)ÃÖšÄÀ6­±�Ï�¢7� ÈAÊ AÀ‚…F ÈEREv9i‰:s„IR’=×Q!&3Ù*º°G0¬† #’E¯Ø0‡:d™âC ‘ˆC4"’¨Ä%¡ÿ‰yb¥HE+b±€òØbýF ’±Œ5Ac7ÔÈÆ¶½ŽœéÌýSÇjÜñ!tÒãïÚdH@’�$3$"³HF62MÏyN$ @ÉJ†æ’š|'<±ÃÉNúÈ1dË }YÊî°‡Ùc+] KY"‘–µ´%.¹Ë*ö²+Zl{àEö¬ò‡Å£‘©Ìg´±™îˆ#4s'Í:V3oÂ&Ü´‰ nv …DP83NE62ui9çFÒ¹ÎIZ2ž>ýiiæéÂzÞs-ùt()oÈOTú Ùqå+�HPYhF3¶ÄGBuù+^qY£ü%DƒùE%…ñ¢ÈhÒÇŽ6¤éÿ,Iz·<�ô/{Ð6¥ˆSD4¢àLäL;ysâT§;í)P›X¡¾P2EmÄQk¨TöS•ÿdåS¡:P‚Vu(›ø,h³Z¨…v•_¦D…IVb^­ÉTë2CæÑ�>ó­q�`I”G»þn¯†ì+÷ ÜüUœ�í¤Œd³W}.<ëIÇ‚Ÿ¢ÔçdO™Êaþ0 E”*g; ÚÐzŠ Ý*/½ŠÝˆN´©¬-¦k7ÊVg^/�·E^n¯É[¸ùAÃ.p‹+Óãº0¹�Xn$wzçB·Á*dáè«�ÇFö¡¦¬,wƒ˜Y�ñþpgÛ1ÞÏâ2&– ÿi*Yöî01^Œ�iÆ~r<ÌÌ8èëVÏ wšib�~GÅ_œþ¸î«€C�E ÖÀ&‘‚ìà) ¢“°=«kÔë"¬fªe�Ѝš–±xG\âO½ Uo—QëEż8Æ�1�¥hãeáXǵå1p}<Ò ù!¦84¢û›—ÿât¸IÞÆ’Ùää>Ù3Qn'•3]eDxºÖ2d¹,Ù/owµÝÝðwatf‡xÄ›XsFZÅrî%!.¡û, �È�èŒÇx<à°LaŪI†Ã>ŸQD߆¡õuö•a žá ¦¡ø±`žß’H†Ñ½ßEYÊ®HØ_'AÎîâJ¢ìÑ !ŠíânBZ#Ú†#J$î„$Ò%N Š”òeâ&n`'v`{€!Š¡(Ž )r• ž*‚Ÿ‹¬"ú•Ÿ FÔ^ÁâXŠYÑ¢“è j¤„÷ ÿ�jð¢>ž„/ 0æD!šWb\(!â¬J2ÖÆ26£4<#}D#´Ò%.Ÿf f£n#(Ž! ™á[ áN© 9¶:r_+Ú â”;Âã,ÒH-Úc=¢Ä=ÖF bMèŽ0 1"âxñ^ïQ¥­C:dOxS6¥!IdYÈZ5H„€U+¤Š-}âj„ ` ùX†eI† ˆdœcù½àI>\_¹ãJšP¥¸äâäéd?ðde aAŽØ^TQåQ&e†IS:åSN#H¥Re„8V6‘VªWvåW†%XŽ% lh†ÿ¦‹¸ˆZªc$…fhº%,BŽbúÅð-&S6¦cB&J¦d]¥ÓDßhàFf Öfr¦gZj‚æh¶FišR:eç¨f±¦\º&]‚MÞålþamÞfýåOæxõæý¦çp>D›§' §%Fe›M%[T%e>'ÀDçVzcW*gvfZžàgfçvJÞ¥_õUxŠ'‘§m¼doÀfM®ç·YJ{þb_¾gnÆçn &Næoâg32È~§…~HC‚ÈWe`eBçb¦‚ ƒ6húJ„¢æ„ÎÞ]ÿ(“bhvjèqhmx(o€¨zŠèÚ‘( 変âæ0 ä>äŠÎg‹úæ‹fŒþÅŒ.f�~À�*DŽêh—ñ¨�¶‚i(.èN5¨©‘.x&©L,i“2i†B©” •Ê&–öß ¸�¤žNã‘ W _U†Ø'l*§Ò›Rß”ƒ¨Žjw.•±Âs<2!Sš´I+zâGXåЯÇÂF:í Èª¤¬¯ñÚþ*Œ…è£+ÛEê¤ÊuZª�j˜h*§n*Þ˜€³fŨ’ª–ß©&EªĪ¢Q« È«j#7ðªJÔ*�¸,åêÉYˆ¹+¼Æ«n «ÌÿIJ†c³VkO@k´N«¾öĵŠj©RÖ¶vë |k7„ë[ŒkF–+I¬º~Šº»ž�»>¬¼f¬ÆRޤ֫²v MÓ¿‚ê´~êðl9 ì)�ªÁÂaµŸi¬:¬Ú�DÄÞêkT¬·,Æ»n¬Ï+½Ú+ÈJ‘ÈŽl˜”lbê+ʪ춢êF<,½ ÆìÌö¬Í˜­vÒºF’®^lÍþ,ØÎfÐ~¬ …líÑ"íCŒìÒfë—±ìÓDÔžàÔzggT-ƦÄÍj-Årm»òlÞ†­àÚ䨲ƒ` Þ§MÚf…Ú®m˜l^:©,xâ,H-N¥ßU¹ãnë Pn:iÿîà†.Ðv¬Ðºâf™â.nO4®C´ äFÒ ZƒìÎîäò-ŒX.ÌšRæÂâæ +år.芮ð®gá.›¡.ò¨îê²®ëZ\äžàìÒnvR.î>æÚRð–çþ®°fïð~//o'�î41äȲ® 4o³=ïùE¯ìÖîÄÞ.Ý^nùíîÍA¬°&€þîo“/ï‚/ï¢øšîñ–o3ž/ÞàŽ©/¢¥Ó×a�ûZüB­Uo�ÚoÝioþî¯þöo÷þo‡0¤’.Ù>ùÖ‘ùþë´*°`0ð¡9ð×EðËmÏï9]«›ÿ*w0“úïýа³Ü2 *;ðLÿC*KÛP‚?±�¥_üÙ’¹r®Ã’d±ë_6,êy:ê‡1^â†#1ZHÜñ,1È4ñ;q—ß7‘Õâ\‹´kqs±‹1‹. ª÷WƒHï´±'—ãÔUÍq¯ª†‹Ü1ëñ\ö±%ï'é*q3ÒÉ^!2%à~,ò SqàÚ$Û±áq_²+‹q&Oè&2C*Ø^‰2.�rùqqJ82À¦.¾²0‡p,oç,§…C¢-ãT.çrúñ2Jø20ÃeL³5crk2 t³7+Ø2ŸS3ãry4cÇ4ãcÐ\3;‡.nXqk¬!7{ÿs7ƒóNÝò8ë2˜³þ½&zZŠ]‚q;ôƾ³°ºˆ<'=׳=S>çs”sÇ�³o¤sz 4Ag4¼ô¯"ô6+ôB7´C33DG4ñsïùó t@¯³F¿´±r4¯YJBËÈBó�HOÒCç³DcEè?4±Â4Qó¢LÃM´M‡tNïô8÷ôOWiPsQWuÆJ'“ºåÂ’YÒ^ X‡µuø²U—µ5÷¡VÛ.,ÁFW#È^ µYÇõ5£uklµµu^¼õ•Ê5_·sâ†]Ã^…^ct_6LãF'ÀZßµHr.ã ¶dµb÷pc öc kdO6ggUtes°¥ÀçB6Ït¶iûõj,6䌶f—öi¿¶0öþ®6kóÚfÃ6n÷±lë/m×ö Üvn·ïvôvm·p'7ø·q³6r+7tG·tO7•!ù,NÅÌÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹hÜȱ£Ç�CŠI²¤É“(Sª\ɲ¥À�0cºœI³¦Í›8sêÜI0¦ÏŽ<ƒ J´¨Ñ£*E€´©Ó§P£J…¸ôçÔ«X³jÝʲªO®`ÊKÖ«L²hÓª]ËÓ£ˆ·pÈ�ë‘­Ý»xófì7î\¹uõ LxðŒÃˆû¾ý+wˆãÇ "K.L¹²å§ 2kFœX1c�!KŽø²éÓ¨WjÞÌy†bŸC;MhêÛ¸s#\�¹ƒïßq‚ /A¼xˆãÈ}(_ž£¹sçG¢ó^ »ºõÔÓ¼¸qäÇ—3ÿþ<ú‘é×Ó«'œ]{îݽ—^¼òå¥ó^Ï¿ÿÚöÚÁ‡|%T`à�$¨ ~Ðé·šFÈÕtzThafxà†*¸ ƒ9˜‡ž„$–ˆo^˜!†¶X�‡ ‚¢ƒš™hã�CQ˜¢+²èâ†0PÃ�2Za¤f$ŽL6é’Ž)öXÄ�@Â8d E™™“\v™”*®H%‚V ¢‘VÔèåšlF4�lCìÈc�cä•Y¦¹e›|ö¹opÊ)e�/–‰å™ZRç碋¾)› tÖy§™ ¢©&£˜²IDtzÀ§Aš ꨤŠú驨ž æAÁ«°–ÿ!k´fj«—›vJÄ©¡–êkªÀ°j«°Æ:k­·&Ëd®ž‚ £¯¿‹ê°Ñ¹Zl²–AkÊvk#³»:ë!´¥KƹèR{„µÅf»­·ðJ.¯Ï’;ª¹èž«.»Æj‹l¼¯7¯¸ Ú{oªùžk^µ×b{,·G|ݦÀöjpgœ0 ¯Ûð¶ïJ,rnW^Yq½¤ òÊkœpÇü¾ ò¿#×lZÉCžò±×’ìdÝWÙm]vt™Ý¬f?KÝÐ~j´ (-jS»Ú~Bîµ¶QˆlgÛ¹Úð¶ËÌ­Tw›žÞ¢Ñ°ˆ½¢b«Ç"VÊ�,e7³çŠ.ºÒ¥îg­{ìjw»P-C‘úݵÀ¶ ã%¯éžˆ^.¢/ƒì½Ž{=\á×sÆuã}aµ¶ý²²¿ŠÁlP¥;]w–À† ‚ìU ˱Ájy0AL—ÀŸRa–œ¡ðîpÑÞeØ:†opå;\úöž#.1sµ6†*[ùXβ€ÌY[Ƥ•1‚¬Nظ‰8N‹ŽÂãïùÿȈ²îˆVß¹:Iþm|a8ßâÖ÷¸#Ž€”Û·5+_9ËXÞòŠYìå/'H´£…UëfLfeš9‡ílß^%@³‡7!ˆ ]� çÃÈ9wt~ü¶fÉÁf¦°z^2Ÿ›ìç':ÊSCâ ]eD'šº.¶=YÌ Ò �4ë(]cLë×}›î´š?-“> Ô 5=K=ƒxûÛn¨î2Èê$õ'Ïfò‡;b$«akÓµûx=__@ÀÁv�={Àï~FÈV¶iÇÜìuÊàÙšÞ«´Ñ2WkcÛ Ú®&·¿ î!§·ÈbýB«yûjߦ{ÖëB»�øîkÅûˆ»ÿæµ½ñ-ìköÛßÕøuÃ\>f/ø£iæÊ¹ípOfÛͤ¾_k(îípßtÜ«ÖÚÆÛÛñ÷ÆÚÃÅ#�€K^¬“ å†^9°[Îàwp‚x9¿ÿí!dx»•.%ƒåF–� �3=/æÏ½çã;Øýî¦#ú ŒÞ… ']ãææº÷¬À>óQtS7ܬŽõC#šåúæž× v±÷ÀÞÇžyv!X‡Î{>í©¾1ÛÇâvâ™.î¢:=ïŽ÷¡�ï~÷]¹WÈñÀúã…§õáC—xÃ1~Þ*÷5ä»7ù&T^옗y�iÞ:Ͼ»ß̹PúfíÒ{®ˆø[ƒö·ŸÀ!mŸ‰]ÿìä¨÷@Êáü.}ŠGúæõí7dÄ>ò|q zOÀ-RöOŸàÿ(~°X€R"`8�€ øÒØ…]¾"%sÎ×yz'G”A4PUHA}&e}�#¦³}ÛÇ&x‚Þ÷}ø!€)@~Dg~è—RP±~îÑ~¼ñ~î"Èô§zÕ¤€ HvA² ЀX€Ø#„8À€òÑ#*Ø13v�M”�ð³�-Õx9 HL;x$¨}'ˆ‚ò}F°‚肃r�~NAƒÚaƒ«�ƒÚ¡ƒc8=Hw?å„8 „0B„Fx„À‚JH€H]€…Þÿ!…SX… s…¯—…ZØ;\(‡Fñ…{†{H†ex†&˜‚ˆÃ†âç†ß‡šˆtøv¨x?ô‰|xV>HM€(ˆBˆôaˆ‡(€À²ˆŸeyŽøà1…&°6g‡ZXØC—ˆ‰8MBNã4¢È¤˜6øÑP“ 7ð�à¸1ç‡2¯Ø±Øz8†AÐŽî( ö–‹1$@„ôx�v*R²6–‡&hB 3*k£Œb¶]ÉWv©²8 “‰å(�î!Õˆ3×x ਆÛHÝ8àŽ 3Ž«¨ç¸é¨Ž³ø‰îøŽð�N¨‹ú·øˆ�ÁØ#ü(vþh$‰2ÿ9�=³Œ§u�ùø) ™/ )h1�‡A Y2i àH„ÚHܘ*A²‘ß(Žãx~b’}£+ºÂFj('ÙŽðèkò8`/y–÷“+2“/W“VPd²3)£“+Óà“�–�m³�Ñ(F9H™”C²”Дû÷”Ï•¨2•Ti•W™•1È•�â•ß×k–A0–ˆˆhù™g©––ýæ–pi'8)*tY—‰Zx9À”è2”Eù�­˜‚I˜â”hs‘à‘‘TyŽ9Ž�É’Ù1”I–‰8˜95šÉ™Yæ™ 9�™‡*û85ýX“§Y(r™“«i—¯›{ÿ)”}}³6¸™”ºi ¼¹†P‰‘R #Á9œXiŽ|¡“I™Ë™6ÍÙ3Ï™’dé„Ô9 ?y¾HšüfšÄ—Q3—ßÙš=ékÕy*²y.´Iç95é‘ëYíé›Èœ�Ù‘W)Òç}óùÉ•û‰6ý¹2ÿÉ* „J Àr ØI“Ú¹ ¨Ù�ª¹šžª|:ž³Yž`‘¡=³¡ÕØ¡úž¿Ÿ2Ÿ$z•'ê…ȩŸö¡†/ª21*3ª€5: 7jˆÚ Z =Ú ÞI—BŠh ”Fj¡H:}³)k#Œ U¦ B 2â¾$Rø!ˆZŠZ7?ÿ1"$1©’ 'Z×h–êYldyk³'�¢b£©B¥ù‚5¤ ¶$¨šªËq*Ü™ ¾RŠƒ1­´Z«›¦WC„ö#×y„sgG‘§´±6ùç§÷¨�šƒÊ«b¨ä�¨b ¨UÀ¨>á¨#©’©”*|ó8�-byøÁ©&è©&ªÓ‚5ŒSª«rª©Šª«ú)­:¯«a0«µJ«·*¹ª« @¨2i¾š0Àº‰î¡§SS¬Æ$ȨËê!…J‡š¨‹:9�º%�­Ùº­�×­ ù­b®ÊÑ©©Y®fš*¤š®êÊ®íú®¯óÚ3c¯÷š¯ûª«þÿº– €¿ZGR!¬£$›°²°2Ò° ò°%±Ñ:± ¡Ö*;©²´eê±/²> ²>J²ÔI '{5ê*4*«ªÊÁª# «0+«¬s¯´j45»«û¯›/[}ã4@Û!B #D "F› H«´ÒJ­1ñ´!1lD(Bkµý†µZ릟: ^‹®`¶¦úHíê®e ¯gK¯2[«n›0üگ̊³s‹.uKw‹3y[%{û§ò!#àø·¸Ï*±ÓJ±Õj±�ʉ+) ˸üæ¸ã:²Ó Ž“;4([ªc«¹>`¶r¹hë3õº¶lºù2º7{Ü«2s»-©ÿ;¿ñx #T»·}ûÁ9*7[èâÐ:¸º[¸¼{­™!¿;&‹Ë!àØ¸äÁFäZ�ŒyÉ+4¥e¹«’¯ÒJ¶Ï˹ѫÓ«2¥U«Ðƒ½è¢½¥Ë½‡à½:{.Û¢ ¼t(êä˺櫷¯› éëë¹q[î{.ð‹» ! Ÿa¸¡økмüû�þû<²–G/Sú�¼*ŒÀ ¬¨ ½ *½S3Á´ZÁ3ó¶.™ÁÝ›³ÿ‡.Â�ãëåë!ç+´+L³ëÂGÛ¬Äñ¾Í¿L›6Ì8|:ùK%û»!ý;¼ÿkäZÄ÷òAªKl¹Mÿ\OìÀ�k¤DÁÏcÁç‚Á/<š\\Š ÂXÚ%\2­Ë ¯K¨œÊt°Ê¬Œk̵m Ão,ÃqLÃamuüp" 9|¿zÌÃÀk¬-òÇ=€µË‘ˆà‹„|ø˜ÄP�ÈB£w‹ÜÈ-Û¹;9ÉU\É3ãÜÜÍÈ|³š|ºçâÉ Ü�$LÆ&lÆ(üȘŒ�©¬Ê¬¼Ê®ü�ì[º1L3¼´U0¸ ±!BF‘Çq°Ç?ÒÇ Ä€,Äö�ÌÊ,vF¬°‡Œ5¥…KÒ|« ì¼P쪥ÉTV 2Ýì͉ÎÂÁ]œ0äÆP1ÆCPÆ r¾¾ÒÎ÷ÿøÎ¨Ïò¬ÆôÌÆ€ëÆ%Ç9 ÇûÌýÌÿýCíË ÌúëÃ~¬ÐÅÈâáІ¸ÌÍ<ÑCSÑ‘tÑ›–ÑRÀ².ÛÑSŒÍ ­Í"=Ò^ðͥΜ/+M{E±)ÅA„¦Œ�¨boÈlo£ ,D¨+óˆ4 ›Ÿâ vŸÑldÕGhyši¸šé4wÝ’ºú€£…ÌÈq%7ð’�œa�¬_›/˜ekB†˜¹R�¯OT ­è²pÛ WR5ΑªQ]HàɩН\ϵ‹!ýç¼ʽÜMA×Äa×mJ¤Ÿbo¤Ê×üê×ûØ¡íƒ}…ÿ}*ˆ�/ŠÍŒÝЉøÐ/Ùõ+“�3•� £‹Ù @ª›=$� “ -Ú”KÚÿgÚ¥ò,©½Ú™ X ÛŠ:ÛÊQÛ ÉC‚Û͡ۼ½Š¿ ÂÁ}ÃíÂrÜÍ‘ÜË­ÜÍMu½ïmØyíkÕík}�*Ý)�ÍÝÿGØüZ�á�.ãýå]Õç}Õb§ÞRí]2#ߘMßÇÁÙž�ß�:ÚèRÚXvÚ~„¬Mà aàU€à> àò**·ý3¹�ª»ÝÛ1áŠPá!pá\›áô�ÜÜÛáŽÎ]Яx}*Ô�À)Ž*+N-ÞÝß}Ø÷|.ý·ØôA(6M–ÿW5’–”ݻȯòMä!`äøM™Û-#J~.L~N.ª å~§¾-ÛçBÛY,—[Þ2]._.áÀ�ªÂ½Ó¤ËžÞá>!Î#,kƒÀPpç§’ç{ž}þç0ã‚NƒB(rè‰þ3‹~’�.ç–M„(锞–HŽéû½äýÝäÿ=.O€Q.êaNêd`ꤋê ÎåîåÞ�!ædnæ´žæ¾ælžë’±ë½ž*¿nç×­âÙÍâ—nì/îÝ1®|ÊNý×ìÎ~ Ð.vоÞðãWäüšíXSß5pßÜnéú­¼ ³é�ŽØ.ž,å AåVŽå£ÿ’ê³ê­Nï`ï°ná²NÜhj~l¾¹®+…]�È1ð–+ìŸÚ åÀòÓùñ‘2ñRñ/W5Ðz)áŽæ±ñŽ>„û‡.?4ý'òôˆ*€ "#ðö™þéGx%Ľà¨ýÆ+ßòè^ïêÎîäšêøqóDéÛžìÉi/ëHJËÜnFßðžý)I?5À¾Ì§âô‚mˆQêJõèbõb‚õYoÓÁÉõˆêõìÝŽa?$#nÙf3Oj?¡mÏ o?qï‹tÏÓ¤â¾yÂ.�0_ê Îùv¯åïžðÍ!ø°]ø |ø7P÷yyȱøm~’ñø6š’ÿJ¶–ßô–þôšO€RŸ*ž¿ìà!ñXè¥ÿ3]¿'öÑ!öÖ>ˆe¯0°�ö²$xÀà" Ãä`Ø�áˆP$N$SÑbŒkl4Ñ‘à€ŽKŒ$“£”)¬d ÀåK˜T¡iÑÇM9?‚ Ùqc�0A2Œ…¥€˜-eÂéÓQCî<øth1Y7l�ÙÕëW°aÅQ6!‘œiì¤jð©¸q'Î¥ÛÃî]“ÏžÚ0o�Ó¶=x „ÅŠOŸaܸÂcÈ‘%C&PÙrTÌ7‚n“UÌÐ]ƒŒ>Rú'd¶ÓZ,Ýú](Š�ÞH-°0ÿß«!:àÝûÅoàN%Øsäá¼)UEvfÍŠ7} þØÓçÆÍW‹MÊ´©lÌÄ ºuzÕóÖ cÕ¯ÛÁýû² ΪÕù±ðý·qá†}oÞ½Zȯ¼ƒ€ºñ ; 1ÙBẖÉ"ŒÌ²Ë2ÓŒ³Î²m:ôp´ Z;í1ÂZ­"×Jƒ­AÚj»M¡Ür€h„Þ|î7á8ò¨¸�Ž+É$åPb®9°ž«Â&œêã±§Ÿ²j»–`RÊ;EX”jÇ­ê<®ØóòK—ރϬ„è[˾ûªrJ¿ýø›Ë?»þ �ˆ¾úË@JsA‹|�1 ­€ÂÊ,¼�3Ï6ôÿðCÒLÛ54 ;‘Œ_£‹ÅÚx‘Îg¬‘·qÌk8,2ޤä‚R,#‘œNÉ�¬3¡É:‚r¥î¨´òñô$/ó´êLbÇÄŸ~ÚIVC1 ã¯g õ… ªµ¶²ÕÖZn»½«pe­î¸ã’Ý(SÛî75Ëælh³=â•·Ò"Ð5”MlÐw_-úõ±è^…ÕÔëj ã`„3²bá!)pøašª8db¨¢Ê”±MÊ*Ž;‹%/Bn0Í�1ù¸¿,’wÑÅt¯˜c–î  š3£¸Ž �b{~Iç Ì­aYëšÅÚhG˜¶Û °Õ6[¦™þ6\ëÆ%ÿ·¡ÑÕTݪ٭Ì]†à•7^zíµß}ùõ·_€ÉHr`žfÝá„1ZØŠUcŠxâC*n15ŒeÓXŒŽ= d‘e#ù#“A9/•ãe—;ˆYæ›hNí ›1ÊYgž}î謫+ÚBg‘Žvén�~:joí·�uc½ksµN³ö�Ú ðÝ Æ&;Åz3½—Í´õ]›m€ß>sÉŸè>Xa†™ëjoŠg³¸¶À¼pŽ?^)d/F¾¯ä“GJ¹¢•Y®ür˜g6¨f„Ä. C�XÒs7½'£qFu3_˜æºmÁÎZS£]×lwµÆ5Nw\ëIm|·à…Ax{(›ñΆÿ¼ä-O msÑäf0éQoÖÓMøæ·‹!cÙøÄ'ò™¯0èsœú Ç>ɹÏeð«ƒü@¿ÎàsÇÒßþ¾Ô¿d™0$ÜÌ!RÀÒåiPS`µÈ;�Ü.‚&›`aÀH� ž%ƒì`mާŸäÙ@„$ØóbU0éÑA…yƒ öú¦½¿±¥{Oùž 7¾Ä)fqiÜãL¹=Lî}ð3"íç9ü�ΉüÓYé–4EÔ-/I[§Å-vÑ‹²£Z‹#Æ1–ñ gH²Fáµ15oŒKçØ¼:š0z)´[õ¸ÓB‰e/˜‰á 1RÃÂÝ0‡Š;ãÒW‚õÿ‘¡}‹šäå*¹9›]R‰™dâ&ÁEeý”™IÝ(“VÀ"�‹ÜúB=íÉÀ äó¥ üùÏ12B–¿zŠæÉ5_ºd /áâËå‘Ij¦Ð¦WL+”A£eÀ2_È~„1rÊàîf¸° Î w{Š> :�€:²m’"üYÈœå/wQÍ©tžK�¡bP¬XJxNKeê?À4{Þ“• te¬þ ÐX¢ _:äBo©P61t'ÍWò~pV´J4`ýß0é¶GöÑ…ÊdfW�Y€¬œ4|‡ÄaÈXê—ÎÏš”)ÀpXÄv3f7MMN²S»ôôÿ§^ êІj‚¢>Ë�ÑJªR™ºT§B5ª_ø¢MuUTk[¥æçU"\e¡Ä3[fÐfV´žU­n f[çFÌÜ��/ñ# í*8ŠA¯ �¦_ÖÒ|¾T 1õaÚ†ØÄÖôrŒe‹c‰ÙHv²ë¹�Öd…¯«lt£CêlÇ>û^¦p´¤�*M€Z¨ö# b­"{Ð"$Ô!ø2Tñjƒ¯¿¨W£¹ÕmÈ&š'‚�0�p=¦\“ùÇenïµwÍëÂP •þ5�u-#ÇXXÄ`÷°·ûS¸»ï‚W¼ã�ÎÊ‹.}ê½CQ0G™Ó^ŽÁ¾òmi«zZÔ4MüÿeW_௘MŽÔAœ—3ø»-¡oQøVŒ×%Åd3‘ûLåzx¯)EäJŸ Øèþ¦'®îuUÌâ?½ø#1Î OwFc¯íÆ™Êq>wì�³ÈB~/‘£jä^õ3Éc\²lú[P9‹¶²�²… œ®Â\Ù$Yf0—{ ½ß‚9¸ÆŒ’…?šá@îd�%Mîr›ëf+@÷Òu±‰;cÏÒ3Aøl?Á§€€ ¯VƳ´¦!q$àšÙlg[ÛØîJ¶#§pw2&<‹¨3r3õ®2?¹Š³ð7ÞàÐ ù€¿hpï\)‚o†’õŸt·»¡=]éXÿQ¢péÈŠP¸ÝUø±±PI÷¦AJ •¦ÉÜÎ@ç8<þq)v$M»³Nƒˆ(qf;›\ÐNˆ´Bí+ZÐÞ¦ ¸‹]›�”›MA7}ÔMvåN‚�7(ç�ƒz÷‹âùÞ·…Bn‚]EàÃzIÁ‹‚𛜱áCy8MÀDq‹[HÜ’áxÙ!ðq�_vä É]1‚r@«ü8,'‚Ëss¤2—Ù.¡yl^M­-IçúáùPÒýËÝ!C?Pщ*o6 %éZXº”˜ÒôÌ<=êC™zzbbõƒÛ%á¦ÈÖÒõ*|ýÞaÏÌØ#cöŽ£ O_»K~æŒÀ�Ær ÝíÿŽ÷ÏÛ߆ÓÍS“ó„˜#=g+×½‘«0ÂqÃ,äõ#y{ãÛòKyõS4/©O�à38Ö} õ«9|bÿØQr× Jþ´¯½Adåöè~¼¼/�ïK3íä©6½Û»¾û»� ¼;2�Á‹‹ÂsˆÃs> ƒ>¡+¢³£«¾£›¼Ê{‰)Ñ7eò¾ËÚ<‡è¼ñK€ò½¬#½0½†@=Õ«¸÷Šø“¿@¡¿ú»?Ü{;*I9{6t᜖û¿— À˜Km>#!/° ÿB@ÁK¾�Ë‹è˸I¼� ;¡ÀƳ@ê;ìS:íãÀËû@§`+Y)ŒòØ.)ÁìÿéÈ1~€ȉã †@½  ÷“ø¼� A´ÁÚ“µ µ¿ÐÁ#t"F9–AÛ‰´‡ˆ£JÄñê;%dBLsB̘å+€4øDÁˆ*|¾ÀÂ�>Ç«>Û2É£¸ ä»1ݧ0Cë@C`QCaaëCA€CpDƒ¨C„¹Ãõ£‰< ‹=¼ ƒ1@”§Ë#’ë‰B �CÌ=E DÑñ"*¶Gü�¡˜¯IÌ6$Œ˜Kì�&DÀM§jôDPÌBQäB+,ÅãpÇŒx7.Œ·UlEW¤¦#àŞ°Å`ÉÅÏ#¿]tÛðE`4Œ‘°ÃÀÃVÓÃÕ‹A‡XÆ=kÆÿÜ/Ù€F¶ëˆi\Çü»FqTÄÙF?T�œ€Ä†GC"À᫹â;Iº�$ZÇOLƒ†xÀZ"Å)4 {”¢¨ÈÀ}äÇíó@YtŠïSŒð8] =„·LŠls°Š0�XÓšŸˆ‹ÍØRJ+ÀJì‘‘€‹Å;· Ñ€Æøµ¿¸›m €®�ÏX ÆxºÛɱ›ì>©È`ŒëSCïpR/É6{rª>¼ÁZ¼3Áÿ؈7}Ó¿p–8²–‡‰H 5ÒÍÜ%á4€eÑ•¹•’õ‹ Q'ˆ…‹Õ—Ýǭȉ eÅP,†ÐÓ=%ˆ$­F&ݶ'�—(uŠÆ Ò«±Òàž,ýÀ-Å9/L0e 1½6l+Ó-:ÓALÓÂÈ#6¥‹7…Ó¼�Óä¡S‡±S' Q˜Q#8Ò�8Q¸øS@ Ô·Ä6%DMÔE5€Fµ�GuÅHmˆ}ZP -!½ÔL]Ö#íÔCüTlt (Í )ý´ ¤TrAU RUÆÔR^áÒW=W‡ÈŠ0ý2­'3•Áú;€3¼^e“6ýÕˆS ™Ój©ÓÿŽú)d­eeV�pV?�ŒˆViTj•‰B=ÔÀ¨QtÙÖn%¥! W†Wè,W€=E"ÕÔ®*%Í wI˜ˆW1˜W­©RŒ¸RyYUYlÕãûWK X1Ø1­Uƒ½Õiˆh ‰4iXýxØ_•XÎ Ø °X"1§ŒÝØLk¨>…V@�VjÕ¶kÍV'dÙ ÐѤyY%W{­Y“H×¹Ô4�õÔ…iÒP݃Qu�)E¢-£�¤U ¥e‹.-‚/uZ¨¥Õ°Õ§©Ú†h›<â\ééÕ¹€Øˆ Ö‰ÖŠ-Ö‹%[í%îŽY ÆT¦àÉp`nk^Q•W ¦×Lq¤ ¢=È`íÙà¥ÍÞšeˆ^ŠY]�&aFaVaÿº€¯ô ŠOqv^]��_¶°²(4‰ú Ã&Ôüm›6Ñþß´À!Ι�ÃójZ›=`œE\&vâ1†×(Ú)vB+6,Öâ ãbÈeÚ`©\2Þ63_€éÜSöÎä� 6&]Îxã8¦€9^€<¥aùµá@Àá>®]@FÇA.«B.ÂCNdO®W8b¾åØŒäÑx`J&\)6\*®�L¶®M®Þ¤½Þ.î`0~Z¶Ü‚�*º 4Neº‰£i�¯7ævngXŽãY®å#ÅcÂË‹=&Ê>öã¸V‹dùüeàã˜a.âŽ@æ$Vfþ If†nè–fL¶`MÖ&ÿÆÅfÇÕæOöbFîfQV�2­qŠrFŒ Mžt~¯ungv~gŽgÖµå;6\ÖåæeöeÿæÞbæ€YD&ècfä½=èãýˆ„΋…nh†~èREÀjÆ`‹Ö`ÕèPþæQa�^r6g„Ic“uþ•^éO‰esšÓ°êx£†p*Šsf'ªœÊÙº ò™‹›�8<ˆáØ ‘”Ò¶{[ UbäÕY8!Ò0®LQVe½ŠJQ1�éÈݽ¬8‘2A„EA�W �à¼�ŸðŒ-á›Ùe�"%RÖnm¡ˆmÙ~ãùjÒXž/1û)´î4þUEÿ�më-zë'þ)¹v™º¦ë»žˆ¼¾’bÞ†4W¿’ÀζÁ†YÍTàÃ.�Ä>àÅ.3tY8ÈNɦ웰lçÃlÿÐlÎöϦ«ÇíBÑÞÒXÓ&YÑ’ÕnmÖ~íå‘íÙþ”ù‹&Íí³f™´îm¶¦·à¾7¸ÞŸâ“ãÞ�ä–ˆåæ•½ÆJmÚ¿žnl«îÂfVÆÐnÿPlƶ B o×oò6ï�Dï»PïÎÞŠÏ~ïxí¬(í‰9íbÁï¤ÑïýæoñïØ¦íÑðm#p²4pÞ>¾Gº§���·ë�ÁkÐëææë oˆ _3Á¦Â×]qÄqÿî.q¯¡o §lçM Ë솀‹ÍŽñ ˜qŒ†o?'� r!cÁeæÔÝÖ�ºZ–&wknsšr÷¨ò˜p(¨pèärèÖpésêsë.ó¢ˆßn$înXÓðŠJY¸8g‹u£s†°óõî�öÆ0Ðþ¤¨èó?t0ô)ôCï—plÒwõŠEwt%‡tµ.ŽIò(÷LïMçtO¿ðçÖÞ/À0ó˜EuìVõ3OцPs[?qYOZ¯õËÆõÐu<×ób®qù¾qúÎqûöc‡dOöegvKÿŠgQ¹›¸ˆt&ïÓ«ÐÿánvÇôm¿rå†Êõ«H ¦è¶R'wD6÷qugvÿ9Ë¸Š…‹wyoqz·wö–q÷ÞóxóŒùöàöü©!iR ûy#4øk×aŠ´…_˜†ŸvI‡xÉË–‰úb©œJ¹x/Àò3âø¡ðø¥ù7õOu$MwØ]wïΔ…³´Oû–'”—?ï˜7€;Ÿù<¯ù|%œçw�ÍMêùmz z¨7Ù¢§±£·‚¤÷gUÔ^à.ÎJüž‘ú¡z«WA¬w­W®'sÃFw“{”/{§�´Wûµ·Œ¶‡ùô®s¸ßuèu¿©ûÇ»{?Ø�7'¾×6¿o/ÿÀ?xgot… ‡‡ÜßnzƇrà/–h~篔JéŸ~ Çx ×øOÇðèx”øxüÕ|¯ç|3ÿü qÑ_sË(}´?}ÔG—²3û9_ý\oý{§ûЦý-¹ý½gŸˆ,hP`€„ &àð!D‡ D¬hñ"Fˆ6Zéhàã��F’,9ÀDÈ ähéòL2'f¬ùðΜGvòì¹sР †z) å(>L0mjrÀ�¨%¦ºt)媢¬ÊìXõÂ…¨QŸ–,R¤D�´i °uâmJrç>%`÷®…¼zïòíKÖ$„À‚çÒ%i·†Ú´U?ÿ ´qã†È‡&¿ ‘҄ɦ(oˆéì¹j1m’Ž(à4ê‰W³žH³æëÒ²/>îheeÊ¿$7«ü:Ì2iÄž1§NŸÊƒ %j©RÍLŸŠ�Zâ÷U)YmUØÕÊ×°bu0‹61Ûná†$,·n_½{ûÒ'?Rð`÷%'î±Ø@c�!Ù“RÙe™5’gŸU%ZAÆ‘†Zj ±vaA®1dSqÎÀvž!’XãíW)¦Ø_m§…§Ù$àF Øxc9êÈ¢YE(åƒzU)ÇbJ¹•d‚TÖѱ¤K¶Ù6ÚCERPäÇ€}&ÔPCe!¤—Þo.�uÿ�tešißIÒ•Uƒ�¹ô£{ X�0hàprèù[‘!•YåQi:è”…Fá!¢‰*º(£�˜•ˆìÝ`(ªH‹.n'!�܈£Ž9>Õã�Aº4def–äTKÒѤ“Vd$%•H]™å–]~ÙV˜9Œi&°Ne)]ÅÛ¦o*çœugPž{‚Öç Æ (ƒÚa£Ýzûí¢�*©e"‘Wé¥D€Ö¢/rJã§6†*ªI¤*ejK¨&¦ê‘¬–à*¬NΚÀ”UÞJž–\V¶+¾ ý,°h–im±È*ë³S9ûlAÑÊÁgŸ‡�­¶‚r .Ê)«¼Uˆ��8ÿé¹–ª¸®¦Z×i¼ ôØã¨f• š¾jñ»›¿·«¬Ñjp`…é–°®»öê+XGl_—o‰l×]_쪫Ín ­Lz~ i«-2É%Ÿ¼2Üq7*.¹Fê†î¥4·»éÍðÆ»³Y=ûxïÔ-±8ôHH`Ý¿LëÀÛÚô{纰Խ>lµthfÂÖ]sý5Øtˆí,Ù4˜ý›ÚkSܶ¶oË=;í²Ñí²¤”Êœ¢Þîö-`΀!øÏ…Þy¿‹+éxHG^ëQ?}ù[ O½9çÂ’÷y袓öéu¦¾:Ú­“Á6 %§!{íí»ïhËb¼¬{º½ó=ÎNÿ<áÆ§…ýt’ǸßëßÔøH&?&Î_E´Â•F0èYé�¸R¤õèH#x�N‘”$è0˜Áß\’N™äâå€EPZ [£$¥ O)N6ÆÏ�«LW¦^9ÇŒ° �î”å,i8[·þëAWÈëÒˆ¦ä ©DD21j_šBú›e638Ï”$%=¹ÁÒmñšÙܦùD6‚�rô›?(å8Cê¡T– fç¼T:mˆw¾S–òœgYniÏ\þ¯�šÑçû Ì^diIT Yèă&¡ udCaòÐ*F”šŤE7i6Œ¶N£ݨGA*Ò­ “ ‡Íš �u™¿ÉÒªÖœÍ+[ÿzk ¨³¦2ýèGÎbXJôjë“i+Š ‘ @›¢«LX‘1ìŽ}l"+ÙÉF[Ø¢lŠªÙ„¦ ³žuhCëYÏŽ¡´¦ mh Û�P µ�}ìh;ûZÇ^ó \½-Ê òÕª„u¬euäYã¥ÖµÆ«­pÝ’\KT¦ßÜuWy5QIøZ,¿’°‚}a Û5Ä*6¬ŒÝÕl_€YÌZP˜Ýìfc›Ô‚V½¦=-{9”�ÖR ¼ê omq«ßné¬kò-Ì ´l�×qãj’°.4ÍýÒsÇbé†�ºÖ��ib¤]®q·»%úî—Â;^Ê–·JçEoÿQÕË^¸÷½cX±|YëÚÙÞw¶ùÝ/ŽÕ_Þþ÷/d 0p,Üç¬>ö ëç˜['¼ŠGÂÑ ÙtIø×¢Ø$»ì°w¥)ºÚŠxÄ’-1RNŒb„vÅ-~o)B_ûÆVµ9~ó¢vì’Þúø·Q î§ Œj™¹b�¼$ß±o”ÉNIæ½y›g¤ÑÛm;ØÞΟýõªo={½/�ØŸqö©½í32‘Ü“z÷€ï}áø« ä[ïSŸIVä+8”oþ =¾}ÚqžÚ�èU†è é™… žø�j‰ù™‘ù úñûɈûAjÜ3Í�•D”  Ê êÅS”‰‡E…©Íoh� Î ÀÜpÀà´ô •P ô ÓlЗ‹�Á˜�Ù�U_Œ`H–Vuÿ ê×[ÊÅ¢‰&Žš´à ¦M Π Ö`±Ý ®Kì ùøàò”l¡‹!Š!…ÓΡ©EaL!TáJLzØ’Az!–�"&†¶ö ®ak ¡¢ªLÒ¡%ž’â¡î!Âôawýa Ò â•aéðà"6bi°á{EâfMâ%Æ¢,NÎÝá®T†²'‹f„�"hx¡ N)¢Z$¢Ú,b ¨"i°¢iE¢GÍ¢4N£ldâ-¾E.êÕ.òa/®É/FV…0j1ÊD8º‹ cÚ(#3Ú„3–4~5Î#=Va�ÿ [|ŽïiÏ6® 'F…:¢8 c9 (”á˜"Ø "2 aÅã(Õ£DÒã=Ja>fÍ>P?úc7–H@†â02„AÊBæ@:žâ.¢CƈGµ¤åEvIF Q?ÆÉfaåGhåVvåW e¨{™%¢ eZ¾$[&à¹eMbäMjä6Ò¥fÙ¥àåUéeP†¥Iöel•åß%K&a&hÿ`ë˜ÏçÄI Ã@&d’¼&lž€lG…¤F¬XxÉ€nîfm)D~Zhg,ŽfQ”f뜦{„‹¬&kb¥kÂækÊæ Ðæiøæí)Dnî¦nö&¶ §w~gF§§Ú 'a(g0gs~ÄsB§tR§X§ú1Dvj'wÚ&xæ§~: C”Ðç0 Ã,箬çJ´glΦLÔ&ßM„vnç5Éç~F¨~N„f €îŠ€~ d2Œ�F'‚Ò€‚^'úÕž„–h~R¨iZè…¦G†òĆîJ‡òÀ{&huv'FŒ(Žš¨Ž §jÄ®([°ˆr¼è—ÄèW¦Ž*ÝŽ.ÿihö(Aü(�¶èNü‡ft¾æ‘ÊáE$©’2©—®¥“”®h†‚ hT©è\)d)pÎ'—Vâ—Æ)†©@|%�iz2RK0 ô©ŸŠ›Bè–¾)œÊ©¡º�&€�Þi™òJUð©Ÿö) Ž$’j›*¦Îb¢.j”æ©�é®Dª¤z_ Úè Zª fªª6¥Gm娬ÆV}î&ê¥êªÞ*® Ä*¯¦À¬êf­šj®+±VŒôj¬þª +~«³æ*§²úêl&Øê³f+¦F+Apë@LÜji«¸®ª· D¹.!·…븮«¡ž«»¦+»Æ+¹&aA¼4+µÉ+¾n+½vë¾~+¼æ+Àz©½¢†A€kÀìŽlµÕë¿"¬Ãî§Â @Á6ìÃVìÓ!ù,N»ÌÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹hÜÈQã � ˆIRd‚“(¨\‰±¥Ë—0cÊœI³¦Í›8vÜ)dÈ’@Q¦\©2§Ñ£H“*]Ê´)Mž}~Th¢E�jÝʵ«×¯` Bå(uÕ’V¯b ˶­Û·pã »‘�Ý»òê�À·oZ¬ä L¸°aŠt5ÞÅ«7o_¿VžL¹²å¶;kfÜø1_1 CK¾Lº´éÓ23oÖÜØ±çТעžM»¶í‚ªWsÞû¶˜Ñ·ƒ 6€ñãn’+?Á¼¹îÅ­=xŽàû·lâØ³kÏy¹òäÍ�?ÿ·}zuèÓo_ϾýÅîÆ¿ƒb<ùÖæ}§W﾿ÿÿð0;næÏ�Σà‚Õ4èà;F<ŸTøIfÈÛt¸ 6ÿ…(bvX f&¸ ‚:8À‹0Nhá…b¸¡‡Ž¨ãŽ´•(�옢?+²Øb50ÆH¡…5ÚÈ¡‡ ò(å””ùø�B¦Xä<&tée’/ÊÈd“7BIå™hÊe%–šQãæ›yÄ)§—_‚)f…MæPf‡Q¦éçŸ]­yâboÂ)gœtv æwÒXãž9*é¤J—Á¥@¹e¡nŠh¢‹6š'¤}Rjê©3YŠi¦ìlÊ©§y$ÿjB¨KâIæ“|¢ªë®-©š«­É)5°ÊJ댣â)¯Ì6ë�¯ÀºZh± ÚY«£*[ª³Üv;´¬Jkè¡ÆZ;ã&è¦Kª·ìz n¦âvêi¹I6š®ºÚ¶«ï©ò¹±Ù–�,ð¢ál08',Ï ÇâðìD,±6WŒQ€–ePbìëqXýþ[¤ÀƒiðÁ #ÌpÃ;,ñÄS|1ÆÝiŒ[bçÜUÈšLr#ŸNÊ*¯,OË.¿ÌJÌ2¿Góq6‹…³ÎT7Åób>“ôÉDƒCÄ×`#‹Ò¬,`öÙ3?@Ôq\õÛJ]}1t×ý3Ð`¦¢÷Þbƒÿ6ÒÙ.øÙh;­6ÛsM ÷â8ÉmWÝvÿ¼èÞ|#í÷×b >8á ¤ý4â¸Íøè2Ñ`ºãl@N÷Ý“SžJß—g®y6œwnøçRm¬8é¼cd: À:#üðªsw×®¿nùå8v8;íœ{NsY#To½è½g_ÑïÁ/|ñÇ�<ì~7¿ÍóµK�1õÖW�½öðCÄ=«Þ¯ºÐC‹ï:ù`›�~ô·3°x@À¶¯z›ÙIüø�ùeª~Î(þ�·¿å•¯yÿ#C´“3xðƒ, 8‚Í�p(L!WX ‚)Ç¿¯ùové[;òA²J„#<  ÿ˜BêL¿û]ZÒ²“½ (@äÁ‘ª!« Y]K®ž§6ãH$@ÊRÓ@Æ2æ)OxH£ót…6º±v{ˆ£sh*$&‘K´JáóÄ’DqŠU¼"‰¦Eq±‹_„O 4Æ2’ñŒMRã›äÆ7rNŽs`ïˆÇ<¢d�Ýé#Iþx¤@^1‹·Úâ캀Dvg‘ìh¤#!Y#I¦‘�•¼1¹:RÊŽIôä';âDÒqr3€L*µ§CªÍ•Þqƒ�èÈGÒC¶Ä.+éƒnz“—½Ôä/9Å ˜óœ <™dÒi™ÙR¥æX Íø$gš"¬f¦8ÿ¬lnÓ�Þü&/}9)`þ®œç4g:½hÌ;"³”Ê$d* ¹JDFŒ÷d$5«ÉONù“’¹ h7ÁIPI³9Mh.¯PÌѱs1îô#fš0TØ4ž�§E!Íæ“£GÖÝî¶R‘ú HM*–Z¸Mš¥@L¨9WÚRƽô.1íÒLQÓ›:Iž‚£çEí)Í1Bêh¡†ÊV�5©JeªÙPuRæ¤ôœTåcC“øÐÉj«]EN�WÑgŽ5°ÄgÑ !µ¾©­m}+\{°T,4uœOµkT¥ºÒ y–ëth;!J'À"̦‚ýjNúӇô”UÙdì;ë&Èÿ²U²p­ìe ú;¨ŠPªèìg9€�â÷mWµKVM`Zp v°Û !°zèÁ´l�¬ÀŠ-ciK Û·qµlíæú§ºžà®SÍåp‰kÜâ"W´0%­LizZ¯êiOÒeuÏ`]b¶¶”-w½{7ð"U·ãµÝ`XY–²¥,EDá¥&œ�1XøÂ¼…†7œ'¸FŒOÇÝW€®�x O(.Ùp€ƒ”ÉâÅ0ÎÓfLãlàÆ8Þ€Žw\; «Ä@ŽÇaµ¨E±®È0ÂÊÀ‘®¤zJî= ƒì“K%Â+ ð¥.Œáúm˜ÃMò0+@e}�¾l(ñ‰S°$·8ÿa0Žq“h\c[â8Ç;Öq�Kòã ùHDF2ŒŽ,h%,aMFê“É<™)Sy*%�p„µ\a.�!Ã_¾E‡“úá…ØÌð!±‰…‡bi¨˜Å.޳,dLçØøÎȳž9çcVùùÏ- ´ @h$:LF—“÷ôéÂ8úÑ@±ô°LieCV3ª�˜É¼-w…Íj&5›ñ¶â7#LÕ«žs«_}g˜ûÜ{&IŸƒˆ(rÝÒÓùº…Ãþ³±Ï¨ì?ûq€µóQ;ÅlOÙáwNàô¨¼Ý1Žw³­È|O¬ÚAûÚžîƒXáå}øÉ*¾2Œwüã/y©‚Bb8Ù9=æƒW»[â<Ã=¿û$a£'}4†…úÔ×ýÆH7@ÿëðúÇžN³¯=ío/ønô¼'â_%ø8àþø÷i‡O|ÏH~ ”G2–g!˜÷|ܲ_Òg<ÖqÙGzÜ×} zàww’wdçç%ßÐ�¨~ëw{¹×Õ&‡0ó×<ùÖ”†ùgV"ÄV| u|ï�|4·|HÕi7;Ñ/”Ö/ ´e�€¬Òyjz ó€¥W(8�ßwt¸ Èt~¶�]â�‚ì7‚%h}½Wô'Ò‚.èúG@284xN6ˆƒrRsÌGmÂñƒò„ò1„ Q„Ô•€iF} èf¢w$Ú·}¦'�(…¬w�®—�°ÿÇ)²¢…‚íÐ…î§{�†òç{*øõÀ¢lhdK4E÷‚.b“!}°Š…¨kAga‹ø0‹í•yq±@q† lÀÕ‹RÕ/XÖ/Ù•MÆXOrÈXdF#ˆ·^Ê&[~÷"î0�Ôˆxˆgؘ�Ëe0 n³ø�øÐâ8ŽÅ¡HòŠ–6Š’AwsŠ›�вŠ}Њîö"¯c±ßX‹ø¸XºÈ‹¾8�ÀaÂ`ĨFÐ'ÉØ�I²ŒÍ8\ÏhŒõ˜$ÔX�ÖWÙ¨�òÕ%ܸ0ÞŽá8ŽâXޝtެ"Š‘DŠõÓŽ§�9 �ôøqöømª–�ûÿX‹†ñ�$�–6�)Áˆ’™’�’´�yà�J ‘“化†”Çh‘é©‘iÛX0ݨj"9’$i’Ñ”X¢’µÄ’Þã’÷“2©}®h“°(‹´¨“…Á“#á“\”¾˜'C Š©F”Jé�L WNÉePÉ�`2•TY•Hu•XÙ‘&ð‘ò’àH’%ùŸ(–ì lÃRj¥ÆŽ?Ãb¢‰jÉŠlY‘]“08—=Ht)vyaxÙ‹ybtY”¶4,°•� rƒiuž5‘h� ˜ŒÙ˜W™•á°•qvÎùœ–Ù`IVšÉ™œâ™(š$3š,Všóxš49©ÿ‰0«‰ü¸“‘‹g(�³™Pµ k· $Ù¤›»™”½‰ŒË¨~ÖÈÊv”ï@zˆ)•yœ=à˜5Ò …â‘Z ’ªöœÐi™Ó‰XD $…Ø™Ø +wÃ�Þö0´Ô„¼Y“)“�ùeØ Ar‘w›ÖžRõžw–'{7,¯R‘÷‰ŸF£ŸÍØŸ ùŸp 0bœÇi=Ùx Õ� ‘)4µcêœCŽ˜ zÇ*z�ê)Ê� á�ä¡> ¢ª)¢a@¢èÉ›¡¢cPˆ…\.Šc0Ê*2:£áY£‹BpùY{û©£i!jŸŠ‘pÕ•BŠ�Dj¤ø“¤/¶¤GФ—éÑÿ¥ª}ꙚXŠ0ZzF\ʧ0Ò5`¦Œ6—Q¦ëiihª}jÚ$Fצ™ò¦ÓB£rš$tj4édÂ!Ä ¤*’�ú˜~•(…J{Jº¤Š*�_a„T?SZ(Ø) “º�• —š'™º(œ ¦bZ~¨€~&[¥ �œ²¦7–'ñ"£Ä˜ŠIpb3«Š¦]Ãé)Ënd¨ÕѽJ'¿ÚÁê Ãª|ØCÝã=Éú&ËÚ¬£¡Yê0úvãB­DÓ©×úœ”­dÜÚ­ û­¨ kâ*,¬*/qŠd‚Šy®Ñ–®MÉNÆ®¶ê®F¯J#¯#@¯"+÷š¯Ïÿ¹¯Nѯ>t¬ ©T*©VJ©£y°±�°†H,]*ž k­Ÿ ±w$±·V±;,àZ»"ë±Zd!;²S‰®H£®'§²+ïªjñª«óŠ�Êi0†* ˆŠ³M±º8$þ [ôÒ�y&‚h´”FÅP ke2 *zÃL¸R;Âtœ„eX&¯ùôqdûØw³d©0Y�Û¹‚Ë)l7šÄ)™”ˆx�Ú©áו)°º@æ oB³…û\rnßÈ4Úð;ø§�ë uC+µ‚x3ÄÊt{†v‹·Õâ�{Ë(}[r‹�;¸I"™‡ ]Š»¸�ë¸E¹éY“[¹—ÿûªš;Yy¾ (º®:¤ ‚¦{º"šº"¹º)кê&°»œ #»9@»³h»¸{º¸¼K7¾K€“¼MêÅë‚ÇËXË rËkE~ I€û¹µE¸øk¸©€¸ãw6‹›Ù«½(Ľß[Œhe¾5:¾pU¾ k‚Ü9º…[º“å¾ï‹tªËº%æºö뫱k_ü‹þk:¹›»Û ½k-¿{ÀK“ÀsÛu;$ÈK'�ÁÍËdϽ�…Á S½ªÅˆ„“Ñ¡OÀõ¸¹'ìŸhµU[õªê{h³¹-Ü$*üs1œ¾’ níkÃa¿à(¿ô[¤=l¯?œZûknµË4ÿÿë\ L ,mL,¼N±_v;“s’¼z«É|;HXLÁÐkÁÝÅÅ ãÅ÷•¸œ³c\Mea$¼åXÈ\lÌnÌÂIåÂ…º¢)ìÇ5ÌÇað<PÌÆ È;\¿Ôp¿ £¿A\;‹ÜÈ�É7ÉNÌ–<$˜ü)T¬”VìÉ›�Å¢Ìm/B½l½©Ì­AÆReƱ±<˵lËâ Çà ǹLÇ/|¾½ŒÇ… Ìp%ÌÃ<;Æ|Ì:Œk¯ëÃì̈<‹ÐLÄlÄŒÄlÇ8`EÜωÀ3¼H1Ùœ"Û+œŒŒß<ÁgTÁÒ #挸žel°ÊŽ\�ÿêZƱÆÏ�˜(ó|ËöŒÏH¥ËoÂ~îØ¬,ýϪ¶Çùø<Ä\ЀÌ=È¢¹ŒyÒ•MEìG\ IÜm}'IµÑMÜÑKÒÔuÉà™ÉÝ «ÑæŽ'í¼ ¬Å<½…kÊëÓ2]F4 ¦dÃ8]Ì:m¤¥UË> l@Ýׄ!D}Š…¨byœÔ“e»LMÐN Õ<¼Ì‰BÕMbÕœÍíÈ É�Ñ’¬ÑÎÉÑÚàÑGaÖ=„Ö{J.%Mpn]Ò ×)Ê+]Îu}Î_õÒö‘×d´×"Ú×:¡9íˆæ·ÓƒÍÆ…�0‡�Ø9°Ø÷ÒØ>÷Æ¿ Ùp%Ù“-8NýÔÿ}Ù²¢Ù5ÂÙ„ãÙZ=Ñ\]ÑõÖÖLÖJÁÚäÚ=:/‰B²çrŠoýÉ·-×£L×l×Ã…×ëÌÊRÕ©Ä­-��Ð˽UËØ5 ‡ËA�ØÒ�.ÔÍm�g•UYÚ½ÝÙÐÝ–­Ìám4U-’W�Õ[ÝÕJ²ÄbFÉï-!� #�?öm!¾‹Ò£ÈßälÝ]ÌÛ§ìÛãÜi ÜùH6%•à >ÈóÅÆN4Q'áˆMá·çŽ~Ô×­áŽ¾Ý þÝ"žÙ$¾Ù&ÞÙÍÈŸ=ÍJœÑÌçâIß$ßo+4þµm}Š8®Ä:¾’Ù_>¿É,ȘM'â�!ä}6æ�âê½âl¾ƒc�ÚHŸrku̼WD‰Ðí˜O¸Œ{“Ïe‰ Òk…k ÄÝ$`„¨}î(67K1€KQtá3ADƒZú›!iä=õèDkuyÒ©+µ£³U ZsÔ “.Ìô< $zQˆ²"šÔX!-óœB1„W‚�¨b¤ý lŠ!•¥î6!ëì@ëû¼âV„뉭ëÈëzãëØžFÁ.rºÍ0Än Æ^?S,+^²ìHÓìÚðìK@Tˆ[³d�uíØ„ÚÎÓÜn©ÿãíMî¹$î Rî¿0èž-¿‡ÑîòîÚï,6ïŸPïÎyïÚ�ïݱ︉ý^Ýÿð90ð³s�ð»¬Ä ‚¹~•»n4½>á¿^ñ:ÿÆ_ì‰}ììñtòJŸ¨ÎŽÐ~òÚ—òö¼òö5ñ/ßà ÓíöÆß¦áž§�Eî*¦ö<�.éžõDô«ÂDOzF�H?÷LïôÇõò‰ø7hñU®¿T?Oï%mí6…xa¿‘c¿2e?åg¯ žÁŸ'SApßû& ÷#ò$_Vïg(�Á*Ož`:Šïè�/ó±@ó5bó•„óŠ_ÝŒ/=ï$§ÿ�ì>ù•w—ŸùÁ¿ô‚ïg£ïÃ(õÈ'úwbõX¯9Z?¡¢úk #¬� ®ßðW ±”WÐ`*„=æ`ØÏÃyM¤8Àâ€pá šâØ°a5�!)R4QÒäI”&q¬d9pà˜Úd" YÓÍMv9ãíäÍçÏ‹3 ÎèÑ0I•zdøÐÙSg)MeTðè@…=8l•ÙU›R¥WÄŽ}ˆçÝY�#ƒf4¸É­Ç­ÙäÎP×îݺƒôfà›“�À?¦déÎð§O.aÙÖXæÈ Lžüï߲gß�œxÞgÄŸ ŒnˆÅô\ºxU¯fÍúæk7—s ö™2¨ÿET¹ugÍÊÔwÁ…»hð`Â…LËFœÇ¹ÑZ�9šòR$ç”ÙQ²lI|qך6qê乓v´Û‰=jlRßN¡J¥jÕ(V…[9x•ù>ÌX²Ò,­Š„ŠN·6�‹ÔäjÍ.½á+¿óà<ÂV2Ì㩱m‹Œ²Êdc'³³œó 4ÄF+ ´Ó|pưñ5{¢Í6‹ Òm7Þzð­ "‹n8â| RHå Šèºç ܨ#¦¬#p$í²4�»•®h±Å@sÌË‹ç§<ÒLo=öÚó/>< r†:M¢ª*y¼Œ%+ýøÓ@ÝcÐËÂãÊ(-bÿ« ÄçÑÔŒp +æÒÁ¶ã²Ã—À¹¤‡ë̺+®U_�/êûo´pp¼m5WÄ{TœW–}¹ ;Ê7_ršƒxàå,Ï]ly¦Óüαóüs¡ã�›è¢Kßþô¥¥Ž8þaE (Ÿ§¸njïÒÓ¼öC;{Ù._zSËîæ;³/à`U3ÿ<¶ÏmÑ F M˜<1O‘¡e½�oóͶ¶† ë±{GÃP÷tõ½•5®eã3ßùfæ‘%­ïQí›Gô¿gi®~XºŸJ@§¿m�ÎኃÂ4Õ)Å€ŒSë¤fªÁËjòÊOÖºrC ^z¹K”zÚÒ»üŽ`ré ñ¿´�a>1á 7¥¼ˆ©�…v{^ û%=2ņ[Ëá]~pÉ3d²pñðG'=É.vQå£<Š,Lé’úÇO, ÕdhðJÄR–ÛR">ŠX¾ä’' <ãÔ>óKxœ‡—ÔÀ›Ø4./^¤=FñÍ h! ™‘…,áJ˜fœÅÿ Ì™¬A7½ͧP“+‚Çôb@Wu/—ü�ÜÉx�6Ä@É2Áá›Z²rª¡ÌkàùO6,la*òW8Ìé‘ѱ“�šP.šŸPñ$‰“‡)-*‹¬˜ 7¬¤]Ø™É3l²‡'%)�bQT²Âq~â§+a)ËXÒR‰·´ƒCwÉK”0˜Ÿ9OzŠiL¢ SiA±g3� MÀHÓ§80ÎEM™M ÎÅ›ßLj8©I΃¢³Aê´ä%Ýé€ÊS0ôªIòpñxhœÊ(¿QÊS¤ÿ€+å�Z_I˜ÆÔSµ¤©Mw2Ìœî4˜´Y*w€T¡¦Ç¬Ù&R= ÔÛXÓ N•T÷ˆš©vœÎ'VéªUÔpÕ£^}g•¨ÏçÞ¤­nh\‡rІdW¡®ÕŒfúª»ðÎ6° Ñ(a;š^‘ޤ�5)8P*Y•¶l¾.ÿ¥Á}ï›ß[z6 %©Pó`‹lhCvK̬¬Ú3eÁ FªƒÌT_t ªð…¯ša]÷œÞª‡ÛY\Ÿ'¹%Apš™»aÅÒuqF`Ì�Ñ�AÑ‹¦q�ßqã:þ•¶åõqà\ˆIIJÃdo2#Ü{ÒÈ d²Jž}_édûB¹ˆR¦²�¬ŒåhÙ0\Þ„— LÔ0{dÌ ¶�fÌl�×¢kÆmnÝ\HßÊ9À�‹pëÂί†õ¸„$q{L¼>㥟*n+¡©[ÐCç Ñ‹Vt£k éðzOئ¤ôy­wé€4ÈÜëô§�êXŒúWK&ªû¨jóu÷¦íª²ÿPa-kwÐÚÖÈì—=uÓ�]G ×gùõ‚-a˜œ­Aì¤*4CbÂôh¸cL®³ {×A�pÏ&pxn˜«Ä¹ZÛ¢º¬´=‹„Û7ä.7Rýèïú5¼“Ò «WêÊ`Z½šÞÞbKúXPÃÉòEz¿ýÍA}&@ë[8 îjƒ;(Wø°¼�¨;Måá ÞõÄßQñ‹;•Øsá¸n‘úñ†<ÎFeE³íÌΔ‹xålZ{¶sȨÕÔ4ø§kq>€´3â7LáùÌmã ã8Ýí’<ëy½Bno‘�,ê$ï»ê”¹:ÖY¹u®ïuà9}µØ/Bv.Çìì‰|á#ÿÞàÒi©M•{Æ£*—º[øî ùmDî7’Óyƒ¿dà‘‹»œ!ŸÏ†Ìï"ªÔžŽ¿ïÓ>y�TþògA÷æá LÏ{êè°=ÓËéÒCýÞRG=ÕþÖ뀬ƒ½èº)ë%4ª=ðº=Y+»#Ù=‹è=íË�ß+³à£†áK³a3¾Û¢»Kê8 Á»qr¾½‹¾¾ã#êû룶“È>Thîó>»?ñcò“¡ ˆ¼pS?Ÿs´ös¿Î úÛ´h O3=|Ó7á7Ök½„=T °c8Û˲Ì=³{«~‘Àd»1¾9¾ØB³+¾#Ð8ÔH¾l¾ÿ x>¾ó»®R¨$!ì[�‹ÁÄ›9©Á:¤«†àAhú¹ܼ ä�!Ì¡"l:ü[ $Ô¿ÓË·ÔkÂÕ›ŒŒÂØ{¨Ù+8+\@,Ô2„¼´ó½¶³À1ÄÀ2$>5ã@WaÃå«7L¶8DÁ9¼nS¹;$Š<”?¹�Áº ÁWj¼YÄ´ÛAž[? ÅðJĬXÄRƒ n¨i§wQ£hôÇ©´Âz�­©* ¨¨Åtc“¾‰?0IvlǦ‹4–ØôËš“[ã¸YœíÔtûÔ‹€×,0#UAdˆzSUeUxrÕj`WuûWÍŒR6XÕ(XEX:UØÃ`X ÖÆÖU•ØŸ Ø¦œ¼eÍX½šù¬Ê€õX…AT‘ÝÏ’=ÈtÔ$íV–ýV'u÷ÌÐ=WÆKWvÄÙœõ¡veVPåŒxM� �!ekˆ¢EÕ×ÈפÝ×¥í×X5€…V�•ÚÖ ÚƒuÐ^ÍÚOhØxØn‰X¥<ÖÏ[ѼX¨4\|tVµÕ\¶¤!åO¹mÔ”©HeÒvÉÛÿ½-WTõÛ¿e›Ü>ÐÙðâY‹°§Äu #õé�^zm{] |EZ6PZ¦/§UÄ·ŒZÎ}T•…SƒÕÕ9=G¬å­�®Ý¯-ÖÔ�Xd•‡õSø„]�ÝÑÓœ]B•VCýØü|[’-ÒØœÛÝ]YIuYJ…Y·¼Ô¾¥YÀMäíƒâeÞpÞŸU\°œ^êÚx\™Œ\íå^Ë¥¨ïÕIZ”ñíÜ7ÏrL_¢\ß_ÝZ‡íZˆýÚù Ûú½_�(Û¡ŠÝ�MÛŽ-T!µV"E#ERPÒþÝ—Õ[(•ÙáõÛš \ä½à v× ^¦çÝ„èaO¨Þ_¹Þ'&@ÿ‘“pêÅ¡h8žº©¬†•¸cÞ P¼L_äÿpœ �bm[ëØ¼£°S&ñ 昇×M&ŒH3Ir•Y™•;^â A+!—)ö ¥‘ûÚºA–jY¨äÕ' ÞKM+T�Œùªˆó 6ù)¢`šé˜ÿX]ÿÐ(�r•!ÀXc6¼õ€ãv�c‰¡ã:ž‘KÎc–ÝcTîãùã– äA.ä¶9ätKdÄè�ßhäGâH>CY˜ä©d¹äLŒiáävON P¶/QäR–&x.(©bŒde™te½€å]“åõ å¡°å[6…\Þe‡îe_Æ`vSÿØ#f91f¢@feV!¯hfyfÆZ¤aÔ kþl&äU5ä�@d£PäÉgw=‹BgÔPg`çÒdëØç‘WyfŠOnŒPÖºQÎç ôé„V†K€æ·Wv§XfŠYæ6Qè[nh‡Öeˆö剆ኖ 6æ-7Î�æˆ9îh�~�>ƒÞÝ—‘¶Ú‚ŠÅ9iIim!n/oþpfdæg¥–d¥duÖé�åé�ðéÂ0Œyƒzî£{&å¼1e¥Nå¦î>çjåˆj˜j$ Ú¢-¬Æå÷Øê]îê_þ°Þ:‹.Dz‡³6…´îеfk<i¸Ê’Î ÿ»n ¼^émnén~éoNÀŽÁæU†AîdľÁÅÎÛÇŽìšl¤^ÅË>U†É§®:Ïí†X’Ñv*ÿXh†~WAíð�¯¾U5ëbŽíÙ®m™¸íÖhë·–fè f“~@Ž�ln½&n¾6n¿Fn¦�iØ-çñ²é¹ÀéèžÅéîd¡¦g¢¶g£ÆçÊÖçiîgr]åÍèÎh©.èôá�ò¾¨ó^h÷nö~qÀ1Qזmô¶omÀoÖÐo=f>’ÆC?ðkp•>–.¿æEð¿^ðÀžéæÞ¾çž‘n�`ìC‚¾ð��¹î §lŒ±ìgê÷î™ÿ@Ö ñfò^qSjñ¬Vï­²¯%q•÷†a~í6nÁõÈñeVkÇ �f —ëò̈º&r”6ò¼v[‘]rp€ép~ò§iS’¤%©°*§ð+—H–`†àòGñò8êOê1·ßÌþnXIóAØX�õÉÉ 7ó÷@oo6û2:;ŸqïŒïËkŒ ?çhÛtAÏm·þñ¸æcºr°p½p$n%ÿâH?îEvrå†rsÆô ÑtÙ°òjÀò¸¹-�.ç ì>uíNõîþç3�W�uYOqZ¯u87m°H§]ßš^÷õX)�i8x„_9{BoÇÉ6ü¿A›ÿB3k;«c¥à®ö¿ö¾nr�`pH¶ôs6ÐLÏ-=wç0÷OGwQÇR7õ0÷ðþñ˜•walõ4·wXŸu…¨uYhù�ñï#^x4ð#øL2x„?x…_&†o‡¿mˆWöýžø˵—Ã6Œgtwt¡ëxÿxJù(7¼’Ÿª“OyO_ POw°X÷h÷˜Gõ™'óšwêyÇù@Öù Ðýhs7úGú9'z€7ú£Oz¥gú¦úöˆú_™úµ®ú€f‰oö¬¯x�ø3ÈÈø$tl—ôävdop’w“·q¨`ûÏ\y-où—çðº÷»Wõ2·ù= ™ÿz×yÀß Á_qÂÇî·Å?ú±ä bÕxæ³/„Hre©o´ü¶©írõí"·K� „¿NÌÕÌÉg%©Æ ¤7v}¢ ò�…iúƒW|&ô âSkXsÐ>ÛŠ_ˆÏcBg ¥1àð!¼ˆà&æ¨hqÆŒ6rìèñ#È�GvÀbò$«”*ñ±l™1£¶˜2Ьò&Μ!dÈpâç Bç�-Ò<†“ç4T‹9Ž‘)S§ÎZ·®èê• Ø3=Çfdö,Ùž +¦ÐCiK2bäÔi�¼z©¾¬Ysk7nØ.ŒÐ¨QŠÿ/ ×Ôé¦ÈR'·-7®‰¹7ËåùóäGãyû¶êÔsW³žè\h^Ž»vôÛ¸«7»ý#ÖàÂý¯ÙÒåoáÊ—ãäé¨PDçMª´ñ]¨©¤Rµ“ùGÀZ½~ +6íY´i׎i›»áܺwåéÝ{¤/qÀ‚ ƃ8ÚbŒ=äØ]‘mšE•]ÆPfKqÑg MFZB¦9“šj¬ièÐkM&mtP…pÁç DJõÛ6à¹ÈQqÅÇ‹/Ú(œs@5TQG%5×còhÇ]UÞÝ€x�וyg¤ñ$”H9eZ°çÞB'>$ß]õåÅWFÅé7ÿl†X€Š5¤�V¤à‚ n¡g¡QXš…¢¶á†ÂöálÕ6â¸e)—f)þ¹brG.#qŽJ ^ŽÐñH��H™]Tugä�I.¹B“PF9¥”U^éÖ¡«q‰——`b$æVû•yfbi®Y dnÂy™œ¦i‚ÅJcá…zò©¡Ÿ±ŠÑ gÜV¢n‰ÂÓÛd5N¤~mû-V•þÝtÕýˆÝS�VD•J¬Ä„ ¼Ø¸(ê’¥ššª©®·–&Jc]vÝ… Á¨|yL3-0&Y„áú€ÁY¯„ö+fËkì‚ÈêÙȲ¬96r8£Rˆ‚Š(-‰xú»ÿ›¢&¯KÂÙØœ ¸!ukSÎ=$îŽÒõ0ºBª;Õí¾ï¼âñð4ÔöššobX}õªïý{î«ò˜|ðKVÑÄðXûq®»R|`»y Üó¹1ǘ¥ùqÈ«‘ì˜Ì9¤ íÊÓº\íR~öMsÍ7ûìÑÎ4-þ8@“;ô¹rº�§I«´4¼.Jð9èPCé¥ß‹o¾WcÍ/«þÝõ×=Ⱥ�Ø ×êFÃfž�¶š²Ù«›Á}‹ÜÒ]·4Ã~ìgÈ{—\0ÊÏn­àZ¯f8ôHƒy3Î�ÐøÞû,ù¥æjZô�™{§Í‘ ‡.:¥›~/Õª[�u«ñ ÿk}³Óª•­øó°a©Mm žðâÆ �¥ y º›ž˜·¬f*D°Mˬ7 2ê%âëø>˜3ò SD³\º07³õµÏ}€_üä�ÓÕÏ~ø{™þæã%Ù!lVù¹]™t÷úŽWlCàðŠ'¬:PyìÐð†w½9Ë‚,µ´Ä!*f«Q" ¡¿EÂreê:(4š ‘ÆÂå$É…/„Ÿ gH¿ÔÙ�u\J×vè¿�LÜ]ÄTÀ"Q�Éc`€˜¼4ùÉOQ„")IZäoÓ \õ kq±ƒ #Ã8©1Rî|gLß A¥œ6º†q¤!UwCÂmiÿô‰U·ñ¿Àø±?CÔU׆Ào�sc"ò†ÕH(>R’“ìd%¥G½Lúk“”¬ˆ¶¾Ø8QÚH4ø&8S Îq–Žæ ÖêÂ×l‡'‰Ór2*гžA|>ó9¬‘}¢Ÿ¡)@jÞ)F�êôÓ3ÏŽŒ jxh[þ2>ÝÅfy ¼-Ë =h‡ d 0�´¤¡±(JMA§XȦ¥PØÀÉŽ™4 +M©EKZR•pÏfÜüéâ¼ ÎoŽ“œ¤3'5Ð Rp´ÓKï„§¼ä¹¤zÚ³LùÔgšøéÏÉÔ …Øb>ŠP/)´sièÓú�ˆ"f¢ÿªèE1:Žòé£b ©H7¡S’ž§+u©l`*Sšvõ¦8ÝkxÚS 2\BjQÅYÎsêo�ij}ž O�Ì“ª¸çUß±OÇôóÿìêWi‚»¾&¡Y(GÐʵ²Õ(nÕ\M!×¹*«£v5¨Ÿòª×½ö5¥¬`¿9Svtµ†M)b˽ÆRWR� gd'›Ôʲ“`î4 T£Š“ÎR´Wm8J{Úš¦MõèXëSVñÆvI…h1$º¬ÜîV*tÝÐo�‹W‘"¶¸(=®K“Kƒå6÷¹(�nJzÚ½êRØE×%jv�JY<Ö¥»s*x¡ÊÙ©z©HµÿRЫ^®¢¶"]-|;äÚmÀv#²¥m~Ûº_§ ´¿YiÈ>*ÜàæµÀ“Á©Jé$a3¸°tB2„Y!á S™9¦AdS ]¥vø²Þ1Â;bòxÖ&6'Šó â­J¥¹íÍŒÜZ²¾Ö¬ µoZñ«_Šò8®>²o :ä�”¸Gö«’{ÊdÂÖÔÁ9Ý«tWåIcåÊã¬Ì™·ËaË‚c‡zÑl�AÄ2g:ÍÃ*íŠÛ ÐѼ8¬¯Š¯^Ä|V&ä¾kͱm—…dWd¥Âý5° d€a[¸F– ’W*áâ õ› ~òa÷:eJS['(ó¥Û’i.sÚÓyµ�9ÿ²Ü屿>w©Q|jT›–Å`5XӤλ¬tFø�õ�IUë<ßzÏñ’Û•Œú:Ø)±‰Í¢c[Éë[6qšMƒgGÉžvµ3’k{6ÛÅØ6w'â퀛¾÷LË}ns§Û:ëFõzá­ZWï¯Þ3Âw}õ}[×6·Àq*pVœN?ú&>ì…Ù8}xO™ÝlŠÆâŸ®Æ³ÞŽSÕã ß´kF^ò&¡œ*_yË“2§°ûJ7@@eîÞÍÛ)6?ÎmLë�ó»ç?zJ‡^ô!ýàogºNCco¨sOêC¥ºgXtu¬k]ë\¯§×ÏÌíÿ°{û$Qø<èÉŽò³£ûÌi^»<Úþö¸? Î4§7�ì�w”‡ï³Õ³Ž ס€ ô MÁ ìÃÿFFöžãoæxp¶¡ùη·ä'ïÓÊ[ÛâÄ´æCÞéΛÄ÷Ÿý¸IÏrÓ£õªW:ëéú÷Ö<ö7ñ¬uÎs\û|ƒ»zï½|£ øJg‘ñ_K$ŸÍ,ß79ßóÍHôIõi]†,ÕüJ�Õ…\ FM€nà�xŒž8>Ók8‹K©•ZeZn‚ÝL¨qDzôDaL‰F… ;Ô  ~×I`ÁÍl…ô ¾ÝÈéÅÛ!Îì`„„%Ix­ÏìéDqÿ`6GFaä@ æ Úú@n v`ž|`‚à5ù `™àC¡ ª �´ †›G¼`Ä ”Ì Úà ‚ÙIì Vøà*]æÅáê!`H¡!VÛ F¢ÊÖ•bà0qaRˆbHŠ!4EO š!:“FÚL nÊaС3Ùa â`Ú ò¡á"â ¢+ŠÇ!æb•%bÎÔ¶-iˆ:eár¡šÆÇ\¢3�!`q€~@'JÒ'~F(fÃ(@)Æ”„†,t£7ª¢;°¢I"”£9Êb¾]xeG$‰.¾cuñâ"NI#Ø#jÿá0e1ì#?®F2‚ páØÛ¤A>c4F’p­ (ºaGd#lãdx£7 ¤ìA9šc9’GŽDx}$üÁ£H: ú¢””N= ã=b”>òã>ú#:S@!AdAªÕt$$,äÊFšÜCª‡)r#EÊ‚E¾TNžYòd„`ÜM@¤DJEQ%M"e¼$‰Fn$S’ÄS‚¤Tþ%¥É£IFÀUZFVºŠGqeWš˜K¾ä\,¡EY¶„YŽN…N²åg¸eHÀ¥”%ENÿ&K„^æå^òe_.!`®æO fUZ!V"Š#”b.¦95&1€ej™H‰&>T&Bª¥XŠ”²-VNx¦ÛÈeQú&iŠG^"Àizdj†$kVgkRå/¦lÚ#m.ˆm"n gð¦�ø&pš¡Ÿ´ƒz®§pÙg‚r‚fEÖ%ÞAUi.etvÀtR§uöç¹fvÆEš!fw^ÆwÞfcŠ'oDæ&˜§Y>cz®§z¶çŒ¼çGÄçD.'}¶DsÆsæ§~îç5ú'‰‚ €Â¦vhe©SmÚfxZË‚¾ÆL"NMÚ$„vˆ„Nh^¹§qâ†*ghnèhÚ§sšf~Šèˆ–¨’JÿÊí¸�<)”>c±¨hÞTéР*š ÁDÙæx‡|)èPMhè6£…ÇY4ãбÈ-©›f“Bi”šá”¢˜•Z)–Úah Ö{~©„i¾Œ).!Ι‚GšÖšzÑ›.êjÆ©œj�”.•Þé²ä© î©´õ(Gø) ¢Š ö*sªK%ª1*ªþ¥£Êi¤^ƤRjŸÈ˜—øÆoô)˜~Ž˜N™ª¦ÞÈY„Rª«ªö‘“>ê3>ã«ÂjkÈj}ÐêKØêŸâj êê ÒŒ¨.ǯn“°nkT®êœ«Z%«²Úßœ5k=k¯§J«§R+¨ò*åI¶î ·Öÿ+<&É£B*¸†«�ŽëC€#¬å…³f´ú©Á~é§ê…-Nؤ«½>l&I’ì«Z…†¿þ«*l ¬¦ëÁ~¬ÇŒlº‰ÃB,ÊjœÄŠÅ>”Å^ì,³êÇnCÁ‚lÈÇÈvl¼JÊɦ,ÐNÚÊF­Ñ>ãþEHÈ€£Ì–+Íž+Éö¬ºâ¬ŸGG.,¸ülÐnmu íVíÑšaÒ~†'”­Ù2-ÚÚ ÆÖìÍ‚¬Õr$Ö~‹Ör-Ýþ”×jØ-ÒNÆJ™íÙ¦-Ú®-Ôò¬¤mÕ~éÛ’DÜnËÜÖ­ãVD®äæªT bíÐz—FXÔEÊã~ÿ.èzåZ„åî溛æBšÀ]kè¶®ëÉèVDéêÔéªZMm®”•ìëî.ïjz ¦ÎnÔ®E4ŸJÃö®ò./Vüî |¬ð’ñV„ñf*2/öf/|þ.ôFïôæ@õêò&¯ö–ïò:o÷ ï÷6—B¡ù¾ïùrïÁ&ÉåÎêd¬Oûz.üîïë¢ïüŠGýš«Tà¯w@œ·ð/‡®ÿ,BÕú°)Ë„óLWpÝ.°Ÿ60<=ðoD°wî[°-©Ç ‡�kÃ;ο0ÿ6. Ï0 ×° ß0ç°ï0÷°ÿ0±1±1'±/17±?1G±g\@!ù,L¾ÃÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹ØÈ±ãÆ C&I2£É“(Sª\ɲ¥Ë—0cNôH3@H‘$GÊÜɳ§ÏŸ@ƒ 5IS€Ñ£Š’*]š”ŽÓ§=¢J%Cµª­«X!iÝ:´«×¯`ÊõYô¨Q¦h=…*5jU«X¯nå:¶®Ý»xó†-k6-ÓµNÛº}K&®Ü¹�ô*^̸±ãˆ|‘2•E¹2`:‚{.lqâÇ C‹ 6òÙÉ•)_μù–ë׆m‘žM»¶í“¦ M­0k¯a¾M¼¸ñãs¯ZΜ·¬Õ‚[¿û—u䨳kÏK“¹÷ïΡ·ÿ•¼úõíèÓ«'ëñ»ûUá}G>Ýü¯õøóëÇÝþ½wç�(`$˜Ë�NG�aÖݷ߃F¨ÐVèß¼ 8`�"˜`} ž'áˆ$îW¡…. †�pØ¡‡¹(h_‰4Öx\N#Å¢ãŽÎµâã�§ÉÈ�&idH& c.Å4é¤/P6Ì”’Tiã•X††c;òÈÛ�@ I¤‘E&©$ŒN>¥uSS¥$YÆ)g^[v©c�`¶ä)C2Bf™fæ±dšMBé‹”TZ9碌zU§�x‚¹gŸš¨ hj(¢n*Úè§ îôh—‘†Éç˜d^:¨¦kþÒæ›¡Æÿ*+K£z™ZžzŠé矪fšæ¦l& ç¬Ä;‘ÈÚ©l,{NÚç³ÏVÚ«‡NVbmƒ ¾ «±Üv«²^(‹k³ºB-¯�®ZŒµ•`k�¶žz+¯¼àŠ›'¹§š{nªéúÊ®»¿À;ì¼s[¯�ã’«/´•ÖâðÃxD,qµ×º+pÁ{p— 7»ð³É„,òÃK1ÅíZ oÆ,ǺñŽ;û1#"�Lr-&ŸÜä¿*kÛòÏ6v”TD½ÉÑHÏ¢ôÒæ6âôÓÊD-õÔQç`õÕbd­5Àc´eM`sd–Qª”m6Ðh%´"E�ôÑK3 íÓPS½ÙÕXk�u×)}ÿ6Øc `öÙiÎÓÚmý6ÜqÏÒ4Ý�P­ÌÝxç ÷Þîªä÷ß¹ ^¶á Ç„xâ‹oÒ¸ãÐ.)9åxóâúë|£´9çî¹*¡çÞÒèm—~º¹ªÛMXå9¼{æ}ãØÝw™Ùî¹îЧÄ{Ñ?&­t�ÀÃ(µÄ¬_m¼ë±Ÿ4ûFî5?öíѧŸÑÚU´O}�ÖÏâb$}¯ ÷„±Ëî÷¼À´eŠËÉ ñЧ¾R„}î#Z®â7¿úi/jø{‹þ¬Å?ÿါ ñ*·zp!¬‚ÛÞv:ì É~RÛÌ+QÁ—ü€ÜàÕ:øÁ$„#ŒßÒLÈFM…l¡Kÿ^˜¢Ê0›áƒ—>oÑd|ø ·¸È�Z]þ‚ø=•.qaÀ e˜Ä%*`3Ö•ç)r$)í!IØ8úpr[ÔŸOòÅĉQ0Gœ!aÌxÆžm«F4¹¡Gn’ò Æ�Œdl¢g …¡rGkÖ t¦\Hî5<ÃVà‘-¡Å=ÎI…*W©‰Vº2°ŒeÎð  Øò–—ClÒ!R„&ŒÜ€#ÛIIz•üÃ%ñ–É=m2�ü¤kBÙ Q¶±”8:%xx³JVº²••ªT-oiË\îreòå@€ÉÈaJ¥˜�œ$2�bILnB“×ã$’$ÿÍ[PÓ:ÖìˆDLÉTr³›©ø&8ÃI¦q’Óœ†á%„Ô™œE¶“y‚‘Qˆ°e¸d.ójÍ Ò3£I5PVL”c£hCºƒ¦¡ U(Cùe¦%A4.MÜ�J—WÄŒ‚§ÈK›Gí‰OùéSž,é4OZÍ”^"D¼P*:Ó™N A„*†}4¢�ö§§mÑ(P9Z¸¡2óžÎÌ'4÷y ~þóåÈ@/À©v³ª ½ê�²ºUMô©ëÜŠÀ*±b%§-3+HÑ*Rµ’TΈ¬‚.×�Ì5Es®Xô¼zÖRý¢¡úê ^¶¢,sJ—Ã^±,S¬ÕBzŠ‘ÿ²5©�•ìt.C<Bu$™ýÎfYôY¼ê•I£Ý(WÓyZ�–Bîa­OË£\¿M¶9 ­m‘*µÈ:c²€é-a.\ï WCÅ­êqùZÝÒþU áˆj—S:Î*HAhDgư«]ÇÞ¶»º o9HC‹¬!Iy™s^¥×ª¡Å*¡vAá ö84Aˉ(4Š{X¾ÐýN}Ytßéä×g±¥§2‰šV£®•»Qó.x×"Þ·¸UM5‹‚‰¦Ù$À}Ó„”á�xg(៺ƫÎq2EžP“§|žºîˆË“ÜÝ&_ Ixʜη…9«´·Öð]|�ÞßÞåZÿÎgÓzν~#Q]ñºíKUjfµ×ýî{ïûn[|ñÂo<ñQ5Œþ?Mɇ+KãjX$9˜}Žqf ¦~•ƒv«°Jœõ 8�ÜGÞw6×{â·z´A;îq*ÅhFŸw5ìiî÷'ðÇ…gxô÷{²'u©@uûÒÃðN€y2€­V€Ts€Ö1vÒ\~”vxã€È"H�l—ØoˆxHw¶á�ß‚‹_A‚Fh‚Ø~«¦‚ðׂL÷‚öuŒ·4Ž·+&`ƒ8Ø$:&<è>85@ø B¨ Èc]h5H¨J¸„Ï@Îáw{r)ô Џˆ‡o[ÿX„Þ!RAH| ‚Á…ºV9'ˆ/)H&+H†¼‡x‹¸ˆÞ|2HƒÅç†T#yZ'€JC€'ÔV«H(™×{ˆf™x„ž·I¨!‚8ˆ½Wˆ†x ˆØ{£¨ˆãd×qG˜È’”xc‡â.ÏÈ€x³‰äÒ‰Fò‰òç‚ÆxŒ¥ƒi¨4kh$ª85¬¸u;øŠ=‹¸%5YUrʈ·X‚~¸‹ˆJ(ˆ„ÈÃHŒ�’ˆÇ˜Œˆ±ŒÑŒ Ô6(m1�df��X}šø…(†ž8†ßX†á8ŠãXjù§†ûdžé(�È7y®8 °ØC²¨Ž´}õÈ£�U`/`S¸ÿ2?Ìg$L'9³t‚"ù—âo‹P”ø!(=>·%9¡,¥£,ÙFN¶”Ô(H“1$Ì7\Ù•^É••bƒb9–»G oX b`'ªir)c9 YÕr9—™”æ C9‹ÅP”‹p”BA;Îa“?Sžõ•À“Kç“9c—³ y95ÞÅ—~ÙI‰ÌF�i'Oi'Q)•TycVI[A‚+•b˜¦ù•aù–d¹{’c®ùšiÙ%k‰/m(g9—t)Œé˜¶©—’)~C˜¼!˜>B˜xe˜ˆi–Tó“”� `Îð›\ƒ”Yh™K‰™Ã©™‹•�&•ð™šZÿ6šyRš§yž©©š6X–­ùš®› É–GÅp&™&¸)—uÙœw)”½é’{i”Àù—±d™É1yb.…‰šEғ˹˜úÙ˜xÙŸÐ)��Xðå—9º#›Ù%�IN­5âI›.bžçišé©žÃP–›ážï©–© Ÿ/FŸQ“U+”Ÿ²Ðb¼i&ÿG¡ãw8ºa¥‚+>‚ Ç© &À SÜ9ÚXÊŸ<…>Ê� Q™üч�¥Zº¡:R:óÓffâ�!#J._ú''zš)ªž,J.jð|2úœ5J(7ª›º£4ª N2¥Tø4A _B¤`b¤U…œ š˜ j2»ÿ¡Q ™‘å§Ö¥VJ¡¥[š�]â¥%ÚqI"¦ÓõeÚ,gJ&iŠ¢¢¢ë¹{-ê¢q*us*¡uš&wÚ� ¥{Ú§:�Ú‚z+„ú#†:SˆJ&Jê]ãT¥éH 6™UZ�Wʘš¥\ œÊ!`êqý$ªQ�4$ª­hzªHŠŽª: 5Voúª³i¦óYtz‰2ìâaR¡¬Ã¥JšUs7©2¨B:¨ÁÚ ÃÊPÅšœÐ™¬¼±¬IÒ¬½÷¬J©Òj©XZ­×š­²­æÖ­®1ª{RªFB®_)9oé�éJë £±ú¨õ)¯ÖB¯Qa¯ú‡¯ŠÊ§¬R�¼ÿ*“ v"CJ¤N›¨Êée› ‹$ ‹x{³Ñz¡»s©«©º8[nܪTdú­¢y Sk ë•";–$+fêêª(®tJ³´:A.Û0ëœH’¯5 ­@ê«ÿ ¬…  ê••r¬‘5´£ç¶yp´Þ•´�X©ëã´˜*ŒÍÂ|[ëq{ª $[{ªìI5Þ¶xÓªîÉ®1j¶²Š¶,[ kÛ¶û™$pû+ª÷§MK·K¦³+¬x{¤zû'|ë ~Ûv1»°þc ûi¨a.àâå4FÕzŠ»'ŒÛ©4UµS¹X;žZë¼›¦•;5—+•%K'+›�ÿ뮑pGÔ¸B£›°÷jº3«¯©Ë¯+ᯭ[!;»‚yÛ•{;³È1¤û¤º{ƒ¼‹´¾+~À{"‹,Ä«_ÔÙÈû´NH.Í+®Ï›±Vë­=®â{±ãz¢Ù+5ÛKNÝû½ñ®ä{cæÛaõо¹û¶ë·û4A“Ëm›�Ó+h.Ä�Ã"ã’x ~W Osº±Æ?ø˜m9@‰±“±%K&t¥ç`xUÃï-�å]ÅpŸ  9¼ÅÄ@^üÅ 4$JZŸ¯©}Y³B*eôu437ÌÛjO³Ãÿ[ao•³NìÀ­&hü4«Ô“ƒ¡Ã9Œ3\Ã7 -[,ÇuÿÚÃmñÃÄ+\ Cü=EœmHÜYL¼aw¼okVUR,†ÏRÅ‘uŸ™Å�ÀÅ9üÅ`ì"}2ƳZÆj§7hlƒ…4m¬o®Ç!�tÌTÖadzi®¦Ç-©&æÇ¢È ÑVÈ�sÈϒȽl’Œ,Ž �´N2ÉÆSÉ�vÉq¡Ä±É'ÒÉ?Å�3Å£ü_ÿkÊs‰ÊªÜŬLa̰Œ¶² z—SËpËlÜ8o켜 ¾Lauüd�<ÐÆŒ[È|`[ñÇ«ËÊâÌ={)†,ÍCBÍmÍ>m@ì4BÌnH‘F|5✙œ`8Bœ¹Ò,lÊÙÎ]ÿfÅ÷©,÷ÙÞi±W$Æ3KÆ®yN(Fi¼ZíÆZ ÇN£ÈÞõË)ƒ-ÂÜ%~WÌ�¶ÇhÛÇA¨Í4Qуì1 ã©H¢ 9�+8¬ÃÕ¼È-£Û\Ÿ±VÒØxÒGLHI¼ÒKÜÒs/äÓë,ÊDWÓ¥|Óv’Ó;]E�óÊ?ËAQ,E½Æ›�Ënw »¼ÔiÝÔ Ì¿Õ}mT}VýЭÑËÜ^ÝÀ`mu—BÖX| ˆŒÖ­Ö� Ò�,Ò‘üÖúhÒr�Ò‡1Q+:’•§À×tÃÎmÕ6�›8}Ÿ…MGqƒØA ÔV ÔWæØ¶b«€Ë�ÔmÙ±ÿ�Ù»�ЩE! ÍÝ ]ŸX�‡Z]ÚqtÚ'( †šÏ¬}ÊzÝ,ÍÂaÁ¤ZÛ� ß"šÛq}Ò”˜ÓžAw$Q!.ݱâY’SÃ)yÜ-)�‚Ý%„-•¾sØÐò¯IÝñbÝÿŒÝØ·Ý”­Ô� ÈRãÔ¿¶âwç­—·Õï»í�×’òv#‰*þe]ß{rßÝú­àÚlÛÑ5Ò{}ßÁYÌ÷–�Gàˆaà#�à4n*\U’³ãr¨4�5:á;RáätáÏ�áz¹áŒ=ÔñØÞ!Ù¤ÇÝ-9(î.*~'ù„V�Þªã*‘�í“à6߉ vÓ�å¦Òã°�ß@ÿžµ!Ýß�~äRáJÞuLîpN>PžRn 5^½‘ÀàTCè>"7,èÎêèå:æ·$æ¢Þ'¾ØqQ¼ æ!ŽÔ#ÞÝ%žÖ'žÙOÝ s ÚØ,-îŸ/ÎÞ}>å>Rz€^䂮㭽é†N &Þ$×<½áÚÖ¼±kýIJäcÙä÷Yà"ràämì/]åFR3¸5 Þ ¢þX®ÜƒÍÜnØcþ,­>Ýg^ݱ~Ýj¼æ"^Ù·Û¹ÞšÝ뿾'ÁŽç6›-Ä^“äŽìa�¤�>èÍ^èAâã²¹œníÑûß³Ý,‘žn“^m9Í—Òyט>îšNå þ'è.ðê^ñ¡ÿ®åñ×eï>—Ë�›Í­C4oïeîêXë²Î‹ÿNâ&5qÕAú+m ÏÇyÞð~îÉ7Ά9þëŽ/O³Ó^ÁŠÎßW�í¯í�Àíbéí¸iò»Šò™3õmîEòòW.óìÞóîÞåðNáòæô¾êCrï¾ÕCÿ€EoëG¯ IÏëKßô‘öôWõ{îJa+[ºH2 ˜Ÿù{ ”×4o‘Ó.õ#ú7-Rƒ ¨Ÿú~W|׫Á¬é›Eà’i_.C¢ùÿë]9M<ýåbÐý†ò¦K–¼•QŽ*Ùuþƈ\ƒæ¨íÓcYîbëây/I�© Éæ.f 0ÿbÅM—Aߨ‘dŠ@ù¸ ¸™�û�àŸ?„!úÛ$ ¤/’¦5©¯ú´Ç†­HËàAe c¸È¡-ˆ½L4UQÖÅS5jdÔÑã$� ��$ÙÇäÉ)UnÚ´qÖËH1="T˜�a1_9íäùÇçÏCA…^”•ÊèK¤³-eZ3!IhQyNý%ɪ$Yµà J•UaŶ"[iÌH&ÔÒ¬y3§/ªU¯ZU¤Hè¡Xy�¦J mÌ\�“¼épQĹVµ.fÜØ1€®]ë*Ê‹(Ѿ³mÎÓäçIN•Ý"]šÏiÔ=T¯+võj2±eŸ<Ù:,ÿQ³H9wæ-X!.àÁ7÷¨Ö¸ ‚É 4(ºðÈ'z©hŠèð�?†|Jr$m“*W¶ÔxVfG¶ ¾�ûèÝCD÷ffÚÔ)T©qå*fù«íUÊÊm´ŒKϦõt¢*1I꺫²ùúú 0Á#¬!èlað19ŒŒ«É*»ì¢Ì6{„7и«©4ÓP;Mcð5Õd› <q#+©ÝxË÷„‚»ŒŠ;9å’ó±3ç0<,:[¦«î:"OÑ®£ÏDòÎðú/%–\ò+’™šsÊ-§b¾ø.Š0©ú– ?hôÛ«þºúÏ6wÓ@3ÛJ®sP(�’ÿp -é¹'m‰«CJóŒ,ļF”¥ÄS Í)IsñÅaœ‘Fcë2Ç‹ÔìÄ%�TFH઴²£#‘Lr %óh²àŒ’"‹0ªòJF²ìλ.¿Ì!ÌòÆ,“–_Ù+t.6åSÎ8ç)ª:õ›«1ÿÀâ³OóÒZ+PõpJ“' *Q¾ý«Ñ\.6ÃI+õ÷Ã0µlDNaÍÃSÑB½eT>J5Õ6{H•Œ.­°øb[áñ‘�:“•V\l5ò¸] ê•9÷�T"b­3–Hd•UfK.Á»Ø 0ÉË(ÝiQVMBÕL,² ´Ýk[¤–:nYpwqz¡ù[¬Ü¯ölÿÍOc”– S~«°+Ù)²ƒ¡Ë.Dõ:i¿ŽsÔH#Šk\ëê§ÊD$¸¯^5Ô¸VåÔ×&®øf+2Þ¸c_ dì�͵d^—ô9n(««ÎVŽ®ô–Y›/ÎY̬ÉD�93�ž{變vsíz¹]zæo£zjx¯"WϪ­Kã?×åH Ãû—²ÍníyÕ^;3­�{sI¯Å³îÝÀ;ïX Ÿ°WѺ6p‡ ‡-U^ÒWñÄ[ÅúUÆÌDãtDò#)èdš e_óŠDîJ¨£–SØ'¬›�.Z¥ëYÿµº¹­ME�}1;:Ý.j×Û ïzÿ ¬Hx]ûÙ Œ7¶²�íAÎ;š÷Ü–¯G9InÖÞcîæîuÏ^hŸSÄ%ò•Ê|5BŸúÒÇ*Y¸ªG¼‘_`è·ûá�dúë¡ Tö? P;Í¡ä,híLZ§+ ­µA«dëu±KZ·îS»pA�ƒY)Ñ<¨„î Zîæ"/¼8Ï{÷j”¾‚‘~ÕÐn\Ù^ÞÉÃ%…<㣊à†(±"‰J4çÄ'FñJ“£b$Ïä$,jN‹ ,£B¼0êì<#cµÞµ“5ÁÇh¬ÏçÀe'ºM�wvPº¶fË>âÒPÌ d,Þ”.´àË�ü¢Š"=ÄHÿrï‘1©¢B~� Æ(ã$çt¦³t¦ÓˆG´�âtÓI&}2O|„(·ˆ:äSŸŠD7Sf˜TnŽ8D]'¬X’-ÓB¦Ó¨Ë5òÒ>5¡0ug)¯˜ëjw,Ý1OÉG‡.o…Îd[é¢YȪl†S±æ"µ—MGî�›¦¬É7WÊÁ‘³œæôB:Õ¹ÎM¾o‰ñTÆüB'dPŸûüMÛPÄЫ$£_‘„.p¡µüèýx5R��/±Ÿ/ó#Çìe”˜aÙåµ[ÞI…i#éXMJ¡ M3R‰T$Àð×V¦`� ¬§h¦°°ñ•RXc&3Ù•ÿ¬KFe-›+dC³› È6Ñ�0å3²RÈ-R¥©Ìh¤WÉ`-ÍNrÓ�Ä( ³Em_LÄËjÉ;^U¦$|ŠN±ä³/Áa�Ûˆ_%vA”šÌlÃ�7£ÌrcÚÁ—$i#ìf7‡Âî �Ó+ÍR”$¢:MD q^ôÎÑ¥]ù«›—Á6E‡ •rYÚR=¶.‘ÍÌdaÙË)³› ¯S< ÚŒˆ$¤MˆimTÛ¤¨vI¬M†kMÛ_È–¶{Û˜Ár»,’ðv?¿Ý@pY‚”â¹µ/¼˜[çB7Ò}§vT¼âš‚'»ÚåwOl/ã(§À &/0¬^~¨½ïÿÕa‡�kØ-!lŠÅïcô«þö—)®,f¯Dà!ÿ†VÃEq‚—2ÚÀ$ì´.ó)VÛÚ-½‘•„‘s!üNWV·!ŽëUHlb2§ø¸É�òr;ÔÜÙʘÆ/ÙŒ�UlÝ“ì»Ûõ±wÕ"dbˆw$E>ò¿” Ø÷Æ·PöŽ”�wß*Z¿Yæ¥r¼¬0gÚ)#3qÍì4çBÍf³­ÝùÑ«òâl'ºåÓõÝs|]q÷¸Ò@¾trÐ]tÔtºR7üC±ÓFGø]·‰b5“ŽQÕ¥2bi!·êué5jêŘØÁ#|ë\·ËÁ²ùz‡%Na’œ;i¯síì>àÉý×>úœaìÿ4bt:W,­osß [mûÓR+W´Ë�ÿí¿G:ðyóñ&rEJ‚~Óê62Ù‘œ½FVæñþ•ü²(?û|_2çŸét¦€^-ø}é­Žp…Ëê&«� ñ‘ Ï< 0Ø Ù[©Ú³½³K"¬‘0Þ{#gð=‹ò­à›­á#„{>äÃ7妀�1½Snk´çƒ9p¼£'û¹¾ü1w ¿¼¨A¦¸A’ÈA²ÛÁºŒ +!LŽ\)B‚;ÂÕHBÔcBÕs¸‚™Â‰{À 1À¿BÀô$MëBJ§0\…(ì3ŒC4Lïr©6Açëˆó.~BÁ8¹Ã cA�ã¹êi·´ú@ŒA\ B C,Fž@D:b¿ElľxD‚ØEI¼ JT KL8­[8®Û£'ŒÂÛ6Œ½O´ÂPDÀ,,E¢Ò-T¼U¤@1Ü” ÄEXl—4<µ LÄZ$©|„—“/ÐØÅ^¬C¦ÆÂËÃaìChô¹cŒŒd\ÆÈ39ÿM{F*K:€i¿°è<È‹¿äÐFÑ3ÂT1½6Ë¿qÜ?MÜ8NTÇ•aGÅwŒ8§Z–yŒšz ƒ ÄG2ÄÀºK¾5\>d9[ä;}<.]䲄¤ŸdÈœÛ3bœ›$£±¨ Wy dQ¶ÑC�ß“F!§U\…’Ú <¬œ ¶B•è 0jº‘¡°3¹…/ÃE9Ž·Ú#öHž`øÆH§Ê�²|„ãè8M;‰ß» ±œ­ºô7¦à ¹¤(§±¨ÅãŠé@"‘¥$ˆ\áæÀûÁ¢™óÛÈõ³Ê°ÀÊ÷ÑÊ+áÊ©óJ;ËJYLžt?N9ËýéŒô†iËCxËþŠKÿ֚˺ôÉ»”†âK¿\ ÀÌ Á´+³4ÃÔ-ÄŒ@Úl̦{LÝNÉÄ�թ̸ÌvzªbìˆÎ´ÔÍ8MÔ!Íu‹ÈåœÈª¹Ê¼ÈÊYØJ=K™›€Mý�MJ¡ÍÖLÜÈTKgdˈpË/¹:¤Îd Nñ°Ë›S—uIÎä™Ï¬hÎXxÎÛ”N¬N/”„ëœPÇ\Š�Ðî¤Ì ωÀÌcÑÌMO! ö¬÷døì>ù\/®¨ÏÔ¼ÏÕÌÏÖÜÏ=êÏÓøJåµMy+ÐÝÑdPñpPÖ4OµˆÌ… Ë 5Î ÅËV‚+¸PοD§ÀT ÑÃ4‰ÿÄ´ŠU‰¢ÈNÝN‰ÉôBðÏÖ ˜‘Ñ`äÌ#ñ̃À—(TCÍуØQ¬J²ÏXÀOýœÎ®LÒØ\ÒÇhÒ�„NÂüS´Ü͵tßÎÌ€P …S/50ÅвÑPàP}R5¥N6µÎqr.ìÔ²9MË:}Š;ýÎÕÓžÌLí8O� QÞ°ÑF1ÔCŽ.QÔCdÔµÕ̽-RI}MJýOKu L%KM…R:•Òø´*] ¸Ä•,åÎ--Φ‹ž í*� Sæ4SçDÓo�ÕeQzÓ”ˆS\u„½�^-”<}Ññ”aN-Ö@UÏÏLVe ìhÖ-)MÿËcÃý:—b#FУ›¸%ÝÖK­U{ÌÔmHãÀ`“3a�ˆr“sÅRÐR›àRSmW u+U%VuU{=Y˜Î|5‰œTL’ ƒ[奀]QuE…mHôlØE�.‰Øˆ˜.™9JbUŒÅ2�e«óèØ¼üX‹ Y‘mŒnMS”%,•íD–mÙ—}–˜5šý›í×Smä„×1ÍÐ2Ý€3M · Ú%Z‡Ø×£MÚkÌÕ¼u†�ð|Ú{Ô”Œ) bcí ÊÚˆåÚpÛ±¯mÑ¥Û¨�e ®²"�­ÔµeÛ£Ð{}ÛFˆÛ’¨¸–%×ßlлM×]Õ[ÿví/wÕYÀEÁ�W­WÃ�]Ä]Ó>(Z7m\•S€¥S�õN‚uZ„ZÌU@ÙÜÎ̓Ï­]Ì®Òí�[Ô%[Ó1Û0Ý£ÖÕÖ×eŒ¶eÞ�HY•½Ý±ËݺµR"•Ù¼-†½Í EÕ¿5£x=^­ðÙåZ¡]¶“€^•^8=ÑêÕÕëeQõEFŸà^Ìí“Vß#©>a<ÛBþýZžÈe� ^~¢c=Û¢ŠQXgvn –@š^ÆÈŠ ô‹Fü¢Í± ‹ˆ‰˜‰éçTq†a™˜·±ç]Žx>®_†æ¯J ŽÃy††zFº{>Ú|^… ê¡îç¢v‘£n�¤.èž§¾ŒòüœÒøZb¾¼¬f,Š‹®Æ³f® bxæèˆf²6J é쎛Xë¶6éÖ–UE†ˆˆIhÎQŽ—n(™žéÿš¾iúÉébØégíiÃþi}Nl"Zì‰A¯ôJŒÇ‹ÆâÈÊŽÚ"ñÌìÞìˆîlE|,¾Þ„e6‘ÑVˆÒÞ’]8mŽîhÕHÖ6EÚym’&7·>iþí’Û~jÎ9Ýö\t©Þng¾g�lž¶&Ÿ®ÍÖPîåfnqîóbïþÎf¹ªI²°î2ôÌ& Í–š¬p¢™­df‰ñAFÐÃóæC`VïÞòŸ fEÓˆHX �8øéЛ;ÇÙÚ.éƒü¶ìýîoñýoûƒ pÐîk8éiBÀ>ð耫°gãNQ¼$~†ðT‘p,gΞâÿª) G–¿…ÿ¾T+s®¨Íï‹îohß�Ÿ ñm ­ŽÈñÀØñ´.†µ–®ªÆÑ¹D>‰"çplDKøæO†ˆ‹C˜-'çj(Pµ0…¨òáFpˆ¸ -¯2²örTó—p —ó3O‰4ßpò¼níhó7K9:ÏXM·s¯ÆsÒÖóˆðΫès�®ñ ôŒB—ï‰DÀϹo“xôYÇÏS’“=KÇô½~r¤ÁROOP'n ÉrÂN5²&1ǤÅs1oõ2çìê¾v6ÏnßnW¿\ÿì^Oq‚ÄóŒF爵ŠÔ6ë÷ŽG�m Ÿô=lôj§ÿÜVB‘4™mŸº¸ÐëQøm¿ÆiõÁfêZ÷ßjw‡wV's§÷\žxZ÷p|ws}‡ó*˜™ëÈ­íÿûêÍ ë§Yïinok®´vv†ß ~ê±st‰×ï�ˆôܼZæ=Ã0 �çø+pè ì�O:’'1Ÿç‰!1”wny_yêny§—ÚŽ°õ™÷zöFÀ™c×yfx°&x±6xöFx¢éB‡í’6‘¤_’¥�ø×pyl¯xI÷著ºªwˆ«ðŽî�7÷É®›¯{tg�'²/û Wù gùÞQü{×4íF?îV¤Ô–{I£ûœGñ;_ñ�÷‡ë¾Gvÿ")zµžïh/|9|"oz#ú8Aò—>ª�üÉ÷Ê×úrõÕ·Íç|ÏÿüÐý³/ý–*—á…f¸ààó�‹ÎžÈÏO©ª¾µ^ëÈ& {µ«¤rŠj¸#ÈasˆU[,øè Bb *kè0Z´CȪhqÆŒ‘6r4áñcž�"Ÿ‘,‰!GŽ"EÒjéòãGF2g:¬ÙðN[:wúê)p•Å‹1:*jÔ¦2gJw1ýåô©¤¨RP­ à*Ö¬Z·r½Zõ+Ø®bÇ’-kVë×*Ub±m[ÐàÉG�ææª‹^NzŸ>ë7ÀV¿ 6eøð¦ÄŠ ÿ0nLæ1äž¾,樜êòPŒ3gÒ²Yí³‘Ð;wB*mZêÔ?¾%÷ÑB†6!N¤TVæY)7Âô¸2dïà&~ÏãòeïÍ2‘:Äyk´NÉ?oãÎlô¨M¥Î˜îâëTêÔ°gÇ“/oþüØ´kÛ²mÝêõÜFusÝÍ»×û_ñY|±b‰5æd�IF™e˜e¦#�ÕôY5¡�-¦�–j« ÔÚk±)„mQ—Ûn‘Gœp½÷Ûq-Ç s7å�t�hÝuŽ ¥wÞý^T~¡7$‘E©{íqW|óÕ‡‹^œø˜ßW��ÕŸÿ™ €P �=!˜ÿÃe©äÆ ƒA(!…–†a†º×¡‡ F$âm$îvâo)´âJ-Òò¢r1*ã…5•'Ž×í¸TSÞ)‰�FZz)¦\!™äœLÒe—MxAy_TZ…X¨ºª–[réå—`XQed*8šž�&tnB§"®ÒéIcgm7U"Ÿ+ù  ! Zf™0ƈ(�>ÙÈèP9꘤ÝI d¥™š{î�›²G,BM‚Z“¨QNi*`¨~µ*«Zr¹ ¬`’1«,µ–y¦ri6´&¯£ù ¬°ìd,²x¥gJÍŠô¬oÑ×"µ—Y˶£)jÑÀ�bW�‘ò5i¹èºüÿ2Y꺵äIîÒª}RâG¯•¨U¾ª¶º/RþR×±™ ¬k„ “æ&ÃrÒœP�³Ý)‘²í©bŸWRIÓvüqsÎÍ8š°$ßš‘·Hq×ã¸àµ 3Ýu ³’oÁ÷éÍðæ<¯©=ÿôCs‰Ø$Ý1Á›¬ Âö 5œ OýpÕ5…ˆõmû"m1p^ÿ–ø3bSKRfŸ½SÚ•ÜmŽn¿-îÊäêg7î.ã‹Ãrñý¤¼;nïàA â‰/Nmãœ1ÍæäF½Zï[�lç\~ε³¢¯Dºée¢n“êÏA×úÄ&%ûÛ>²|{îñcº{ï6Oj_ôRYÿ<¾­Âò?“¶å½.#¹zЮ$§0ÊaÈrz‹‹õ4w5ÛÅs]06œÑ%iH£¬ÊG!ôYD2’Y S«ÙÑ*¶«’übx)õlÅGÀ¸!m6Œò0^z9ƒ˜¤!Æbj!œ�@›�Ž€—飈”ÇE.7û"°|$Œ-rqŠ-Ú\¬¨½ŽiG;HÑà×:èÁÓÝ&„ª«U­HXö$…*ô áX™!N†~, µbCÞP‡<Ü¡9D!‘=FZÐ’¨DX°$NLE¥h*&PŒÂ"œ´ÈÅ-zñ8`ô¤b�VF¥œÑ{#Qã/B/•Oÿ�9�£,èè ;¢p…³³%ƒöÇafê)Á8f0¶ˆCd0Ó!ó BrDÅë'«6³É‹mr³Þü&!oè��“8Y$:÷å3n²%9EfÜÖՄ¡ž?«ŠT~�ÌcrÑþDᤉδ þ*_)]R¢×䦚ò—-º ¢¢õ‘2ªQIT¢ø(H‰)R#™Ê¼!3‘á̺@ó =5zÍlb“›Ýü¦7ç㤆�óæ<:YЂ®“•í¤Å;ãÙšyþ¤ža¸'Uò¹Ïdnџƨ‡^Ä¡ô ªK¨;wó®ö £�¨ͺŠ> Ò;ÿÝ(˜ÔŠ¥Œ´®—*)?…±Ìf6ä™!‰ff¦™‰Î”¦6Ý&NsªÓ¾õô§�êV¹ZTg”2©C‘g,èiOµà3*úÜg?ÿi“€v \õªÙÀŠT±Æ…¬jE+ÕÊÖ¬`ô­Và¨Yçj×Ý ¯TÝ«JûÊÒ¿º´´0¬LUEÓš6±�X,cËù›sBöd�le7ÏË.5³MÝl:+‰Ïš´ª¢­ i‡T²¢Ö9bx/|miK²ºÖ¬°�£Yg‹•Ú¾·Õ-o\ßž)]i.Zúˆ—Æ´š…Õfs ÝqJw%Ô…ìuqÂΚ(T»J} SâT¨@ª 5ïÿUG›UãFv¨íÅ |ã+_8Ò—«¯“¯d+̶òÅWþ•(€,ä²X¯(å«2üšÀªˆ Öƒ™kSçN˜§Vpu­+Y •Ãa�Äv3‚YÍ>•³QõìTC›bô®¸ÉB=-˜Êã÷ΘÆ5.è� ”ãüÞñq\s‹¥!z,E.‚›‘ QXþ:,/ !èö´±¿Ér‹‰ÊeÊ 7ó‡ âUŒØÌ%Fó‰…aU¬ÆF«@t4˜(4g1Ô¹VwƳYA Ò=wtn\ñÕr ¬¹¹ÐÆÞ¯SNŒèN+#ŒN¬ TŒiS[ÒŸ¡t¥}ziLky¨Øíô§ÃÿŒ‘1·Ìá=óxÓŒbV/ÄÕ§ˆ6dd=çZWæÖU«®?ê+¿Û×[v°—KìA»à8ô‘ƒ›äáZ¸¸³x6{àýjWÛÚØ®4q¸ÝmMßbÃó w¨ 2êRŸûÔéNõªUÜj¿ú¡±†Î¬é�{—5×ùÞ7Xú ¿_»)à8a ^p„ÉJVð¢ÑÙh—K›âŰv5.ÞSw1ÃïòÇ¿,îY\Ñ»"¯xÉ›WUŸ×!š8;ÚsCa�¢ín—wŒeNsa;ßÀùWtñÜçØzÐ…nl¢˜ÙÓu8ÄÛ"q28ýé_l¶@õ$YÝãuùPºNfÿ›¸¼d7FãÑŽö}­]Cn;ÌçMoš«î7w¿—ëo­ôÝàŸìò.{á >ü‚�­th32�‡ºÔÉ9yöTë—×zf4_nΣÚóV ½è5AúÛ°ýô£€»ŒkÍz8¹^×x¯ŠÞOÅ÷žûýï·Ï}¡M3Õ`¤´ð5A‘GŒ’÷”"þ�F+Á„·•{ �°ðîDý1ÓÿAÄkÒ8É©_>ùˆSTfÕWG°LŠ�‚Ž áÎÏüÌ\Íü­`€ÉßT- Â9þ™€þ…\+ô_jТ“{¨ò�.`Fâ“°H ØQVT bÿ`%h`p aõÙxè� ² Ÿ î "Å Ö w½þŸæ¶†& NÀàá"!’Øz–þ‚B¡&¾˜‡î\þaîm!2u¡M|aQh"bÌ.RšÕaýµa\J ^úÈj`:žEî Ž¢à™†(�R@×GE"¶¢p,b5bG=¢N8—$ž%jšN Ú!Žàv"”}¢Y„¢ú‘¢2›)zÇ(‘’M¨bþ¢+Vã4^ǾEa-&Ö-^XUâ*!&úâx]`0 £!£†è("c½,£<Û)rQ-Üÿ#‚͇5îcoÀ"-]GQˆ-6`#Eœ.ÖSjøz‡:®£�ñÙ–<Æãú$"eF¥Ae¾™$N!eA*%j($�<¥0F¥®Me(Z¥\Vâ£Vv$Wj�WbX*ž†åh¥¥¤J’B¦¥K®%Cªã\ÙÝLRMÎ¥dÆP]nä]öd^bÌ^ÎB_&`î„`Âÿaz]¹-e26e&:EC6¦c¾%dRådÆ&î¼äS8×*ݦ3ˆŠ¨ÒÍàG”ˆÆuâ.zqV…¯øH”Dɬ‘Õ.ÖifÊʦtΣû ¤Ý¦nâoƒozpr›p"!qzÁsV'x,'W5§raÓsÎ�N'|Ê£yJÅu®RvâÂvv§ |'¦…§ŽgyÆ�T çP©çdS{ÎÐ{Æ'ƒÎã¤ÔgÝg~v Lðg–ù§S(9Ž…9‚s"¡snhƒŽ(‰¢Çƒ–:¡„ò¦~Z(ÍÝAþgqŠhWthx|…�"(�–(�ö¨Xœ¨M¥(®è!µèn¬—½‰c=iÿ(EÖ¨�R Xä({î¨�Vi•)7 i%Ü'BamHDÕÑAá™™&•jÅ“B©©›•¶©›¢fT@š–ri—fÒ—†@˜Š)™–&b2%W¤©þ°é›j�bé6ÍivÖ©�~ižÒÜž®¤™6éŸ>i .¡^*‰*/h)…(jÝi£ÚÛ£&Köi‚f Ò‹ b*«N§¦r*tx*�*å‰iŒªSEjY¤êšZj«þjl¾ª�vª¬Ò*óÙ*®¦"D'ð*•¬*°Fk�Ö!_ØÖm�‰-Ñ�¶n«Z�çxB«´†«¸¢ ÁU�dë¶jk·z«Œ«»¾«Ë”kFÝWe¤…«ºš»¶+¼î+¿ö–€F½æ€½ÒÝùj¿,ÂÉûäÝr lûaSÂF¬Ä–Ç¢_ÃÚëà ÀÄn,Ç:©Üäœì�lûu,É’lÅREú¡ìÖ,ËNìÉ@ÊÂìʶ,ÍìËÆlÆÖ¬Îîë͆,ÃŽìέ¸ö,MÅÐ -Ò&­Ò.m¡!ù,BàÌÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹1ªÚÈQ’Ç� =BI’#ÇŒ(Sª\ɲ¥Ë—0cÊœI3¡É�!sJ"YòfÍŸ@ƒ J´¨Ñ£oªÒ’çH¥H£J�JµªÕ«,•2éT¬`ÊK¶ìJ­[E:ýj¶­Û·pã"E›¶+[¹xóêÝË—!Ý­v}öL¸°á°™6y¸±ãÇ�c&Ö¹ødä˘3k¶y“�çÏ=B‹¦Cº´¯Ó¨»n^ͺ5Ü®VbËþ ZtèÒ¦QŸVíº·ïßRaËŽMÛ³íÛ¸éèÞí¸óçÐ1 ˜N½ë­ëØûhß^ »÷bàÃoÿß^©¼yÞÑÓ«_o�zu§Ø³�ïãý{xðóû�ÙÏ=ûÿçÞtÖÅwK~õuw~óñ×_sF(áj �Ÿ�Î7̆.XL4 †èà~þMh≆Ux¡�ùqØá‚!Š8b‰(Öh£\*·a‹.ãaŒ ŽH�7i¤XÔ‰¡äŠñãä“=c”T��†dIÒ‘\v‰U’Kêhà“PöHe•@b©åH^¶éæQ`ŠÁ$vd:å™SZ©¦![¾éçŸ4Å9çuus'žzŽ˜%Ÿlêè£)"餂Ηǥ˜z虉:¸hŸ�†*jC“R:�’rZŠé¥šš‰hšŠ®ÿ ɨ´Ò@…ÉÑáî¼ áë¯+,#Äk,±‘$«ìq¶màl­ÐB{뀹òÊ«°Øf{ì¶Œ(»,³¡9»A´äŠ:­{ÕZëC¶ìÀí±Þ& n¸Ï–k/ çR—®µíjûn±ñF2oâÞkð›ùN·ïµýû/±3[ðÁs™° ïÚ°ÃG|Üćlca”lriš¤Œ§ §¬É¶²Ä,óÀ^Ô,.È"ç{í.ážûð½ÿ.~ðׯ¼ñ!ÏÓù÷2ÿÇè¥'{º°ÓW¿ÝõØk;íØîý å Ÿø|G¾ò �}ÆSIX.÷Ázò“•TǺã`ÏuüË ÷Zò?CF¡qAš�„$^HÐGŽ„�är óâ‰ù«~´ÍW¡Á úÏ{B¡ÿCxÂ"âÂCæ[! Ó×”ä)qyÔ ÝûfÁJpJ´ž/ØCþýwA4ЉhD"Q… Y"¹âD�Î`3™hž=ÔM�z9M5(“†1>c4B͸ åä�ès!$ 88VHŽ¡¡cíˆE›ÁІ!¥¨Õëi£ë×h°V°‚íHzÌFx÷»¶½­b+VÇ’²f•l$(+,ËF³ÞÉæK_ aH®éa®ì†ï~7ºI�.j«{]×¾I»�à®1ýëÝðÖ·‹kc»ŠÈ¢u²jÍ[3;úÖ×¾ñÁï@ô›þ2¸Vê ©ë¤ÕÎ'°v‚zÖ;˜%ÜNn+±[iõV«ÁÅðp5\\�ÇÃóqˆ=;WÚ)m¿%ûÕ‰S¼WJ––À/nm£þĬ\u…Æ5µ±ƒs¬�÷x�?>i�×›á Ç·ÿÃHV2vD,þ=¹ÄQöÕ”©L¥SøùÏÆòx`¼e?u99_NŽ…Å^2÷ÁÌ�ÕËÞ`¹¾Ý‘oœå| :ÀÎ5ƒr¤Ì`>÷ùÏ~t‹ÿšeìÖˆpS�5'�r‚9Œ¶­£!]^)NúÂl²›3 gsúäì ¨½ jRûÀ¨ŽöŸAíj¯LÐÛ!ô¬&ÄÙ_Èzª´.�­�^\3øÆ»Ž°n#ý‡_ ·½Ä}¯q�¼i9'Û)Ën¶žK�§mI[ÚÕ¶6ž°­m›¨Ûßžõqr5nÜ,úÜc&¡ŽÕÍcv»[Èð&²¼�¼$ãáØ÷æI¾ñ<ê}?»ßÇÿúw´Ník¯Úº­Žqoz(>T¡ŠYZM©7ã“ çIÒ[ìz†Ð‡žnuŸ™0“I¡ÒyÑu�œ)]›²„U(eXýêNuê�]N&G‹w&Ó*ÆnZ¾šÀh—™Vµ*3—É/©/ÇNi>õšÿÎæJÂùa´sì$H« úÐ…^t 7&éK7`Ó!D�§'êZ›úŠÏtu¬g=N퓼þ;°—LìdŸRæ§„vG¨}íçl{ÊÞîòÉ�4twŽÝ}‡w1è}¶|÷(Ïëøx ~ð…_÷áo’“Ä+~ñ1ví1C}ÿêcæöÂ]µ z=bœÙ›§ö·?¦Î4x¡ßâïj>kMÙµªK¿âÃgÅg|Ã|É÷?P— R—,Kej£'Muâhµ—}ÛgZw³2¥wzâ—ª§ ¬7pè êÇ~¿á~åÇ‘s ÒyPÏp¼—úÇý÷G7ˆG€»c€…&Ê÷Ì'3Îgj¢W}(qÚ1�·v'5vÜ'zˆ'~È�ä·zæ×zéws§%u§A5‡wñ‡R+Ø.ƒÞñkgEƒ«bƒŽ‘ƒ:Èt0†9À¤MzRZª¥‘:©TZIÄà„N($=´©ŸŒ�ª^úrÖƒ£: ¥:§ŠªÚy)²¤ÏÔ¢Žð¢k£´êjq«¸J$ÑC¼:¾ú«Ñ%¨mJ¬ÆÚ0È:•S¢¬Ìꬱ UÑz¡Ó žSZ©N‚­c§­Ä­Úç­žJuâsäJ¤zR¦Š˜¨šª×®ƒú®oê¢q £s*£µz¯4š¯úÿ üz½Z'°Âê®= ±ÅJ¤‡úŸf§°)xR ë°±ú9±”ô$ ›A;~, j¯}Á?#{N%‹Z'‹²Ù¢²˲¯ê²± ³³ª41†¯6+s‘Iý:ÿÚ³z%%t¶Aû´VY¤ïÒ€‚´¶¡UK ­«UÔJ±×j±ü¡4ÛŠ¡ÝŠ�ß láêˆ×‘m¡züLZu©éz¦$j¶­J¬°zC²:qn;âCNÓëI�KJÌR(w‹·+£·$Ä·Bë2ì"mÿ"¸B¸¢a¸ÎZ*’ò°U ¸B[­:µ�[3‘»¥“«¡àú¥q—¹·¹†1»Ãñ¹Vÿº%:ºl ´B{º²”ºef« ­[¯»á½²Q»¶K&¸›·=²·¥‹¶¾›-À¸“7¸ê²°Ç‹¼Ê˼~ë¼Rë¸û¹+¹K¹Y;Õu‘aJôà;¡æo*hf,¤›®Š¾& ¾æÙ¾ïK¯Ë,]A8±ÁV`¿÷ë$ù›Tº‹ ¼ë·.ÂÖ B<ÄÅ"¼Ã@¼¡a¼LмŠ�À'µ¸Q[±LlµŒµ×û©Ù›!ʽ…AÃü+œr@| Ê.%|Âj‹ºl«º5C-\/<É!ÃsK;ÁdÃ7œÃ¹»¿»Û¿}»˜šPƧ0ÄDL,FŒÄ=ÿ UR$ELìÄçÅ ØÀؽ^0½œºfÛrÁÚÛÅ\Ë`|R ] Äg\¶å»²�ܲñú²ó³ìûƬû;®;ÇtŒvÜ4¬Ç÷ËÇx²Ã=,È„lÈB\Ä<¼œ´çÔÈ¡óȉûÄÍ˸ÐûÀÒÁÔ;ÁÖ l›¼ÅšûÉFQOõTRÌ¢¬cl,Ú‰©À°º-—šˆ2#pzU[Óì ¤¨UÓ炚å;ʦA%U{Û1t¦¨Ò6 ]Ђ̂'6µJ̰ê®g¥¨¬iBˆ;õÄÄ É‚…‚!Ÿatå;$ª “0Ò$]DÁ”9AÎÖ$ÎÇAΤ|,‡{NêÌrìÿl¥î3ðœTò<Åüa�õwÏõ—Ïç�oüÌ4!pÔHýÏBÐH:ÐMÐÝ m± ÍÐ ëÐ5Ñ5xB};�¼Ým ]M!MÒ%}B'-E¡Ò¶ÄÒ¶áÒ¨µ-1}L3p5=¡7- 9½2;]É#âÓƒÔƒ'Ôå±ÏTRH�ÔÚÐÑ%ÐÑöÔP½˜Í` ­´VÝÐ+ûÐHÑ%ÔÕƒðÕ¥Ö«2ÖñQÖ•pÖÓ‘Ö=°Öl= &MJ( r�It-v]Zxí¬U ë|,í\…ïÜr¥5ØÙZØ|y.ˆØCGŠŒÍ?ŽýØ! ÔÏÀÔ*mÌÕ«ÿ2ÕØÜyÝ¿  ¢MB¤mÚ“‚Ú™R'í ZÛ²ÍÖµ=·ý¹½G»½­W¿í¨œÍ¤kƒÎŽ�Çý¨¥ÜËÜã�!Ï}y.˜ ^á§HÔ�mÔÖ�ÝÚ]zÜ}Þ�)àí„â ÜX� Z݆\�w¤Þ’ÂÞ¬âÞd ßf-ß}A ­^Ê2Û´íÖ¶ ×D±ß]Ôß=ðßIàž­×ÎZà�xàâ—à N óÜÓÍ} .¸2^á~á"WÔ7cÝ×ÙK=ÙHúº!~)#>v%.àŸ�Õ¡½ÕÍâÿãâŠãy ÚØÁÚ®-ô­ãÉÂã÷-ù]BÞC%õ<¼ÿ½+¶`S;ÞͺäZƒÎèü×2åS¾ùqbWŽ'Y®å\N=„Î`¾é¨…ÎfŽÙR­ÙTmL¥ÑÙINÞnnÞp>Úrî=tnçx~ä´ç°-è>Žß@>…®AÄÜ ˆîߊ^[Œn±Ž¾CL.égEé1cé<�éó¡éõ‡åõ§å[n ÓM;¢nݤ^Z¦î1gžiÇÔê® çÛ±^zç� émM-ƒg…Ñ2¾ÚÅÁë8~¿>Û�ƒNÅžAÇžìE¾ì´ÐìØúìíÒž Ô. ÖNØôœí áY×éîÎ?ãþØå®Wèüá¶‘îëÞî¤ñîðÞ‰9ÿŽâo®âqns-Žï`­ï5ÅïdòÞ´ðØÃ,oßÁ.èÃ.å;tì–= O:‰î¶åíVŸ �nâçí‘^ñ5õôk³6ó8�gR[Ûòôªí‡}yÌÐönoõòôO_òHí‚ò9})mÌ"$ÀÐ÷~ €øº0ø„ïòtàÔOïgÕ Œßønÿø�/ ’?ù¹²6roÙyS{˰ùœùÌ`  úääô–ï¢!>žïù“?ù¹LKßôÄüôQ¿ S_õW¯åYÏæ•ù:/í`öG3ö»Xö´pö–�öÿÓlùpo —Ÿø�8êõw÷——÷¨¶÷#â÷ø€ÿOø…Ïê¤�ø­ø5ÕøŽŸú�¿ú’_ùZóü�ùxÇù�ù¡/úÅAúЯÌ‚úèÌ #Xð×A„.dØÐáCˆz¡XqÕEŒ­4nœÕÑãÆ�›Dö éÃ$-”ÉT®d©ÂK˜±dÎÌQÓ&FŒ²tîLÕÓçÏž=î$Z´ÁQ¤&”š@ÉÈéS¡M¥ÚÈêÕgYµæâÚUàWf-“Ý"[6êÙY@S…`ÛV«VeqåvíªöÔ]¼$õö Ó×/0À�� &¬Ëða›tãÅ{V­^Ÿ�$O[ùkÁ‚Š5Ó)* mTS¡E‹!]zÙiÔ–�­fÍÇõk�ÝK²ÒÿmÜ–-c&ˆ0¡DàÁ!n Æ8΋"?ÞT»Øsèb-ï¢^½vãÙµgÿÓÝ;òU;ö9sæ&Ƨž>]º”Ø{¼‘äÏ71À¾ý«WåÊ%L¸ÙhÜ/®«Æ*½Sb±©&è¢ki@ebke9‘6¯´Àt«Œ5½lâh¹Ž:³É ËPÃÀ "Ñ ðv±£òÌ‹E³Ã4 ûÐñºgM4ƒìã°5D�7a|;H8&›$nƒìÀS®G�šÛ«ÁçþÓ²™éª£îºí ûï�ï®åb4=ÆÖsª=¥Þ#&¾ùä«ï¾ò³ ÂþÓ2@h ,ͨTpA,‹ÿ B )éBÒN´‘IòP¶E¬iE³1E‚VlQ§Õœ‰FÃ&Gd‚äñÅCRG"S5ò4$•ü¥I^�{2J䦤r+õJtËÿºôL1µ#³»Qe1p¶TdŒ…M¼ÜdN䤳Î;ïÓ³>ûüSÀ=å,CÌ!ÑEl”¹G‘ÃÐSU+íáÒ 3-jÄ;ý0IŒ¶Ôž¬EUU™aÕÕÚzŒÕ”Y‡¬ÕÆ#yÓµWŽúõ¸`7¶£bI:Ye­«­Yípùåh§�ÊT™°½K[n½½«N;ñÌSÏrû;7Ðt­’y–vÅÙf�ÍQ í�ßIõåÿ·GMsàT` Õ`3I}‘æ+rÒ‡wŒÖX+®•á[—ÉUÉŽë^èã0¤yä’{8yËÝxc–å0^†9li E‹l›Õs3gøvæ9\ü€ðº¡5Zq�’¶éo-� jHÅ�ÔF«kúĬ·6q`` fq„«•qá†Óîã:µÎšØí‹ãžÛ7»íÆ[uni”+Crp– w9fÎgNXÆÆq†SçSxŽ„òŸóƒsÑÝO]vÓ;ôsæ·}õ³*,ýt SÏþÏZøõ®cÿzvœ¸hl×3îT¥;ÞÅwm›ÕÛ0†+�Ñ­x;^È’×7Ð%ËyôM˜¤÷ÿATA„9)J�6rÝìMÛ“Ó{¼¾qU¨B× 4—ªtN}îÊ`3##QˆµÃHiJSÔ±f5îÊA…°¦&¾†~ºA'¬HB¢ô/§Ú Vd#V± :�Qà‹*¤¿5ì2½ÑÕ’&œ âDXTÂ`û´8Ìl¬! ”ž«€E‚è„5K¡ã¶ÅÂÒ…+0Ô“ GR›šO.ãÊaG<Ç ;þç‡q☊"Q H¬Ÿ�ÁD'úKQtÍñX+r�bÑeÒE/’ŒaDÆIÒ;3Š�íSã@ØØÆ7±8 “ãÞ†UÇ1í•Çü Cøh8?ÿÎÒ3/äµ ÉDÊI‘¹`d~Ù·D’hçÓS%‘¶C¥EY›TF'ƒHÄ‹ˆr”I¢Q9ÇüAÑ]R¤š�ªxÅ‹tF‹wáâf¾¨!^öò9düI�Ψ£4Ó mÜU2%GŒÔŒË“'à6˜G Zóš.ËfBKÈM� 0…àlO ß3Îr^åœ4Œä ¯âÎK¾+“> í‰ÏUè“”º1å)Ý•JÖ tAFÃ*K—fñE¶,›Cu Q^ú²ÀÑEû�Q5n™]ÈñvN‘ ®µéÓ1˜†šŒ¡”x{\iG˜Õ@.§›�Ë–SÞ’›§>CÐN!ÉÃ>ƒÿ’SJQÖW“º2�žö4R•ÊÏRúó©q�ÊNXÉWž– ÏKkÉÐ[vñ¡aiIDÅJV¨ ³¤Åd†ZõÈV¸u™a€«3Ñ2×½dYx… ^«ÙÖ¾¶´µZdL 9SÃ6±‹ÅScÉÓFv²�¨,Q.›åni³Gýd(�¸TÕ˜òŸÆ è*ÚÊ‚jèªÚ\h‚bëU+|E,¶�è/ËXVab”˜¥fJÙ Ò‹ød9ºNYX#Íʆ£åU<ìá ü93Á_òw0Û}ÌxG°Þdrq‹[ãâà æˆÿöpÁC|6~/‡6FäÕ tvCúòEÏüÑ9ïù¸´ôòôysÀoëøôYOýê]Ýú„/¼ì6©½®uƒ{›Ð=·ƒ;’�»e »e�¼_9ì£ã³ äåƒæƒç;,:ãšÂ›>™ó6à “�"-ö;…ëЋ¦‚�ïë˜Ê¿‹À<ÍK‹ž8¿¸0·¦�õK�§s?ø«:ù»:ÔÛ:ÕëºI;»uQ%þC»\›¬ d<ìD@Ä ¼9‹Àý˜Àö¨Àö¼¥€‹q�lãÀƒ˜¹?ÁäÁì+Aÿ’8ÁþIÁuû0ËkAò{AŸ�Ae ÁLk: =}[�4=¤? ´? !Â>0Â'2»þcÂÁ¨²Ü+¿Nã½UÊ8/>cS+¼;,Ly!.T /\ 0T 1Ü2|¹m£¾Üޤ/B» 7ì8Ô�E[+ ?w‹x–\?½¨ëƒ©‹¿RSŠS»‹T[�UÓ…VKD×+BØ;¨rD%„8ÿ³Œ&Ì�'¶‹»DßËÄ >ßèÄáûÄ‘ ÅÉE(E¥8EHE¹XÅ lŤ95\¨b¼Z¼EËÈÅÉ?:dÁUpAÍ F¥ÛÃb¬ÁzóCÆÈÁÿÑcÆÒ³:hÄ:iÔ:jä:kTEdD$t²o´=fÇrœEKÌLÜ8˨»v¼�+\<Í“Gp¡G{Ÿì09׉>�0¼=ûÇ z¼�dCK¢E’09ƒÌ0ŸÓÅ9|´^üE*�Èa”Hc´È£�-¨DÒ£:BìÈ É É!ÌÆEÜÆFLB2H»pœ²HìµIܽ(œBvDw¼>x�¤žÔ“æó |¡ÜŸ:{L3ü4,¥.¦Hs$Á¨|¶©D7Ü«]\Ȭ4:ãÊy#Ư4ưDƧTF³ÔH´äHˆÆS˜F›¨ÆkÔ�’”Ë“<»º\BaIÿJÁ¾ü½uÜÄš¬„›|Á´“ÃÌ�ÄÄ“ÅlL+xLë4ʘ;C4žÊ<˜a¹/¡ŽÈ;<ó¨0™‰,>cY°•Œ•�‹¶è/Ñ`¢¨Ï©#5óG�&ªÆ†Y�4Û‹Á$;Yê Jfxµdx•”*›ˆ%™Ô ˜ËΊHÌ<:¹7G@ ¥zÃϸ%]¹=Wº æ:�â5Õãe¦äMžëð[!q^×€Þèý êÍY_…ÀÞ0eÜF܉î%�ï%Z˜3áš³ÌË-ØÆ=®ïª õ]Ö•�U!5"¥ß‰mÔŠMR¶<›Üýß[¨Ôn D�ÙÖ[POÅRPÕÒ¹MÙÊ@�ɵ`/@^À¢¥‘Ù`æ�æ\áÿ[•aFUe»á³à^’ðÞbß6ᥬáb5XbÉáô=·õ]ØÏ]ÓbjÝ1kÝlEâÊðßIà'å&Û Y*ˆ‘%‰’­âFWfÐâÈäb/ž®� œfc¢h^>c¶@[IcêV6ö°ìåc9~\®cÞ6Îãòµa‹òc½Øa…íaB~X ŽX!¦Xü5âÛŒT¯k%fbI.`(Ö]•¸ÒÌ,W+†`,–` þäu½à¼  ¢ e11å�@eçUå`e+pe}•áˆhc¦ÔÞZ¦c5²c]Æcîå=†ã¨@ß`dV 6fC6R"^æ‹=â%MâG^âH¾Tÿj®ä�blvImÞäþ OöGß8ÕhesÞtÖ u~ÞÀ]Sw†gž•燺“sª€AÛÈCȃˆç†�iŸº:Õ½MºŽ îÜc”ë`M†‹�ó29­@dŸ¡ ª°–­+±'»øÃÄ‹ûêh ¦iª®"¦V &r U„ØÕCxk¸.éƈ€Äˆ.ë2]qg}ú ˜Mz6Žšþ¤›ž-ØÑé_ài†øiÅ€ ç¡&�¢®�£ÆË¤�¥æjÙ;¡½K³¨¾ßû ê©°–ëÀê–Ðj `jëkd!k®0k̆ Hëà™¶v#†€ë¸–ëP®ëÿ‹¸k(V™îë7’išv$›ÞVÎéªDÄ^ˆÅþéÆîbãxìʼn콘l‰ ¥® ¦–�§~¶ÎFÝ©mѦ«>ÉjEÚêÌ]Õ»Pí°n‰±6¥²¢³žmwQkÛæ ÊÕí·æíÞžëßná:âNÜ ;îПì¯*¼NÁÕ—Žéè–ééÎ릖™0jæBêîÞ‹ïvêÍ.‹ñ<Ð~„óÞ ¤@ õ¦ öËô€oÖÞ×ÎØnoÙþ Ú&«âo܆îðq¦k_…áŽ#?ðº1îílï °¡5 G\ ¯pG»ðêv-¢¶�Xàp×Ýîʆ†ËÆñ¦‰ÿðæì¬�j<9ñ׋?Н‹ÓŽíYQ—ïÖ¦ï×¶o;Gëü®mƒòqrGò!¿ˆ0©ðàHr%ŸC¼uò.�ræþÌç>a,Ïréj.‡l/× ”�PÂøp½q4q²(ñò¦ê ÙðÚˆó˜s®xñ±ÃsÕžqGV¢ú6‚ûÖñ@çñµ&t‡`r�E�îF7ðGÍHGîa"w®tXîió£gùƒŠ¨ˆ “ �ŠõuËön;oT¿UosÐÞì†ó8 Ñ[k\‡]>·q?7s@_ýt½šçè6çÊtGKöƒ_vHçì�ôÏ€öåžrÿÃFxk–l§ˆmߎnŠo¿bQçîqñrñãï5÷lû8qvÿôW÷–ˆw=I,zÇÏçõ?Çotýâ �7xŸ.x¡„ÿ0…¿JYnrgˆÇi‰o«x2¹x/ÈxíØx�xs’Ðî@&u’0uÍ.y56ÿló–‘ë€uxÇÏq‘y7©÷¯¾whÎ÷?š~·‰ÿù€§ú¢·pé ü£÷°¤WÈë+pˆkg"7s³Iˆ|ÉwÕŠÁ Ü xºv¬×z /Šëˆ¥Xòú Ò/}É—|q‡wÖo}Æ–ó:ññÚ¯}˜ˆ ¶oùçÿ˜Ï¹_Ñ×PÝu}"öì`" =ýÈÇçþ2¦\CüÄü¢/|£?|Êê¾z}2qüÇ׿ŸÊŸË¿ ̯Í¿xwævϯ з"Ñ/}ÓgþÔ_ýÖg}ï÷ŽØˆG>+˜çà°„ !0lë!Ä'6¨hÑÆŒ7æiäñ#±�"‘,ÉñäÆ�±l‰2L#2ÅЬà&Î0:wnêé³eËIB‡â*j”Ò¤¿–hêÔ)ΨR§N`õ*Õ¬8Ÿr…*µ+ذbÇ’[õ*Z´]ÿ°m›ã-\MrçJë.Þ>z÷Vêë·,Î*‚Û¶õbø°•ÄŠwÿî”åøñĉœ&S†1rš7×zì3´ÐŠ*mz-á?±à¾UIÐ B… :´ s‹3bDù¤È�%M¢<éúP–/cάIs*c�>&ï<ÉèѤH—þ2«õ{Ô´ÀSüµ,úô깞UKvüUòéЯ?—ng¼x�Óôë—|Wâ 6`Ñ…Q‚ :³ ƒÑ8ø n¬½5]O›qÖL¹Lä“/Š×|@$aÇñ†Qp!ÑÆn¶År Œ1&çHŠ5s¢ è¸ãp$Q¸‰)A £ŒÉéVD‡‰g �BwŸ\¸‘1åUªXyåzYj¹%—]ªGÞ‡ïÅ7ÿ_}ôA©‰uúÝÅŸþõ WX`t *Èà‚Bˆ‰?Z¨™unØS‡¾„ùTˆ#Jhâ‰5®A‹¶ ãŒ6¦ˆãŽ<öøc“ANzÊŒ.&iØ’ÑujÊ“PJI¥U^ºú*¬±š÷Ý¡b…(ß*eš ešj²éf%p>%'�Ú‰ žyêM„úùg 0 ºI¡µ6•èC$2Ê›£+FjÙ§•Z*¦™Ð##œvnr¢>¤dZLvšê}«’q•¬ù껯–`¦UÖ­d–yf¯úýꦰN; �9ü ŽË2˧³þI@´JÄ¡‡ÿr…íj‹º†c·´} »@�Kî‰æž»ÿ)…§~úØcîÆ/Zò6Iï\öâË/ÐA €¿î�p®ºœŸ¯ü›pSâíµWÃC|¢ÄͲö¬…O[­ÇˆÂ§(kÛfTrC'?”rK+‡Tn¦¸©ÛäÌ4Ëb3ÎWéì¤kgúÜêÐ� îjÑ?=fÒóÊ´ÁN# ^€iM­WÕG¼¬Öpq}a]‚nLhÇF;²¶#7šâ£j¿8©¸+ý£Ü1¯;©Ýw»›·U{És”˜My/àƒ ?…ò‘Ï�„`d&HA^°CÔ`,8¸ ÂG„va IxBòQp8iá!^H¤ʰr¬a'vÅöP ?¤g1Ä©Ñ|éCâ¤Ú'‘÷MƉOÌ¡ñ‡™E‹¬Ñ"¹ØÅЊbÄ 'gÆ¢1ÿ�j4DÛè‹7jPŽtÜÀï˜G=†­�Æ Ü](©/‚¯�†¤!}¤—È.ò†�|äc"9ɽTR—séO»Á1Žüå@EXЃ&´¨„c¡2ÁÅÌåAšt�¦"sÈȾt£@Ô(…È×Ñ#‚¤â)9IjNPžt”R)Ùà‚Êb¸´’0ÿ= LaIÓ>Øô¦9íçÿ鮀z0¨!j1�*Ø£�Jb‹ŠÅ2¶±‹í©."+ÙfP¶²–¥,ù\ô£%6±?’X7k4£¹h4‰ñ$0.«Úf°éTŽ}-*\Ħ]ж¶éë&›äh 9ê6:l"‘÷»öˆç*©ùCo ÄâZ¥ ƒ}.ñæD'Æt±°u,d%YÕª‰™µÍf)TÝT|vY¡MÑh)TZÓ¢vµ—mm§®ÛXÙò§¶¶µnù“Ü�ð–ƒú­„äxÂâ¦å¸ûÕIá¬2è2XpÒ=luåËØìj—»jú®eÂ;�ñ–WOç Nz§³ÞÑ´×½•…oÿ“$üXÛÌÖ¾»¸m%sëßèô÷yÿåp98`75C‚Çsž™_ŽÎxU[u6Ú�,Žº‹aˆhØ'ãý�G@[É¡tÄŠ)±ee"f# XHJ¦¯sÆ›>ÜÈØÆ4®±|nìœ?oÇ<ÀqÅCæ 9*Eþ³¾¤«¥_ŠªÉ‘84¢£¬&‰i¶Ê›¸2–]†..›UÄà¥ÐŒ°Üˆ17Ç9³ÂIOÕl56ó:o†³œkBg\ٙǑCËž¥¢ç!ºÖ}$4“ D'úDÝeô¥« éßHºG”ŽÌ�ÉÐeËœ&3>}“PWw͘a“©ç8ûÇÖq`ÿpçà),-±�¹imëu×¶14¯#¡hý;ÃŽÖ´¦‹=œð»ß¸‘®²ÂìähúÙ5ù YŒÇñÆ525ÁŠTv»íTÓ„DãÀ«fýi€Ýo7 ­ëxËÛ׋^V£§£J|GÚ\èê·¿1p@ Ów6§ÞŽS»É¶!µ Žn´l{úÅí%�k…ãºàÜm3’Ï/õ¦2…VÎò�è»$0ç÷¿ç”rê¥à9ïÏÎ.•žëúçצ‰Ðq"ž¢=éJÏÓ³ât¨óh¿4�‹¨nrz›·›•ÔúÖÑu’|=a'ÐØ{Òìßí•àøa“kÿŸ[èq¿ÉÅ�̘_Ú]t\Ê{yÔîç¾³>_�Nàã]õ»hÙðçCüÖψÆ?~@‘ßÄä?Rù6¥},Sɼa6ßöοé}–û¸¥+Ò—žÜ§O÷ÆU¿•ÖsÿU¯gLìy={ZÔÞöÊÀ=ËuÏ{™‹=Ødo‰ÙǬóËkÿ&È÷‚òÛð‰<\Á²ŽþœLUŸõm ê-Xýu\÷- «„ˆrEÇ™�œËàJÔˆËLà‰ šOì‰ä€N�Šá ˆÕÎ<�\•XXÑqP[¬Þ—œÛM0  Π÷ÁÇ2FÆòJ\ îŽh`Op ‰| �r NJæ¼ÿ †… ® ®´àöÑ ^á19à êDòÚjÄIüàá¡m Nt "¡`Œ Ý” X�àÝ�EJá*Pa b!æáðháv!¢}ao„¡^ F‚††O>ÏIæÀ‚ÅTÐá²… ê¡&n¢¾„H©à ”H ¹P  â(f`á¡"a®¡Ú�Eâ$vŸ�* 'î"/v‰'Æ †¢ž"–¢)!*¢*""+."Æ5E#âJíÌ"ŰF-²Çÿݶåb/v£7â0naþ¥)rÄ1cFüJHŽWDÅ4rP$¶…;¦ŸÝÿ#~£>îã«ñà½[u•ãFœc¦àˆ:®";¶¢é­PTü5F‰Ðcrê ?^äE^Ü?ZÆx äA$2òÆA2cB:£-J…CÊc5Â…D>ãzàãÐ}Þb$Mv£FÂ@vÖ§ô HÀqŒd"š$66$Ñ]t´d¿d£LZdM6å.Þ$øådb}ÊqèÉý$…¬#k´cNEJ¢ÚQ²E=�Rú_Lše&:¥Zb!TîÄ8R¥kXe¼aåth%\p¥K¾#N|e�Rf LB¬åãZf/~ß ºÈ#~JŒìO$²b�-¦‡x—t¦af¦fÆJ¶%¦m,&cžÿ‚c®dz NH&{l¦j®&‘uæ*f†fc†Ïc&ddšåd²¦nî&B‘ÇFBDí�ȧìß–æN æSè"o.'sŽoâ¤egiÂqöÀtÞåiâfj6'wv'¿Æ|ºDJÈÅ�äLê§�hSÀà´}æx’'}Zã¸!¨„N(�žÛ/IçuºˆÝ߀R¨‡J¨‚À/)‰–èZƆ"_‡~(‹ægˆŽh‰’è‰nqh„¶(ŽæhXL…t—e`ê¨�é f‘)’ Ô$?)“6)Y©“F©”V¨ÞM©•Zé’^©–i–n©—æh—~©˜zh˜Ž©™h™ž©šºg𮩛rg›¾©œòQ@!ù,BàÌÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹ØÈQ€Ç�ƒBŠL@²äŠ“(?ª\™±¥Ë—0cÊœI³¦Í›8mrì¸RäÈ’$Q¦\I4§Ñ£H“*]Ê´©Ó†;7õhP¡+ˆ}ʵ«×¯`ÊÍ5ÀTªV`ͪU娷pãÊ�K—lÔ³>Ó®m붮߿€ ^ZïO {ùz̸±ãÇ�îIuŒå˘-³ÙÌY‚ç�‘C‹Mìd•™S«æÜùóâÒ°cËžíòôGÕ¸/³ÞìYhÚÀƒ .°ìn6¹sïý›¸óçÐý–Í@½úñ丗»½»÷ï]§Wÿ§~{jí¾_ƒ_Ͼ=BÅmÓþ˜O_‹ýû}òë/À¿¿~ý¸(àùbà�(¹§à‚ÞÁ§•|ôÍw~öç�Hà�žÄà‡ ç QF8¡}öa!)f`Š˜`ˆ4Ö(Úˆ+•X߉)®X€@é".0Æ8£�H&Ž*¥…Ç“Pž¨EŠAViå�Erx¤’\vù“9 å“RRiå™Xnh¤‡^¶éfW`z$æ˜RJcç�g¢éb–[¾éçŸHÅ)€?„:æ“Ñ$ªè�xæYešÿu¸ ”Vz“ …z¨¢‹2*�£�î©f }Zjê©aš©?‡âÁi¢ž~ÿ *��ê')ª¸æÊUƒ°ãë¯'+¬=Ä»*«›¾ë¬@¢ãì³ÜD+í­ºVk­@¼þ ¬°Ák쪭¾ͲÌ> ­´ÑR{íº¨ŠäÀ»ÜÛϼÞëͽ޼£¯¾ÕôëÈ¿Œ,0<ÜÎÁË#O: §s.ºÒ" ñÄ1•eqTìfLš»ðÆ;o?õÚƒo¾û¾Óo5ÿ:"ðÀŒp 7ü0ÄÜLL1Lç€ÆvÀ�*áU ¹5ÈB‘Z\$#i SZ’#’Ü %}rKLjÒ�œôäëˆ6s9k”ì“‘CARÑ•Y„¥,IËZ>2�;Éw)’^Þ0“mÜa0ãøI:†òeÆD2ݶ¹®d�Ídå3wcÈCJsšÕ¤Ù-7¢ÿMmq3$Þd#ÞÄ Ç{É”vtZ:×Ù¾6„(ðŒg°ZIÏzÂ2Ó A>!¶Ïôs[ÜB£B@ÒkÕð›¿$h'É9Ìs–㥠ÅãñÚ ˆRQ¢�'kêé�‹f4 @ *û²AÔž‘Ñ'å–” ¢�¦:•¤ 0©QÎb�Ó å$æÁ^ZŽ˜Fm¦6Sæ;oŠÓAí@L«3|:Í  u{D͆Q#I•¤ k©qêSKj­“ ´qÀ,¨7j΄¶ƒ«^í ;ÃêN•ص™f5šZ�ÈVYº¨C-*ÏÊ2E²*õD4ÓkS¡*ÕKRu V,aµzX˜s”P…já"2ÈÇÿžà¸ÍíYÏ:Ygˆë§—ͬ\y¶JaÙVJ¡-iû:Õ¿’/µ+ÅjK ‹Ø×â1¶$�­BÖR[Ï +·ºÝmÉzûÛ¶®šÕXqsª­ !b¢ÕÆr«åWp¢–XWlV]êZsÁ»ÚMw» Òï‚÷âïdËkÙó/®^⯣’r&œãiаÀá³»Q­T…Ý�Tè^U@ud-ÂZÁâçàÅ0–ÒÛâJã{Á ¬éìý —`bøøÇy²�@ä"3 hS˜<Ò9¸/HÂT¡ðG,¼ ÏKÃê°‡·bK�¸ÄøådAQœbî¸Å,†qŒO4ã»ùÿÆ9væŽ÷–`}ýÈBr‘�Ì´$+ŒÉ˜k(?eŸHÙ#Tfƒ•û�åÿh™ÃÆ®—§LbÏšxÌ*³™†æ4«92¶š›ßŒã Ël<ï�}œg=ïyGöó’ V‡º§Ð"9´½è‘ÝkÃ�Žtl'�èJ··[a3¾Èœb´uºŸõ‰2:j—ºÊ§Î[ªw»jb´:¯€Ùd htÔzÐ ú¨¯:«-^ôc¾öFŠž-ìùêË–Nö‰3]fgw:ÚR¢vµã gSËsÎ÷ª³�Wýíp�{¦õbmÝu³ƒÝ¿r7`MïywºÞ|¥¾�}‚KG—Ù*ÿæô¿?ðiœà×Vt¶}·í³v»á¯~¸ú"Îäs»/Ýuõ.{uœ^ûÚãhyˆENis8½ÀÁ³`ï¥i£àÓvù˳QðÝ—OÝYAö›·ÚáJ‹„Úa¦äY›Ëç!²8Æ«¸›hßâîx�woŸÝv…Ñl€<±wí§›ê:„·¯‡du³<ë•%©�#óø*ì &{#Ìžg´¯Lí‘`»’Ó™\½Æ=è$ÿº¶Žcw¼ß]ï“å{ßÿxÀž€†G|ïúoÆ;íÙXŸPäµNã®ÇÙò`G5�w«yÎ9çi_{ÿúNzøŠÖ;¼uNèÛR”5­w=ÿìÕ*û¶Ó¾ö·/üÓ×ýîyõÞE�g±¸z;|É[›ò_Ǽx5Žþûÿÿýçyz¢Çsƒ_ØGÚ—Üç}:Åá—w¾¶w�Öwò@ ˜�µx2o2b¹Ç~§x#3$Gf6ó7Yõ·HWЂ.h|wyÊw/óPƒ6¸/ü€:x‚ÑzÓg�m‡B8„ØÙ§} (tÈ·zu÷i®÷z{Øw¨�Ø�?ð�M·~×~¼·x.ƒ+“‚jµ‚Šä‚/s1˜|Ú†/6xƒú’ƒ:øb8€Ò§6@¨dCH„××*Ô½qQ>m)".­2ˆ/f Šh6á¦yÏÿðˆ­¢B,T¶á6t‰4 Bk±˜hCkqT"QµE)² ¦xŠáVdš§pï+ßÖmÑ&²X´Xe€HÑ& °‹©øj çÀ Â8ŒÑŒ>  Èn&°Œ&àcYr‰?€1Ý¡B<%ˆ+Bˆbˆ‡‚ˆ9 ˆ¦Àˆ¯æˆ�x(’(�Òq+щ™8B<ÅSêø‰tå¢8ŠPЧhн8«h48·g¯¸j±8‹µx‹[”‹²‹��Eö‹Á8ŒÂXŒÀˆŒš ŒÌ茣�æÔhQ°Ä�0Vˆ¯rˆ×˜ˆ‹¨4�Hv�ø ‘8B“H•(긑íˆEóÿ8Šöx�ù¸�%Ó�Eö�w�r@‹U`‹¸øiºÈ‹ 9 éù�ŸfŒI‘Ëh‘‘b i;Ñ!“Ñ„Hùb É)"i!0æ�à¸g⨒äÈ’é’è¨ê8“tÙŽð˜M HôX�r�øØ‹š÷m@IdBùcDi”HY�Jy�L©�O•±‘ǘŒ¯ÆŒÍH ÏhCÑȕɎ –#©f)òm±Â�Þè—›p’��’­"‹®)-9/9—uY›3yG˜{¹“¨˜d'˜g÷j…éc‡9�I©fK™�Mù˜Q)™UY™‰™©™oé^iO i–Ÿ6š­Vš¡yš~©š)ÿ9žOòš²›r1›�h›ìYO¸™—ºI�¼iŠŒŽ¿ œÏç�­ÖmŒòb®‰˜©E‰ Ù”N©vƙΉŒ  Df™>¦y�P ZI�œ)a×ÙS¹"ãùˆ®Ø�ž–9€šª¹–liž°Y�é—qQí£ðž>±—¤H ±RŸ©ˆŸù”û¹jý™*š˜úbs„�ڔƘ Í9•É  ÷ Ñ)¡Ê!›™¡ÀÁ £Ÿ¹Eú¥Ï¢yæ�Ú©f&jŸJžx ¢èe‘\*£¶yRrQC’£x* ½È£®¦ŸyÆŸwâŸæI¤cGŠ¤Ê¹g)‘Kÿ Œ�† ª *¥WI TÚ1Wº<´¡¥Ú§_é¥`:žb*ddÚÑv¦j)¡�КæÙ¦pñ¦™ªrJ—tz"vê"yz'ʧà&œ?:”Ÿ6¤Z¨F*Dˆš¨E¶¨Èب>ð¨‘j•—™%²©ñÓ©±¥°ÄS's2£JªžBš#š0¦ªªÈª®úš°êeax†§ÛZ«µy«’«²«vÒ«|nߦƒDéš„j¨ÈŠ¨áÆ¬šà¬Ðꤓ9‘ÐY©Ôj Öž:´êÝÚ/ßš’¥d±2$©ê—fê­z(*º-ºîêtðŠHò:¯»Q§°t§øª¯<nGÿæ¯Ã:¨Å*° �¬ˬûh$0´DK•”¹g*�Yi¥,Z›“[Ä­›± ®"Ê(ûi¨²èJ²æi²n)k+µ-k«/‹«1««3Û”¾j³Lƒ³jF¬Çy¨Hú³‹´ZF´Eû¤ ‹´Ñù°šÚ´¡A›ð‘Ù˜("«y–¹Œz¢dw'x×Zë—ȸ2B‰w™ªk¸ÿ$aëZQ¡Žœq!ÿñ„·p±ª»ºg®ûºÑm•2)ó¸¶[ds€Þè��yYaÀ·CkŸfÄ[»=Ù 0Mb°¼Ì‹ Îû¼A½0½¨ù Ÿ@»•ùc’©2R*£a¸ˆÿûŠ¢yÒ긷Kd"+¹wG¹fj¹š€¹Áª¹k"Ë4agÔ¹¡ëB£Û‰¥Ë"‚º«À'Óº¯ëº±ûi³K»Žp¾¶›»ÿ·»ŠØ»—¼$ ¼jF¼F`¼¾™¼²Ä¼ÌkÑÓËÕ{½<•J Û˽B1à+–‰ äÛ°ÌÈÀúȪê{ ì[®î ¿êcò«%XQ¿Qv¿¸–¿eAº›aºúÀÀ\À¬f Œ½6Ü”ìl ìVlÁ0†Á'|’¼H¼¼ ,½Ôë—ÖkÅ:Ú ÜK*Þ+/œc9Àk™Wüj9¼Ã|¹n?†w>¹�û¹¹ÿ„¥ ‘Äü»Äþ{ºO¨º�kåk"û¥S c ¼À}œ�YÜ[ÜÅAõÅÃ[¼ÿ¢�dWÆŠtÆb�Æ"<½ÑÖÆì¸qL$jÒ²qÇyLv—üÉEöÇ›œ‚0„ ÄwwÈCüG"a›©±Èœ*û‹‰ý[)‚º•\É—œÉ:Ì9ÐÉÀÜ‹Õä\Σ•¾kʌʞ¼ÁÊ{ư<³l©,¥pìc’•º¼Ãz\dÚμÉÅÌÇL †¼"ˆìΜÐ|­Ò|RÔ ÉÖü¿O˜Í�»Í¬ªÉà Îánã\Îä|ΙÎÀ Æ/&ÆõìÎ ÏÂòüi´¼Ò–ÿ|Ï*ü"¹\Ç…kCŠ)šùñc"ûËm'“;Ì}Ð m!º– �­Q‘©>¢)ùmÍÇ4¼ŒÜ<žú1ÅýÑp'!-Ò$=Œn6D‹Ò9 Ò휊«üÎb@ñ,Ë2MÏžl¾·\$û —ØÓá Ô¬*ÔÀ<ÐS|Ô¯VÈɬÐXQ˜ÑÔº±HÕ12ÕùQÕ­vÕ5œÕ˜¼ÑÚÕüÕ¸ €Ö;ÚŸ��b=M"=Ò_g-i}ʼÒn�¼p-×/­Æ0ÏV\Ó6�϶BÇlÂÏ<]¤>Ý€-¡‚ýÉ„Èï;ȇ�Ì· ÌBÁØ—áØšÙ„;e!Õ+BÕ�ÿhÕ˜ÍÛݸ[�’ž» Md:HÚÖkÚv2Öæ¼Ú¢ÕÚðÚëÛmMƵí�·˹]רk¾½�Óú¬Ó‘Ñ×Äýרš­ƒh“–ÁLÔëkÔÍmÌÏ�Љm!™JÝ–aÝcp Õ;ÁÝâÝÏÞ˜­ÑiÚÙù1Å©ðâ0Ž6ëÍÞî- ðMθ ¬]ch¼°=ÆöÉÊ!À¼¶M0M×j6Ó ,Þy�ÓÁXˆàÆZÜÇýÏDv³øà&éǮþ2H�áý±á»ÁÔµy»â ¡Ž$nº–�gá-ޔʌåýˆçm0ãN3ã¤]ã7Þ9¾ã4Öãüã²­ß-ÿ×üm中Û)#àŽËþä�åÃ=å n© ¾gXþZæ\. EMÐnОÔc#>âÚÇl>ÙÝ]Ùß}Ùá­â(jç-~Àyþâ2.Ú4Þ‹§-K© è(èæÚ>~ß@¾ªBNä‹>GþßIn×rÞä“>)¢�…”ýV¾gfÃÞŸ@ä^î�Ù jǵšQ»  gê>š)ywjÆzÛI ìºârÍOˆž¡ŽŽŒ‰…ºßž�±ö{­0©¯–¬·ði®\îñÑ6Œé {lv2Gú±E¶X4�Ýbj}Š@.dóÝ©—Ññ¼¬À ne´’ÿJÃv2ŽO‚EÕ±ŒÁí³îí¾Ü‹áÎÞO�Ùë© îšÇî•ëîé¬òþˆôc$š"ùâ+¨›Z¿õ?Í—8ðOXð½xð/Ãb ¿g ïðg<ôC?ñÂXñ4/ Ÿo‹¡!òK_òAvò^¡�.óA%ó?ÞËXólyóW”ó,Ñ<_â"öâ¦4â>ôEßëHOvJß¾L ðN˜}õ /õä ÃÿQõWï)Y¿õZßõýõÓDð?ÿ¸dfg_di¯fÏöïö±÷ŸñB´ñZÔñwÏÈ ¡÷žÏ÷Oÿ b~ +/øÎûò1ï·‡?çŠ?&8ÿO:?‘ÏÄùAùAOÚ˜•F¿ù�Ðù<üù¡?&Oúj6õøžï«Ï(­ïú°?U! ¼UÐ`#„.dØÞCˆ9$NlÕ*ÒÅH àØñÖD‰bDŽ$RÒäÉ’ %Æb©ÉeF†&dš�&­ÁÍ>9#ì,Ó“F @ %Ztè¤I ¨ÜÔÔÑS�y¤>£Z°ÀÕ�´ÒàÀ(QlaY± S6Œ´.5Á\8“¦4ªxäâñP7Ã]yõ~åÛ×ï_À�ýî$+V„‰k\ÈÈñã#‘%£$ÂÒr¬T™5?~|™åÀ�*s4Ý„‘QC©y¨>+òðUÑŠ¦NíVfÿMÜÒ LÓÛ7Wà?ƒíQÜ8h�´¥&f¬Ðs,ãÆEWÄÈvaG�*G’¤ŒR´eµÖ¸­y³AÎ>„{–4pR¥L�BE=µê­ÃZ÷Ê7,¶±Ì:+­—"®gæ¢Ë.¼ôÊK0#”ÂÂvz­ÙkŽ3Ç$› ¥ç4ÛŒÃç� A4ÒL«Oµû\{-6Ù”Ëö·rÛ­ ß~ ®½ ¢+ÎD™kî9{˜Î"Œ4ÂŽ£�@ÚN¤î¼S ¼cš©<œtâɧáúû >¤–‰´§‰Ê>ÖðÃJ?þúú/@³Ðò!<¯DPÁº<¸+œðO@!®BîÂåÐ ›ÿ#=ŒŒ²E”4³âàR›R‘¡ÔVkm¢ W[-CiÌ­¦oɱ·ÛóâÕ"bV­¨"}<²:%9:—&')b³1öXÊÆbe"*תó6›²LoKöº|©K9s"2éãM«Öܪ+7Å"+N�µÚ¸æÊsÏ>t^z¿´B¬~M´9F‘sôˆc��tR+ !ÛLK»è´oYLÓÅÃD¥ŠTåL=5ÕUÓh5¨W½ˆU Y…¨µ¹[s�n×$êè×`C‰Ø –ùXe™m©Ê¶ì4=õ¸îÚ²ÝV¢nÍ\ÑS5¯b“\ÿÌPN:×}«]¹ÞmÿÐÁz³¦÷ÞÂòET6Eûíß™&˜RÏBX>…#ax¡N[õ5‰Ÿ¡˜6‹m¼1ã��êøãB™±’=+å‹z=€eí^.vf™k^éfus†vg-#X�G/ýJJh¶Ë<Óáp•÷§r<·,¨qVè@ªÔóê½´¶}B® ó—}{ ²e6ûlƒ×SÓ…�–[¢P%¾»6ÛN•^¾wäVe¥U9[+2Y:•¨K™¡•m9‡a‡œæ±lŽ%jËßÂ|ZÍ}v°Ï/z´ùŒnéüœ®sEyÓê4'×�ÇN±³Ÿút; Š+„Ú]ï4ò;�/`Öà`ÏVÿ°´YêRÿJQòþ·¼4OTÏ“JÞ¦W“ŒiA†3¼žÇ²²íѦ{¸2œ®Â‡¤Ä©ÌWækœ`¶¾€I.ÍÏ�æ×³jý ØÒ_è¼7p%-+LœX—®&.0AîbPÌqF4FP�É�… õ5 ùî"�rÔÌ:èÁ¢í2j¡£Jè6å=lns^Œ*½â&†3”a '8î‘Ì{=<Ùy%ÄÅÑIŽ‹�¥D&>K~Ò‚"瀺ãmBt�,Ý÷ô¯ði`eMXF4¦q�»J|ùK,S˜”�D–t€ ÅC™ËdC3�™Ë3åXÛ f5‹$ ²ÿXA›ÛT–²ÒñMy„³:8S t¦=èg$hD#½í:Kz†7ìiÏŒý@ŸûÌV¶(ñO€ó!Iç2S¥ýôóRô`h;Ï‹äæW¿:GEÙqÑdT£npCQŒÅ �r£HòphIË Œàæ+½Ðžöt˜¶©(IÑFMʆң¤ñ|ˆb&z¨<åiC%*4Í13|$U©á$©COzÒĤSAr©è9.ÊŽx B«[åå¼~ La“˜=f2—©Lg>šÒ4V5«93l†a›Üì&+¾™¦–Ô¤æŒj:Ñ™¡v¾Ó6ñT\GêyOotC±‹ j]n Ѐ ”ÿ è4è�ª•›æT¯›�¨JWúÙª^U´å¨G³RnÜõ®MÝ+J;+�Ï"Öž' mmaz™…¦5E-H5»Ù’ö41Ÿýìb[ÛÚ©JMj^�úT¾6"�Ä]ih/Š\Ún•«]ÔW}V±¢D ð(«lΊִ²Á¨l͆[© WlÎU›uµ+8à ÜržÓ¯Õì8ëÂbÒ°²5®bë�ÇB–ã�l5*»›Ë"³ ®C_ [êZw´¤í([Q«Zpnö¤)­Ile‹ÝÜ6·GAJMµÑ[nü¶ÂÂEußQàn X¹2cnsïûܧöµ6Ö0е«Uîv×»àÿÅpÇ{LŸ7éUïZ‡2M÷Î L øÏ`¼Úë5¿BNg«óß™˜|ô$p�|S'K¶!UæA/ c÷ÂD¶è†9lÚƒ˜µ@&1†ß![o XŰdñ\Œg Ïб1Žu Íå2×¹í€nt§›á>³ÃÈGNòŸ`Ìä8ÊÔåA«]Må.y ËnÕ2˜º–/ÛwÐÏÕ¯_3O4Ë$žÀ=æaï‰ã7+4Õ‰F³�Mçx 8Â�Öi…Û±gP[ÕÏì(­‡C b¼Š¸œ…61bSF`·/îmž7KãFTºÀ—Îe¦—æN ™ÏÚ5v�<ˆROèÔà]öÿCVM\W¿:½±f¯{·QkøÜ¹Æk˜÷Úë2ËØÁöf‹Ýfã&»Ÿ‡‡³ŸMYeJûÎ펴ž#‘›}o›Û¾òi¿-hq»öå%^)¢Ï�Ût¯›ÚÖn¼åm\z£ÑÞ>fm¾òiâÙߤx`Ž5ð°’üàŸMx«am-£ @ìc‡xR$NñM_œÌÕ8‡‚m‚[Ý ¿å0b‘ÝX8¿Ûà1y³¡­r„ÝÚØŽz¨7ÜíšZµ»ñkË}ÏŸ¯XÝ-æ-Ë«-iJS×ÒØÝqÀLñyÐÏ=ÈOGg̯‹] ¤~»UÿËÕ{› ØÇ¸é{4lÜu•áa»ØËÿŽ”³÷Ì»ættA ä'ÿ×n·Mªâ^Ñ×ýØnnlìe¯wòò½ïÇn¼ÿ}ÁW˜ð 5üh€�Þ|ñ9'wÏOŒÝE£n¦”g7jÝ­W£k~ÞØ=°h@úÍŠ'}˶«B±Ô“€Õc½¾p=Ô²>Ø›½†¨½Ûë:Ý»¢è=ß“™- >ÅK;^KŒäS¾¶ã q¾ç‹>Ž06{º» rÀLHµŽ¨=îC®ï?Ë#ºñ«®ò­óK?�7Æ7Çs?sƒ?t“?Ý¢¿ð‹³Ì#®ÍC®þS‰ÿû<à@Ò2<=ä:ÀTÀ¯`À�rAd d5 „¦Ý»@ ü=.»5ÿ´³¸DˆD¾åãŒýªŒ;<L,êkA„Aí3¹¬­ô¾%ä¬�ã¹Âã·Ã£9ô³¹Ä91ÂE|¼Ù2B CÂF{´´¶üsÂýƒÂÆò¿)¬BÀF,@ÔS=$óÂôÁ0 ÄÍ¢½¾›À„«@)RÃÞcCT?,>ŘCb¨ÃǸÃ<”»œ“¾üÃ<Cì‹ÁíC¹hë¾CLD½ÊÁwаG4õ[-öÂC{?䊿ºOļáÒ?¤ã¿R”ÂS ÀT¼BÓë·-tE€ƒE¾C�‚F½²E“ÃEWÓÅûáE²Ó@[sCáÓµ¹Æ94FÇ@Æy¾VØÃ>dÁÿg¤EüÛ»�AjD±C¬l,)mäFóƒDYÂp¼D"„½EÕåÙŸûÙÙíMÇøÍu9Ú5e$-PÚ`bZuZ¨å`íÈ%®½´Z‡ÍZ¼ÜY@�ѯ½Ø°ÍرÜJ³VÆÄVÀP[ÊíÖÇÈÚ•�¹Å¢M…àòÏccÝXWÿ/ì[-¥&œu[ÎÝ•šW¸<Ã%SÄåSÅeƵÇýWÈ•\,ˆ]ãµÜ_MØæ¬SÎeÖf½Z=ÝU݉%]‹Œµ?�½6Ž]ݳuÝ¿€]kÛ‡šÇÚ­ÝÛUˆ–ÕÝÍâÝô]àU@á©¿­ÈÀu ä}åuÐæ� ó­P~mÜç|ܤ݉¥4¦ ³ã __]Nï¥Z†õÜb ÚX�ØÖNõ}VÍÑÔ-ÛŽõ]´å ûU-üm+Ü_Úí߸߇Ø]˜í]™UMšmßîIÁ•ay]UvÕ$›à}]Üg©^¯¼^ ž\îàíEÎ8íÞ©_»Sò=s±ÝLáÿâãZnÖŠua ÏVT�UÏ×­¼µý¦rØc>VbÇàaþ]r¥ ®Ä§Ê[ä*`Ö;`nHâNPôu`'¦×† )~.¢� +¾U,Ž€ ^¼f­ÆÄËMËc÷#ãÏ͆3®©4ÖZŽä6Æ®ÒeßÓuß96Û�¥_¿¸á»âã>~d@îaAfYå(äÖ:)D®-EN²ú«J~ˆfÑ[bEuãÛ"ªxI²±SÛ›³KXÖaýÝd-(gàØV’u¹‹PTÍ|Ž#½ÂouÉ]6ïêj Ff»`¦Ø(gتæ†=ÆÁu^Voèk½ªÔ ŒV~æªÌOÐì4EQÿ©½&% ŒÎhÁ=fæ¨VñB‡¾«hæ‡ifàHþ,k&_/Üf<îf¡Ýaqör6g®@ç÷­vÎLwÞUx.7 Ò3ªç{†Ã¢{qžeìòg€~á�Û=è„æ0HLÛV¦8ˆþL‰žhƨ辻èŒþê�žjX éoé’†d&¦®”ÎÓ•;nžDoöcFHŒ˜ži8ç…”ÌtÞÑHÈéyØéníi"üi4jËÃg£ÖçÑuã~.ç¥ÆÑ¦Ï¿6h„F1…>?ª>c«¾êYÈj­6æ<°hÎüj°Fަ­…ÆR³N´Î9j6϶&ª·F€¸¦Ë¹f„¸kÑògÿ½VG/m/qó>qô¶r\qÿi†m“^kâ‚qwhÜÚ“šÝݾñüæŠ~Oˆ­Žþ¬e²ŒâÝ,ãÊŸ>ð�Ê)‡ˆÕÀD¨NOög˜Ì=î�eɲlôë¦Q©®Á`@pƒè-�»I9mÐøòñóM0qWKÍÕfM4'i5WëjÖDÚV@–†súNk»¶óÏk<Çã‘ý†=Lj>_©?g‰@׫A×ÁsøéõX�$Ç>E§ FGhGtˆt›tþ†_KG,kÏôÌVM?ét·Çç ÈQ/ïR¯�' SõVcõôéõNóö^óY_ÞZg½[ϵÜÞ÷º®sçÆï^Ž<ŸÌa'O6÷setÿÀ­°e߯Šrög/ƒhßÈbZô–´'k¯-lÏvb‘ôr to÷WpwîÜôr·ºs±t_÷çkwŒqxsŒž÷1_u{OñWOëb7·u¸žñ8Wã9ÿcƒgÊ;§�…öæó“6öˆGö‰®Š¯*Œö�.�òøKùLymï-n—Öö»ôpOÏqçt˜—Dtï1šuI!õ�0uôh� I¢"*{7óW•™ �õ�mû~(z€?z\çÓo^ú‚ogC|¿*ßþõú ö†'Û‡·úx�x¦ø!ÿVBÒŒ/Aôpê´ñ{D yÚ2û’ßö“ïöµ_yØ×ô*‡{ÿÀðt™§{Ï`÷»w÷¼¯˜9ûöû¿_�À÷™)|‚?ü¶Wüª ø…øgzÉo6Êú¨ßü¡?öXHö’Úú‹7ýŒO}†b*Ö{jÿøFylGþ�J{uVù{jû–ßý—�í ·„é2Äçða¬ˆ[Q¬˜ê"ÆM7†èè1È�AF’Lhò¤É**W®héÒ Ì˜gÒ¬i“悜&2äç³PpB‡+jÔҤ疞hêà)ÔARoRÍiõªÕZ·&èêuëV”ܺ+ ôl»Hj�¾kë¶\vr›Ò=aî®Um(~ë‹6¨PF‚‹º}—4i<�[ÿýEXð³È…'û«ìá2æš7oÜøé3è¡C�.ÝèôäÂKÏÕmme/Ït�‰�f[éj¦­%ð–:ˆêM«bÅn+nÜòäÊ‘çhî|¹ÞÒ%øö­í:öì×gèî8øð6…+Œí“ßYÑB�=ìm5]¨Q§Š/ˆõþ°Z½~Õ/–¬Y© [“ÁÕ�\ì´f^9éu_~ý5”`Œæ–{Þ$¦c�VadϤæVeþ`–Ùfšu¦h¡©Wši¨�ø| 6õ„±Í¶^m·!•›nuIç[}öé4ÜIÆÝrÎ=·œwß9%•UDÞXæý˜hì•a�'È÷ÿ‘U⇕~?ð×Ušÿ-T–;� X`a&¸à]æä[:}}³#8^ØV†zÔ¡‡�1âŒï”xâe)ª¸b‹Ÿ©Œ¤�ÖH£a.ˆãN:NÈ#1¶Eƒ[n I•X"É�’Å1Ù¤“9@ewVêº+pXÆ–Îyé©ç%1`9¦e¶zfVú±ñ,´cH;­›éÀ)çZƒ¾×\­å¹gŽ}J蘢ÚªXˆî¢d3> ©¤¬¸I¥Ÿdzï›vä§|2¨Q¦¢êiS«þf摯ÂëA gÝ}¸J¯[|e¿Ë%mìËšSc*;%³Í‚m´ÓJ €q ˜ÿ-1©ÙÙm]ß:ȧŸ€ 3†îº˜‡BÖîˆïžï¼õ⛩¾3\¨åñp�§þ¤ª½±JrN3ǰÃÙt06ÙOåÅiïê«–èqLj{‡…‰ìÈE–œSš(?«òÊ˵Œ-�Ú¶5³‚Þ6¸Àƒ¡Šûç¨�Æ3¡>£«î¨ìŠè®eðJšt¥KÃØôˆOÓu–S7°�ïa½›Ö/»€×(źMØb“=¶Ùgçª6ïSVûoã;Cžá‚ó¹nåÝ  ‚Þlð=tp^û±2s[x]÷%.uÎÁ?^عÝŽ¢6ê¤ ½¢çžƒžšè7ò9>±ÛØTu[÷ÿýû_ûíp‡ÝIi¤Êï¢³Ç Ï=Å#“þ^g•#P°‚ËkÞó¢'=—¡¥zºÞ‚´‡³q Ëq‚œa$'¾ •O0çk‹©LE¬öÑ0Fœr¿\3¿ ÕÏ=ñ;AþŽ·?ÿý/lì@îtwÀ%Ú$�²ñÞ x˜&+‚\»J-ˆ. òMƒÒkŒëÂÖˆ0\Ý#— Í¥ÂC�¯…Œxá;bh›Ö�†ï›ÌI<õPn9¬K™HÄþ0€I<Y'.0Š=›bkŒÇ«ûd‘‚Ô[—³Až%ŒÛBÍèRFÅ�±„;ß�ÆBZŽQ“‘c4èXÇÒÀ£ÿ–¶¼£jþ8ºòÑKö»_ —8Hòv‡œ˜"ˆ�e2S,~*%—„ç–~P³šT¬xj‡…mr³’G¸$Ê2©œMÚÒ–}L á2 ÎuŽ’{$Œæ÷Ü2�yÒógéj#+‡¢Ë–²œåÊYKÐýòV8(Bõ¨À·�ãœWÙ Ö¹Î`p˜Å,Û H±dî�™ÍDÉ3ßI¾r ªšÖŒ$…˜Í°q³›•gÊTæE8 õF:%š�v–š#M# éYÏÉá³B­$š[üé%€ÒR õa�ŠP^^ê¦aÒi(j@‹Ñ�% G;êQlˆå<ºÔ¦\Y˜Aå nÿ}«â*×™ñ>³ë^ó:/\ðµ¯B�'ëS¶°�±å K �#A Z§wÆJV”œÇE¢) êb�Írvy³ø,h/eTÁ0ui›Jë>ŸZÐ6¦®}í-b+[ÇÊÅ ¶Åί5ÙÊö ¾ý-mÙ!“°·¸“lY}rVõ –Ÿ$ªL[ßêV¹Îµ uÅÊ]óŠ×½ö•¯�G`ñ0ØÂö°µLì ¤àB¶;È¥¬O,;ÒdÖTœí,ºVûYÑŽ¶´ø:íiR«Zý¶öµ®åmlƒk[/àVThÜ-‚ \Ú׸¾p}Þ{³ª­Fj[ØúéN—º kÿþì+ínwEÝõî_Ã;^òšèUonØ«ÎÈŽ5¹ü�¯P0[5ûÞמ!Ðï,økTÿÞ À�0’ l`ßBÁ·½NnaÞJØ·Á­0†Ã,æ™hØ$Ž„‡Ÿ bGAwÄ$6ñ‰­›b쮘ÅÜíîweÜò–÷/ˆU¬«ã ðØ£>2¦è;dÛÙÈHVr…˜Ì4C™Àñ&•­Ì`,;¸„[îm—¿ “1“ºÔ’]Þ™M êU77¼á±\â8£¸:i¸5® ë]³¸÷z1.–§çðÙ÷úszåˆe3Îí €dà íiWö3ž«¯m¦=íåÒ¤•tiŠÿ ‰H¤1˜FðLŒèèV(TîòfæRÓÛ¸§FWªW­êV»°–uKh-g[ãúÖ»æ5‹ï%�…3\Ø‚Ý3Ÿ�}^@Ç�ÙÍ6ñ³£­í0TÛ^KÃv46nóÙÛŒw¸ùÞõ]Òe`KäIžp ‚àÁ‰`i� b˜ סßé©‹­^ ìÉ^‹\ € Þ äàþñ Pøàþ¡"F„Þ*Gò!`>a.¢ÅL¡*^¡š!]¿iá pá]x¡÷�ᮉ!i�¡G˜¡)˜Œ Þ¬àÅQ—ëaÃÆ`Òž©Ôß´Ùáò™êa;ðaïùað` ¢Mbr¢ò%"V0"2îʉÞQམkõç¥çi]¯…ȪÕ�#l#7.+|#8j�F ] "\8G”X8‚#tPàh1‚“iBY-ŠÿœÈi1Þò´Ô6ùÝì<ÄCøÝ”äì€�Ã$£B&’54¤C6ããÝKL$EJcÔQcÔY#‹a£ªi#7n£7¶#+ˆã&�c€9¢£:npHtÌK<Îc­ÔcN,#>j›> ö£?ÎD@ $>ä®$B6ÌB¥9äC²œ3f EV$‹M#¤Tc­\cdd# }$H¢‹HŽd­Œ#)–z¥ds¤ã:R…K.LŽ–L: M.€MÞ¤´ådàí$ºø#ød¬ePj¯¥’ÔR¦Ú(eCB¤IÂÈSN¤€Iå‰P¥“Xå3`eûh¥#„d;’dbŠeb‘e˜%K¢ÿåX½äŠÄ$€ÑãAYÅÕN>Òes,!O¶p “P¦Í0&nöŽaZb†%i,f4æENeFÖŠ“q¤ ÔÐò`f8~eIú挥®å•JžåM¤¥r¬¥Q!jZ�jknœk¾&J֔ܦ0 Rn®çÅìfo¢¡b.¦pFœÖçUv$ -'WФfB§t6u–åJjEKަZ–æhqçL¦fM‚gØ´¦k.¡y zV”z²§†êŠ{2eD:¥|¦–cbçÁ’“Ežç؆ì‘Ms: XÂ'g¢¤®ih¨hzivÆöŸs0Þ}¬fí )‘i…ÖÇ…nU†nÿ(“I‡’Û¼Hdˆî,Õ'®™(€¡èÒ¨(¶èؼ¨sÄ( žä®Ùh�þÀ�êh‚òhúhs)Vi‘Îi‘©x$é-i“î)p<©DD)ˆ>¥€U)q–ž––â —.§—v˜6‡˜–c�ÖÊ�¢iŽ2ÓŽnD�þÞ�]�B(�†jØØixà©ê)Ÿ¦*MøiDj| jjÁ4VCjê¦$ªÄÁÊ6ê£æ@¤’é¤:I¥¦)¦®©¦¶)§¾©§Æ)¨Šª³’*x˜*ïH«ªVën6á¼\ pªÍj­Êщ]ŠÖÒ®ž�‹vå7Š)¨™Z§MH–dÍ˦Ò]§rÿÀ§Þ޳æk6@ël¢ê©QµlA\«f«zlk¬v+4~k …«¾�«®v©¹~)º²‚º>»Rê™+¼bƒ¼"+½*«½2+¾ê«¨ò+UP«mú«À¶,H^�ÌÎì¼4%ŒDpzbQàò,ßÄv™-“7Û¼à�-ÒÂŽ®Ì-.�7¥ËF­ÔZLÌάÌÖì‡ÞlÑ'ʑϢ‹Ï’Ù-6 -Ÿ-Ë!mÒîÊ05-º<íAL­ÜÎí”T­Õbíf’Î.f×À×*FØŽmA0“Ù’Ú’›Ú­ÒZIÛÚ¡ÓVÔÒ­äN.MØ-Í®ˆÍ–ÆÞ>eßþ­GÿîØ�máÖáJDâŠÁâVÉ0QÇzTäR.ìNî}XíÕbnÖjîÖòm×[Ï&àÏ’­díŠmâ¦.•¬nµ.3½nì6ïÔÎ.íâ-tn.Eö-ï‚­ïŠmènÇ og¯Úïyë*/60¯ó¦¯ÀBïÝÚnÞõN¤ÕÔõ*Fr,6xïFàÝnН…’oòš¯ú°ÔÞ+Ù”nDTDEÄo̯@Õ¯GÜï¥v,ÇBÿ²-ߎùbwðú’ì/Ë)0E0°—w„_§ùVðë òj°{0 ó©� _â ·‚¶ê.SÑ/Ÿ-Ï ¿«ù~�’¼0ãfÿ0Ùlp 71“Þpäð“ð¥d.iÄã¥1yAÇ×ıq ±ê*ñØ0±ŸqnB±“ÛWñí^ñheñ÷brt1M|±ìÄŠ/w€£1 ïiíxÓêï¼ò&Ð.,!ttåMVÔŽ"2%W2A r%òÙ"2'+2#/Ç#[²(�2†ari²ár2"{2BG(“2,Çrq*“®*2++Ÿ+�,÷²/3‘œ6Œ!ß²Fäòàíòíü²2/óÅóA 31³à!³à2³5_s}8s6@ó-KsÑ+c³8�óLhónó¼(òE�3Ð’³;»³9&:¯{ˆ:w;oï;çó5dzRþ¤@¦q¬38ë3A33?;¤??@‡@‡sA?4,tC&´C,4íØó=C´F‹3W9ŒßÕŽÊn´H�4I—´IŸ4J§´J¯4K·´K¿4LÇ´LÏ4M×´Mß4Nç´Nï4O÷´Oÿ4PµPP@!ù,BÎÃÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹hÜÈ¢£Ç CªI²äH�7nÄȲ¥Ë—0cÊœI³¦Í›1UjDÙ1¤H“@y²Ð¹§Ñ£H“*]Ê´©Ó‚D…ú 4(O¢O³jÝʵ«×¯£òœú ªI¡XÁª]˶­Û· Å¢$k¶$Z�póêÝË·/M¹§Ö%yW¥ßÈ+F ¸§`“D"KC¹²‚ËD‹.Þ̹³g¤�Y� Aº´äÉ•)_V°ò³ë×°cO =º4éÓ‘S«Æ¬Q¶ïßÀcÏN|ˆñã9’+·}·î0«[ŸN½:[ Ä‹7®|9sÜDžGÿïm½¼ùóK±gŸ±�{÷ÌC€Ï[3úûøó;DÀ¿?Ù^ØÀ�Z à‚Œ4ÈÈ@ð^ R`af¨ß†ÞןS( n¸à‰(:ø`„Vxa†v(ãŒÁ}Èß"î0`‰= è£*B(awb!0ÆHã’Lzf#8ŠÞ�T2è �-ù"ŒMvéåaOÖfÛ”U*8À™hÉ"‘."™ä—pÆéV˜SÅGf™h¦yåšÊyd’È)è \õGRHG$_™Tæy¦šCöÙ& „Vj©R†Ž„¨¢Ì1ú££@šåŸo^jê©3eªÂ¦G,ê)Š Šÿʦ–nr‰ê­¸^¤*«®¾º`¬{FšœŸ[j˜ë±ÈîÇß¡ %Új§¾þꨬ’ÒúõØ&«í¶íÚ,§¶E+mžÔÛ&¶Ùr«îºt »ðòØÃ Ô[¯�&ä«ïüöë/¿6,ð,ÃÁØZSZ1<ГëF¼W»ðÆË#½öjª¾ûþ;ÁÇ õµÏ"Dy_üà7¿ù Å~œþ¸·?Øùïàù hÀÐAO" 4ÉØÀß=PxíJa3¶kx ztS$Ø_úº�w¨Ã+øð‡&3™ÿ†HDñˆy’ Wh8ñ‰ù;‚¦HÅøØ 7O|¢P(õ²%²PK„á�@2ÃÔÔІ„Ó¡Û~Ä Ê€ˆE<¢“h#/61‹:ˆ"«hÅ1a�[,•Äì8˜0 /†e¬Ì‘�Ƭ‘�Wpãáè9Î1"Jt!Pð˜ÇüíqŠ}ôãi8H[ R“,4¤êICÒØ�‘TË¡#ßs…Øò‘t£P,):~ˆ�$á¤?JÓü1‹¥4–Äf&‚/ª2u¬4£+ÑË|©‘–·Ä¥PviI_ö'G; „Æy�(zꊧñ�:×™L%-sfÎt¡¡DÆV†à•�\c6¯°ÿMžðÒ›ü§8ÉYÎü�ó;¸Y';yÂEu‘„™Ï‘×3%MEN–›“¥>oÉÏ~z䟘\ÖHÀ ‚^@\T�BÕ)”*¸T™ÜzèÌ"Ê£çÌ3$‰¤Ì"ó‰MŽzô£Ý )HBRܘ¥¯Z©äåÒ*Àt[2­MKdÓCŽQ†öÄg5MpÍî@²£?)DTUÔÓ©ŒR*S_êΘŽ¢º‘×sH@׺ú­¢:½(O½ ÉŸvÄw¾$jŽJJP´¦u¥kuj[Ų�D^S-Ð\ëJ×»^5§aØéV»ªœ¯ú•¾›èAÈ:X£Ö°UR+�šúTA5V �}Wd 4YÊÿZ–žX•æ=©™QkÎ’¯lülhå¹ÒJÉ´äDmj»Z¶~ð>,‹8DÈRF©EÈ®vä:·5•µ‚ŒI8@ÞîˆO‡ B“ „ ·•à½ðý¤ÀÎ=Ø÷¾€ öËßÿ‰Oj¨€€œ¼�¥7OØa�"Ààá r„®Þ¤;ÝTW¶×]©�¸{9ï~W±¦ïHÈËóB½^/{à^ø¾W¾*]é}ñ›$ýòw¿þ…€Là­æËÀ>S‚u¸à3øÁFOtCTaêNźaPê†ÔÝ÷|Ä­u« Hlb§WÅìm±‹aœPÏxù5É�qìßó¸ÿþW�…¬`ùÈF¢’'Ìä&[øÉ޲†SDå[ùà ñ–Ë«œóÞ È`nï{\üâOÆX¡gFs�ռ滙Çqöל0äÙÈHÖóyˆÂL O÷Â"¨Œ” ͈*wçʉ^×x�GCzÅ,ž4¥ÉœN3Ï8Í%Q*€Aõf8ûØj¢žs©Oíà<_rÕ:iuŸ› kY«³J®�‡¿›k‡Ž˜×9ðuŠ�-æøZºÌ˜>3²I¢ìþå©Ù¡îר§mg1Õ×ö�GJ8fFQ^J%Ës<îqƒ7ĸJ¡ïv]âFŸøÑë^q»ßë£K¯3Ó ë ¾{ ¸_ZÿÓ�ƒÌï4øßÖî%p^Bƒçá+•ïsÖ îB‹ûÐäoÄÛ5ñsW¼×ÿµÆßƒT¥‚C"Ÿ"Éo樣<å"“×¾ëìrà2ÿ Íhs òH©:×ͬOÔp ?<˧’øz(ÞeŒ™ÝLG©Óå u“Œ|¥Ë®úɆu�i]Ú\¿sÀœ±Ï¯ìÝ;{Î?¹óA³Ýç&-€æ7_nTÉ=;t·¸—7¶3˜þôM_éæ9ß÷’ü]¡�7y®^xÈkåt&r¿QóÆÿµæ3;¸äšöÔ¬ÝJµ¾\æW_€Ûùf‰¾‹ŸïNØ�Ï'ôH=ÕJzÓ§^¡Ì/@ÿÈý.uÀÛMV'|ío/g'þÎŒŸùïÉü›�Å÷¶B§œü,õÎ'зÒ·ÔÇÖ7Ø—nI—bÜ×}ß·Ná7~®W~°w~g’~P{Ã~ц&-§xñÇ:Nœ$_ò’cÇg&g²Cñá6Ê1NUC5À¶yrpƒ+�ƒ:ÈD1€ÙN«±í1$Fbà$Û ;R"9¦]Úd ‚oûö/;$0 V0ÌÚ…‚ÿRƒÌ§x«§N—i;$�šW$fmŠA&ˆG(È#*hyãâ‚̃É!ƒ9Cƒ+fƒ8¨ƒ9ȃ:áƒÄ„A¨CX„äu„c‘„:ÿB"rè_>… "…ÒF…:d… †…3£…ÙÅ…ÎFjÿ¢5á'†›G†5`†:„† †×†%˜#'øI)è_+hhb‡¶�‡9 ‡Çìå‡rˆ�¸=èB¾cˆA˜ˆŠÈˆsáˆKX 96‰Š=v‰þR…s…“…̱…•Ø…B6Š?SŠw6†>P†)v†ê´y®È†‰á†²‡´‰ÿã)¹¨C/ˆ‡¾¨/Àˆ ÂHŒ+ ˆ*AˆÃ¡ŒBØŠÈÎ>QV’!/øX�ájS˜�™¸�›H0 é‰EŠ^è/¤†çxŠé˜Šë¸Ší˜†²†ªvò("³¸GÊÅ‚ ‹¥ÿÁ‹ý˜/ÿx IŒ¹9yÌX„&Ei%àjw-”h–Èr˜xšÓ‘ßø‰’´'0æhd討_ÆŽ>àŽ-ùŠñ‹2I�4Y“ùxûƒ;i=Ù? ˆA©CY”ˆ¨�Š˜””Æ”¸�TO•¶3ÚhÜ8Xià•â(Š"YŽ$ –&)–C–f.p~BE9†¤Yš„9jºÈ‹1!þ¸9`¸ze›;hŒAÌ$_Juˆ}¹ ˜.FĆz(5j`˜éµ3Z³˜�)œ'*]ù3'�ÒiŠš‡Šªx¬¸y�v‡š"šþUš¦ÿ9œ¨©�¤¡šyÈš<¹9;~±Y³©a›3ƒ›+Õ}Þ‡"âIš¾énòµG’ÁœN9jÆ *¨˜É˜ŠØ+ã’…'�ÓY’Õy’×™�š·�Šá�;žÿ³Ÿ8pšs–šèé‹Û÷/î)›Å(Ÿµ9·ùIJ…Ÿà#ÚŸ•öŸT ù).ÄY Žr Ê¹ ÐÒœŽòœ"¡ÑI�`�)‰�+¹zšÊ¡ãã¡ d"ªš$Êž&Ê|ïŸy1Ÿ,ZŸ.zŸø)£ûI£%`£ê+;úfz ?ó£EÈ 6é Xg¤'pea‰’c©’eÉ|Oª¢*¥S4šûY¥v¥:ÿ©žt©¥þr¢ð™¢ñZ/ñ$`ZpbºG/Z¦úy¦¥”jz£lš£:g �ªªšcr:§ Ú˜¥A�¦~Z£§|z™~š™€~ƒú¥:a¨€¨â©¨éŨüè¨%©\Š¢–꘺¢šZ1ö©P0j¦â‰¦£:E8£ä‰ªªšª¬ÚªUy•@.°2¤´ �Fz«Š™T£™‚Š–zAœã ™Ù[­É¯ë9«`k¼8>ýBVjj<òCGò$ ɘ#dñ¬khS ;T%É*æ„Ùu9%â6ò„Ï6ƒˆwÿS;“*»²ÙÔ²·Ä_àx˜p "ÿã8›³ë“<Û ð³µú¶¨ºW"ÄB|a¯x„¯¤i�‘©^{ølÎÉ/‹‡Ë/K´ò¢°°&N+"«7 A±�s1:„±RKœŽâ±²"²þZ5�Êr:t²r4+˲.Û²0›W2«•4k³“³:«><›> ´ö8´ÅZ´r´I;÷Êùjœ$;·S°†¦šW{Yû¸[ëC k# aëd>!±a¶•“6iÛ(k˶hâ¶·= ·PK·ýz˜w;>(K0{«²}ë·û³3{œ5Û7k¸°³=Ë? A븠Âu‘Û&“ë•k— §³ÿ»»½;Žœûsž+>{°£{¥û!§»© ck:áº5»Ÿ¾´k»=€»º{&¼û‹%‹·Í£·Ã[¼Ùô·™EÉ;µ„0Îû¼ˆ½0½ÕË/‹°F«½{AàÁ±Eð½û*¾ÿJÂu’U ƒŸº×«ÁµÀIï«Tà4¿ÒQ¿SñÁ{±²«¹´[»5ð±ï²Ù•<9¶u& ¼yK2Û.›i \ ¬®l ½Š+½ŒË„è‹ÁDëÂ"¹œÃ¸Â"|�&œ±êZ¾èÉ€B‹µê›°¤k!2üµ9BÃ;¬k\Æ;Œ¿²šÆ?|&üë¿EülG<ÀJÿ\ÀL|À- ÅÇ ¸S<«U|ŜżÅÒØÅ�Áò"ÆõJƧÂ>‚¹9ã6ë4¾’é:ë4°þÅÂŽ¢C®óÂ�TÇ%áqêò’äÑ}<Ê;‘><È…<Ä<â6Z“c;ä»I,>Á;MüÄgÅ ,¸Ê[É΋ÅORW›ü?ÖÛ¶¶[$Eâ¥mñË’AÊ(bœZƒÊê¤ÊýÂÊêäÊÿËy"˶ûU¶L¸ìºÌ# yà aΑ�Îx¢¿l[ÌÝ!/Èü3ʬ} ø»Î¼Ä)ëÈÙɉ$ÅÖìÀÌ[¸Ù|ÉÛLWÝü¹A6Ëa,Î�@Îl!ÐD@ÐNŠh²Îï‘Ê%L¾ðÿìò<>ôœ�$ÝøŒG@±Ïý\"ÿÜËe+ÊçÌŒ¢ÆÄÄokÌBÜÉì_Ë|œ ÏÍ�<Í‘¼À�û‘¸xÍ Á-‰ûÑ$Òœ<ÒálÒ(½*ÍÒ9`ã*2ììîLµ—ÓÊVûÊ»Ó=�EòÔÌ!/CmåöÖH]ÐyŒÝØÀFœ­ ýQý?SíœUýÌ·ÃK�¼MÅamÅc]Ö6ÂÍ’cßœ';mÒ'M©^uk ÌNè#á*®þÓÝ!Ó'LÓyÏ{=Ï}}ϵŒG� oëÔRØ1o#AlG=Û(ÂC:ÔØÔ]Ý�=jü«5“ Õ -Õÿ�{ÿã<·:œ­Õ]Í^=¸¡ÍADÚbÚ=€Ú^œ^«Í֮ݰMª²ý˜ RÛ 0×S×w]¾z­Â|M´~=Ü€Í#‚m„­ˆÒÁÜ*àÜ�Ø "Ý7PÝ×=gÙý3Û­•=>—=¤U-Þã�-å=cÔÜÕwJÉëÍÞ]Ú }Úþ•Ú@ÌÔ=ÀÚm½à$/®#«U³C�­xM¬x&U5#¹zÐäN^ s9¤qÙ¨ä`æ¡ÅD€(?Î#�L¾ý‚ ÌàNí:Q ¹2j¾æMÜÄs£T¸w&¯9Î@¹x^y>Pâ,Kñqƒr‚(O2†~èpÿ¾3ÿ"/ïùžbÅ]^"Až®0äÓÍØF>¼HNPJN™LîäMåŽ:¾0åxè#V.5Xžå[ž$‘n"”Εü"æƒÛ’m<5pæ`ÜkÎæm¾·o¾Rq>sN!Éwžçj§N|^é~΀.èQPn‡ŽèÂÞ~yÂè�^�îã9ä—#ä9Cä˜~gG~gIž3K¾y êåfê0ˆê©n/«^L­#¯N _.™a~ c0¸kæàÛ‚»ÞëjþëÀ4‰þ�hRì­�—v®xzÞìcž¶íƒ.tPí†Þð©­í�ÞíZ±ï=0éBêìé1�é{«xŠÿ·Ð"~íþ¢~™+dòî6ô^ïšdñ!D_ô\þí^ë`>ë_ë?3ð—£ëò‚ðS ð+;7n3ìì¿ñÝò~ƒÒNí ŸõØþ–;ä6&Ÿ(¯òãbé^îFvî2ß`4ï•Ìwó9¿ó¤Öóyw"±÷ÃC_ôDô""‘JïïLßoPŸë“�ðV¯²XÿZ߇,ñ=Þ0¯ìÆÇìaÿìOöqöšŸöÏClT]ñöáNér_äæ®éw�÷”íéìÞî9ï:50Ó¥–“èùóT7È…oøˆ ÷»›ûïŽïôt]æ—#žO«C“æ–ÿù™ß«7ß! ��o¸÷mÉ>‘a{®C*Òç¾å/¤ÁñQp$nb÷uè¸ÛâÜ X0ÇA„rÊ ÀCˆ%N¤XÑ¢Å5öàØÑÂG�E0QÒd ”)#¬d™ÂåK 1e²d‰¡ œ9 ìäYÆç / ­Q´FÉ‘Ü`À ÄS›Q‚ ™ÔêÕ¤Ÿ†ÓÕk°a5nìȱà��V¬e;ÁíÛœ9�~@ØÑ(¼8*TIФ ŽSNPØðË—c/–ʳÀZµ%Lv¼ÓÃe+V\|¸ÀsÐD?ÆÇ邌T3ø— ÛOF¡MÁ6ÿ°÷ @0Ç·Ô²�³ž½!u!C‡œ•/gqlƲ©¦Mú·dJ•4# v)s¦v©qq¾ _Þg™¹B‰E:riÓ­R§Ï·€ÕþU­O½~ öùŽèz8‹:÷`;à­·¸Ka®º8º+¯½úºá¯ÀÌ0 3dCãI8÷$£¬2Ì2ÛŒ3Ï-ˆÑH3 5‚Vc�$“^cK6…h‹â6ÜÐ�7ßæ®#E"®¸¨Žk¨9&›œè¿ç³Ê:°CI»í¸ó.&,ï<ó~ Š£¡. 2©Ø¶‚**ú¦»ïM# Új¿®úóï¹(ÝDÓ@ÝR�Áƒì*j/BùŠ3@ /ÌÿpQ;ŒÊÀ¬šlÒ*+@3LO¼(ÅKóôE š²ÆÔÄQíôQ¢ ƒ” R«Ž”ª!Z“sòV‹TÐu×OK+âW`¥L b‹µ2’UvÑ-%è2*Á$ï¼ôÈêL÷L áÈ6©‚Îü¸¢sW^{Eâ\tçƒôØ>'ø¨{0ªÐ�î¼óe´QA^5PRJ+­,SÍ”ã´^Aµ:Rµ��6U'jõ·Gÿî¬YkµWŽ#"Wׄ� VÏ‘Š5ÖJe—ͰÙgmŠVZjÇì¡LlEJSMn»%ð[¬Â¥SŒ�UHÝt§[×Êvߥ+P¥WÂñõI_ ùõÿ6€)µ”`M-:8ˆ„O • QK’ÓÔ‡£ˆ˜Õ‰¯f+Vâ2®µcº! :d‘‹¶d“!86åd™Ý²e„^3æÔ3Ó:4µÍYgžïóyÜ�‡& u d·O¥ã�÷i{Ë’º ª1ä·ßбN*`�ãÚàÏîUì…Gr­T´s„ØN‰ÛNýí‹ ŠJã�ëf®ä“×ÈæÅ;ï"ÔZ«X©°þúf‰_î»÷žûë±ß>µi(î3¡Ì2¡/›J“`}óÆ5sXHü�Ð!`/Gn“‰Çá³^³•­Ë>k¹@TXòo"Éã@mò”Ìo-ñ9fb2ÿ7æìA„´IG€5?Ö!$H,`a ƒ¦"Ä0@G²OAÄ<ˆpÆkRò”—:ï4{³ÙôˆU=o"Ûû^ èÞDä3BЧ>ö …ˆ­±Ž¥äwú… ! ÁŸôwþýj‹¹AÅóD)ò†„I x€Úä�ä -HÇdŒ¬Ÿ%ÂåèpŽLëÁ Á˜Âƒ¬°…,|aFbH„ûùϤÒ&«Ô˜rˆGŠº"`¤wµc^¥yjú"€…)79HÓoÒ°‰DlN¹Xž6Ö§�j;-ùβij·G-KR3«Ù‹üp8 âÛTĨö !Ý»¦jÓÖ µRÜjºª>ØÆ–de"+mwR;éÍ!g$æFÕHYßÊu<ä¹­:Üàõ*'ÕcJù˜Þ–þñ tnýÎ%5©™^dDÔ©¬“A»ä% pc‹·²a/fwˆ^Ѝ·Çüt/}àÛ·€„¾Öÿ³oU9“_Zí7Šýý/.¼7ÏÖÀ@ðž|ëöÁ�+±rRž 7äÂvÍpq7¬×óõÃaùËçžXº)fÒŠ£Ób4™dRR ó†\ãâ8Ç”…›e{0d¥ùš£ì,{ÅÖ­#ËWÉàc²fî[Z( @ʼ¡2k [,¥Àîr�¾œƒBs�6ó„_�f¬Y›m†¦q÷ÚW–vÀ¥�-qZm‚båZÄÏÁ)Rˆ^Lè0ÑŠ¾±ŽåÉãGZÒË¥ôz{|é÷ •šÎÁ’ÐdÒR$Ô¢¶“VUë_S[ÕVµ–YM¶ÁæÌa–5„Û(a ÙzŽ#ÿ†5,½ãæ ¹Ávsñl⃠ÛIË&R³m&èÉ@›ÁÒ®1µ `íñ:ÒçÝöC„üí"ïmÜ&›/§Ïíi'4Ô£VhrEy‡5ÕX5m[ _}Úß6&™Ç›L�;€àÌdóÁ÷”ð…ƒXØ"væ�et‰«8±ÌŽÔ†1㨚ã6¦6ÈÙ(òl“¼ä'·tÊI¶r©šÝÓÅïÌÛ�Z›çç_½2½ynoŸãûͯŽ5ÑgýïZœÂWsÁ›îf„ÿzΩsÕ;x¬ï9Ù¡8Gíl :ìÑî1¢‰àq³Û�##ÿ1zS”"Ä^öÚZ#Ž‹ ÑÒ½ä©BŽÿ#•¦Ÿ�ú¢H�|…BùË—Ê‘ e’ÐD€bËK‚Ù"-d_ûùL(¼ÿ}m ¿)V)SG~F¼×{f4Aš!q¾ý¨T¥ùLÿTÕû*h_*Y¼@ñâñ1 £Ð,@z©€ù¨*?� ùƒ ‰¨?'©?Ù›=S©½»½èÈ=>Û=Þó½…>ñ#>_2¾¾A>9X>æ‹ ç3è;¢¨˜¾Ó¨>/»¾¨Ð¾í¥îû>ï ?ñ#¿¡0?:A¿ô[?ßh¿³x?´‰üúK¿ûë=ý‹ þó¿ð8Ô›Ž4@zI@Á[@ñsÀŒÀô›Àô«ÀØ£=ʲ=bÁ½ÿ$Š9|ˆÞû½¨`@T¾1TAåk>÷sÁ’€?ôt5´ Ì>î‹#ìASa@ ¼!Ü"|=#œ$,%L2&|À'|½(Ì¿ìÛ¿,²B,,;-ÜB 8@/¼‘CáCù#Ã×3Ã×CCPC£»Â là |ÃtÛ½9 Á:Á;´¸ãC>> ?LB@4Aêà ë[ ìKÄE”¢Fä¾HœD¯¨Ä¹ÄL´<„¿&üÄ Å)¬%ö1ÅS\4ªPÅUìÂéP@ë`@YT)ZL[„=4ÔE¸ú¿^„7(8ŒÃaT¾cDÆTF>lFM|ÆhŒ‹ÿiÄ�j<€kÄÁlŒ¢mìÆàûFŽ8?�©?rŒŽ<Ç%Dˆt¥úcÇQ¤ÂR,A‚ŒÇ�£,V¼Ç/ÌÇ0ŒŠ&ìGÏøGÏÀE�ä-^$ , Ü<ôZH9hÈà{È®€2IÆãXFŠ4G¶xAN¼ iœAj¬Ak¼AlÔAFlD‘¿¤(¿’“,BÑ`?•üC–üʃxIŠI;Á¿vl¨w´É¤ŒÇ5:@ÖÁÇ¿ÐG C‰�À&I‘Ûh"mI”) bÁ±iÍÜÌèLÏ�Ý‹"¨”ʦ J‘¸Êˆ<'XÍÌ�ÁXI¸#è °¼ „À±ØMÞÌ'ÏôÌïëžÿµd€c �ŸÙÌÍDɹô�&‚M€*è¡éœNuôŒä ¿Ì¾&ªB œ¬6�Ü‹‚`y¢Ü´³xõ\O hO÷ôL|LψÌïéû¼OÊ´LbÁ1%èOÿDNÍüÍÎM…A…h¢ûÄÏD Ó zd�ÐÕt‚ÖŒµOÈP E²Ù¤M°ÍÛŒ‹Ü¼1ÞäM.8QÐÎWB� í‚âŒÿüO]Ïõ¼D½P Ýо‰Îé”Nm÷tÏë‹ìÔ‚}Ñ ѸÈÂ]4Ì€‘'&Í @JO}‚!mOøJù\úôžÍOñ¸Ì›Ñþ R%P„Êÿ$UP aФxÐ…Ð ­PÁxÑÍPÍýÐÓ˜RœQ(ÑÝDÑP}¥�Ѳ0S%Ò+}­OÍÓ=™RÍR (Ò8Ò6UÒ.TpÒ�€�쨂 Õ*�TNÝÒ°Å/íž0]Ð1ÝÏ25S4P5F•ƒPí1� «�Ó9­Ó>< ­Ô½T`éS�RA%Ô0ÔUÑD VFíG…Ô+�T0eV5ýÑ åTOUJUû$USEÊT-ªUÔV½ÒWíÌødÈ´�`Öœ SèVMSшC`ÓuuÓÁ€Ó‘0V eÍduÍ;W=íQÿ>õÐheÒi%Tkålõ¾uÑ ÝVŽXäŒTp¥UŠågý•L¥‚sÍÒt•BíLXQuWT|R{TU‚`UôtÕ,…UYåW›V[� €5YÎäÕ‚-Ðãèף͉bUÅ9¥SˆeFe�ØÍS–µX‘�Ö?¥×ƒÐM޵Ö�åƒ�]T+ ¥ÕL”]Î9V®mÙ"xÙ˜Ò™E$-ÚÅYE+Ì�•מÛª³R½×È׿ žh\Ç}Ñ& þKÊ­ÜŽåTÓ,Uù�H™`åž%Ý%@Z0 �pÔ—]Õu©¹˜ îQÒÁÀœ8�¿íß:Ù-§"¨ÜíØH-#ÿ¯Ù�•\-ú€�Žå‚ÍtÏ!h^–(•MÐØE „ ];Þä�PÕÝÞ5�|5Œ'J[ûìžÅ]Ñ ç$¾~’ ,Q�Bû‚m'a\Çm\ÈýâeŸÊµ\kÅÜuÒ\;á\Ï-ZÐ=ß-Ý¢8]3MÝÕ­ ÖŠ×­Õ)�]°^ðl“ÛÅ]”°Ýå]õÝ+Þ®ÞÍ_�ÀÞŽ]ÞölÞ!x^òˆ^7M‰êõECakÕ^îí^ÑøÞÂß½OòU ó ]R¥ÊõÝ«–àŽ÷}ŽøíUæ ßú½_ïÉß2Ù_ʽÜ,ÍÜ¥ÚÜÎU–ÏEó%]ÓýÔÍÔíeÝŽàÿ �Þ ®`–GúÈ` æ`ÅÚ]Êí]ký]ü ^Ž\ñ(“FÞÖLæuÞ•€^5Žaê= &6Tæ^ïåR_ß.â1âÑT#"öÕ÷ 3øeZùm×åd²â$áÃÍÒÝãâVe cÆ bc (ã=ã úa ¦àFÖ9Æ]:¾.;N<6T=>Þc1aãdkUa `a~¶O6žá¶fH^MN�äX}KLÖdV&\„²#޳$FŒ% ­›Tîæ.hç¸peXfOY.9ZöbÆe">`^öåéfæ5 b~ã Žãÿ6Òà îà;þà<á=ažæ?.^ xdÅfm>äNdo†èEÎ�F&é�ÐrÞaJNçëYgî)ß!öY›€gPFâ•eûÇì˜|Vé}Þiñðç�Žå!�åîâdùâ0Fè&ã6ãnhE攘]‰ÎI ®h‹Nf`ñ`&øgõa1èc�Ž @®æä5iCŽDYéeéçëg•é,5gˆ°iëÁiÐ骖֨ðiç ešê3"ê2ÄÂv€$í~.¦vf{mÏä�êþ`‚¶åñ5èNÖe˜_Îá5p)‡Îë þj7®Ý±ö›²ÆhfÖhζџi"ÿ‹–í¸˜˜V^B^Ếk¯ÞkFëáì!-êÁîáÂ^×�åg�]l”kl ÎÄX”úƒî&©ìË.àÄÖl+Vk,õläí°í©.èĶb™�Ž]èví®~èØnãb¶]²žcÜnf�ÔŸ‘ŠßF èn¿>Qºna”æf¤þæåçì%ç,ïJ–n˦î•–àéwÎn±‘ À‘± ïþîZ¤l ¿i7탶óÞ_ô&Òõ訮e}&ïÓ–ïÔžŽú–NÖÆï`5Úýް¦mжm¯c´Fï�Š��ŸŽánðmÖg wiæ^p.pn÷ÄðtïWòp?ÿÆñ¨(ñ§€WqJvñ~ñÌ&ˆÍðÎîÔß¶�~oÒÎdÓ&]ú¶Vûæ^"ç[6FòÙ†c/drdpÝFÑi˜tJ�r›˜ò*§Š+/îl>î”ÆkEVn.§ðŽóös 'ó&2swFó“±&dós8ç˜9WeÌVj·óónj€ÖóؽúsoP�û�ïùrBòûæü†íˆVòFÿm³þ•'·VJ¯t:1ðÏô@žkN?i»þôäæëkn îÉŽˆÊ¾ž[.siñcÅnö‚õ”u¡u·õŸn\çñŸqþÝí_ÿì’v©.vî8ö\öñA7ÔBgèÿ×uEïïÚ¦vHOklÏöi°t„Àô¼QppRãvðq‡pP_éý6wGörSTO€'r÷Ò†w0‘w*¥w²wùÃ÷ÛÐ÷ïvÎúøb�ᨰfvÛõTQƒ_íÉ®‘1\ ›ÐÚû<±áÏþLÞåÔ ©_¹å Ž ´Ð6tt ÎHÕ6S�0 mávìà?�£GÿDїͽGˆËøó#��~:^Á_p皉Pâi–£~¥úm|ÇmB _7ƒ…¢ç\£Gz›PzÝfzõtú=·*�Y”©_§ª�Ž«ŸµÅŽ­ÏU%ðz.{Aû¢Íвω³ï–´Ÿr¶×ÿª€{S‘û” ’ºWÅ»?Ѽß{oò{+ üÁ'üt7ü&!žÅo"Çwüµ™üº©ü¢/è£oi„Ð|�'nõü`âЗz‚¡z4´z„ÀzûÔz .þä…}ÙÿsÚnÛçýÜ?ðÝ Xã`ˆ„ s0lã!D'¨hQÆŒJ6réHå#È,"zð€â$Š.*WN�øÐ̘0fÒìh“‹“œ@vªèéРB‡`ô¨ƒ¤JQ2mzâ)Ô¨OP­Jô*Ö¬Z·r *ã+ئ)WªD ±aCj×2ik³I“'rŸÌ¨k·Þ®@�Mà÷ïŠÀ‚Y.¬ã0âŠÿ£�2…¬J—/aZܨä&æ�š�U,ä.~±P:/„¡¦dø)nM~¦ÊQ¸Cˆàχ Z­lå?"ňåI"Ý  0R<:TIž\Ò€IމLo�KÅ´Ó“¿üå žü¤XR ÊQ6±!·¹MR©J¦íËsJ³Áb¹–ü]²ÿ šÙ.séG %fƒÀ^ØJW¾æÆ<&2�Y0á¨&™˜4£I.r šÖ¬Ø²©Md]îh'i�·Ž ÎqV¬bkB$:Óù+E†‘àåsÄ%™I6 ’e‚‹--¤IpÒ/ŸeSFIÊà¡…Tª\e£†é¹ÓÄò³ô£™0¹“\ê’—¿ó¥d€©)aš�˜q¦3—iÕ0/šÒœf¬yM is›^êž/Îqгœ:§:sªS®°sî„'d" zÚ“ µÌ¤&û™€z2”MA)bЃ&�•í—iúдÝŸ·¤èviÑ•`Ô%MGÙèч€4™"ÿ­IgRh¢4¥*56[:nÂô›2­MkjSÍàt§†=,PzúSGÆÓl1 ªZÈdÉûHt3ûT*S¿àT�F5S=¨UÕŠUXÊR-´¤l>�Ö°Zô€e…ÈYC”Öµfî4!e‘¨âú¦¹N ®wÅ+KõÊW¼Åt 3¥é` ›Ä2w§Šm$cƒ*OIR2²’5*j‘ª¥>5ÌCãkDõY„A¡QËjiqpÚˆ¦vµbª7QðKÓÓ…æ]+o Qy«¤s­+,༶t¸½ô«qëô€3˜v+ls#œÄç¾3ºd‰¤B ‹ƒëb—½Úõ wŸúÝð…×`5¢jÿUzUØ04½ëõêDqéÎ÷–0^òÍhkFºQû®˜˜ùu+ngÔ_¹þ¥pp üRâ"Ø[ n0ÿla Syw†/K¦›áênøº³Âöɇ1“¹»#öP‰…3ÞT†ö5‘l±CM Q«VÆŒ¤qã;_è­Þòn‹<Í#˜ÀÚl­xœüä8X�U¾4¯lá,»jËõT‹e²×ZeG;d.³ˆ^Ɉ÷ÄTm³dÞŒÞ8«wΕÍåŒ7mã=÷Y¶†H Ç –׺л9t�ükRð$…Ñ ¨€ -wºsÒ”ŽòË0­íD.ºâiìk4ÿêÉ]çH¥öÉ©ÇlfU“˜Õ&&ŠaíY“–Ö/¾5XñÜÍ×>$¶µ™íC‚=lÉÛC†Föb”Mf;ÀÙÐn“´™BmFZ»ÒÙÞ6Æ­¤éoK×±â÷—ÍfM¦›ë~Óª]Òjx¿ZÅ¢-Ûtá¼U¿µ7ß­%ë7q¬5Õ à1¸Q^pÓá=`žXîì¶E;â(™¸¬Ý6!f¼êêÙx79n.�ûƒ7!5~[ò“èÇÈ\yFÞèÂÐ" YôÖªœ¹zÔSTß}½±YM×õžÿ:à�ž`†NôcýèˆK:³—~±¦;P—úÔ-mõÉëë5î‚PòñÿP‡\3bO7Ùdöc¢#j¿ÛÛ΃·»ØÖ5¯ûÍw­ó}í�ª>:SÎ\ð¢#éMQ:£™ñÆ?~Ò‘—<哯a «ñ'Yô£?FP¿ú(΢äÃ{żf_ÇôT*@*ŒlûÞr S¢ý×tÝ:ù"ƒ¥R´Ë‡‹·o¸?þ[ ÿýË'ظçå  vW  r‹³AÔ)•zd–üA€(ŸÖ óa‰ó¡€úAßôUõ¡©há)H÷µÆ÷½Hø�_©˜_� Jdà°ÈÉNÐÄŸTd$á‰ýáßýíÿí†ÿý]k à>•àœ…NÜiÌ6ÿ!ïT \  n z`�€ ZxËB@ ºÈ Ž_ùeÑùMAúe rž Â߂ɟ bΕî ¶@ÿý ¤ a`· aºÓêŠ"AZhL¡ép`R©¨ÆöõÀv¡o|áÁ(� * >ŸJFûJºhƒa€(Žb†o•*z€¬"+Ï [â¡aJ".Ò ãMhÀÏkX!qŒêœ$ö%ÖHZÐæÙkx‹û}âN„â(Šb)BÆ)¦¢*²â*�µÝ¡,áÖb„Ýb.–£•ìâ#…Fø¢dcFc�D¢1�Ÿø�¡%Šÿá ’¡Ñ4c�<#Ѐâ‚M#5^ž)Î6f£6rã¤y£΢Šcs‘£9NdÆx@é‘:Æ×—@„;bÀ("#´2Ñ# &㜤¤äbd"FÆDxË)Ä@ãf$(Xd¤FžÄAjã6޵¡# àá t—D2×QR¤Rj€\¤NâSlá¾4¢¦€¤Hã#q˜$Jª¤b°ä{œÄKÖILÖÀLþ£…Ø$N~…NŠEOú¤B>™Æ(!QYR.%^ES6U:†eTÎ^kPeŠXåUIÚcôœä¤¤¬¤>¦ã—ÀdL¾ßþÔ¤@®¥ ´eS¼eBå¤Íe?Õÿ¥- b^–&Qì¥fõ%d \Þi�`†a^åaVbbvec~åc¶dd’åd¾_Ũe?ådFº%6ú¤Ä%ƒ�&'‰æ8’¦i>' &/®fSHe`ÖÈG*ba¦ Ö#mB�b2¦cæÙn*HYRæo^fp²åpnfqÂ¥gÊ¥®Ð%Ù¥sBgiJ§j"Ju&¼fmĦHÎ&2Þ£„§WöXR' Œ¥yöf~¤ç4b¦f2g¶b|&ç|†f}Žf®à'ˆ…RÉŸü=¥J¸ =Ѭ(‹ÆHŒl§¨,Э–ñå† ·T ƒ!�^IЉJEfñ(‘"@ˆ)’ž£w”ÿ¨‰ºàk°h‹º(pÀèŒÈ(Ñhà(Õ�âIŽZÈŽöèVH�FEf%©™žé 1éS:©d@éŠJé”fŒòÍŒ‚•ñh©óáèœèè‚)Wˆé˜>E™¢)¡*VjT˜h°ikî œN• ‡•N–îž6žž"Ÿ>€Ÿ†é’ê �¡Žê¨"*T(*£Â–é<ªDDª˜Ðé•Úi–öÓ–:H—nÆ—©§îŠyˆ¨’*°ž©©>…¢’ôY'°ª ¸*³À*¥Êª¥ÒjžréžziŸ‚)SP¯jë!«·"é°ž@±®Ä±úgŠNÒ‹Êi•òÍ´«»®V‘òè¥:Ý�Æÿ+QÄ«®f+¯–‡¯Ñ·þ+t†kw­é šë¹¦ëUŠ Qº«»¶ ¾*•`¤Õk‘Þ«½î*”lë¾ú Àvl^ ìSâ&6jkœk ¬H*,2l»:l¼BlÄ®ÀÄ2¾ZlÅbl!ilÆv«Çö,EjLwÉGªö›é˜lÊ-Jøtײ¬Ë)ÌF,ŠÅvªPÔ,ÎrŒÎæ,Ïú,×â"Ð>•ÐŽ¬ªj�Ѷ[m™†Ò®,Ó^ÌÃöSÌ®BáÔbkPX­¾îlUôëÖv-ßNà× Tت²–-š\Ò>ÕÒ2lÓéÓ FÜVàÜækÝ^ìÝjmÞr+Çö­æb”@]¸¼ÿ"óÈ1OwÉÃAáåÎæ®.ëò”yx.ž€.âˆnø�îS™.³µ®îî.¦uîÄ}î†înŒ.â”®T0ï&¯òbáŽì¾ ízˆí î‚Çò^/ö6WóRËóHôžÆôŽ’üAdö–¯ù"Ñöþ@÷È÷šFøŠÒøzÇùÎ/ýÖMú¾"ÔKõ*Ew½-ùÖ/pW¤¯R寖ìoRôoÌþ¯7°÷“³;€G,?°psÒƒE7n`dð—°ùvð_|ðW„°Û.°üš0 Ó/ û… Ë s’ÿ¾p ïðG‰Æ¨.±˯±±ëî-/±R!ù,6ÚüÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹1BÚȱãFI CI2£É“(Sª\ɲ¥Ë—0cÊLè±&¤�"IŽœÉ³§ÏŸ@ƒ Jô¡M�8AêÜY´©Ó§P£J�šòhǤ’– Êµ«×¯`ê´Ê«V±hÓª]ËÖ)Ù�I϶�K·®Ý»éÝûöfÜ¥x L˜èÞÈûš\¸±ãÇ�-"žüKñ_�‘3kÞܸ&eľB‹æCº´•Ó¨år^ͺµXÏŸ÷Š]š4êÛ¸èÞíº·ïß@aÇþ5;tmÛ¸“ïæ ¼¹óçyIŸ>¹’õëb²kïý;žïàsˆÿ?>Œy/Ël…ξ½{‚Ó©#¾Ž]{öîÞÁ'Ïß|ôË­÷Þ€úŸtÕÑW‰}÷áׇ~ûñWÞyé Xà…Fv /“ãᇠŠáàƒJ8áf¨âŠ„mxË‹0~øa.4ÖHË�8æx£‰âùàn²(ä�j¹ã‹2zX£�:6Éc>¦Hä”TJ5™‘G&YÌ’46Ù¤&`Je€U–iæPWx$’Ir™‹—:‚©‰˜’yæ�xÆ”f|kÞ¢¥›pæ('�(ڙ硈ž4Yˆ}þÉe 8Ú_�@&jé¥m¸(ƒ�¶ù(¤´HJÞ˜•bjê©ð¸©}�Ê(¨¢žÿø£nA¢j+¢šêÅÉ®tôú¡3ʬ+®Lbì$$«,#Ì6ɳО"í´¦TkíØf«Ú­Ü–™ë/»rÒ+¿ ;l±Ç*»l³ÌBí´ÒZ{m¶ØnÛí½C~î¸åšKì±Èª;»íº ¼ñÊk ½õ2†ïÃ,êË«¯ë/ºÆ <0ÁŒ°Â 3l/Ä$¯¸×¾c±°ÿ¦+0ÁŒtŒð) ûçßÈ%ç\àÉ“[±¹Ê´œñË<3¼ÕÚlÎ:7ÝÞd㎻ò¹kÜì´³d­õÑÔš¢t „]’Ód¿uÔtL4Æ«{µ´ZoÍ5Í^+vc—­÷sgGÿ­¶Ðm¯ËÖqÏ2sÍv‹ÍÔÞŒÿÖ·Ô@n5³„Ç}¸Â_ß�wKÃéÕøçh"†vÚ‘³=ùàp¾Éê¬#n³æ‹+Úùì‚nûJ�÷ú·éD£~Já³°Þ:æ‰ã»I³Ó~àíÕ„•ÞÓÙ"ýô#º™ÇõØËŒp,Üw¿Ê÷àýuz0¤ÊùèO6ýô V²¾ôí·ÿ¾-µ3Ï�óIA/ÝüÕs‰}öFÛ^÷¸¾ð)�|A_ú3?ù½/~ š_ýì§üáD¼àŸƒ¬÷¿±^RÜV éÕÅuÕ®º <ã/Ç FlHt;Ý*~*GVZ=…›”ù•˜ÿ nMîÛNÑŠ:ƒØA"†òJ‡i�É$§Êæº2€_ܬoöˆNt�ý£­)MÆÁ1¯™—Ô¤4ÛlÍXmóûÞçƒuÎunÅ�ñ“g½™Ïñ3n�äø8ËX�­è3º^ŽNŒ˜ABæÊúøUh²šéÉfœ¸¹Ä�Vò§)'­P�:?úÑ3K Ùg ®Ú´@S-–¦eeÍšÖ�X´ym¶ä¦&oNޤ%|fYÚ?˜ž¬¦×Çél{Ú ¶3/�mS—x˜ýErÜšlW›Ü�èv²¾Mkq‡�ÜÍ øìŽÃ‡tãfÏ8u�ína_šØ‡B©t7�l{+ßÌÿ¦³¾{ÀoðH;¡?Pq|1p  ãæ8×6€®ð0¼ÖÞ½5aŸ#ñÎQÜâ·É¸ÆÝî½Û<ñÆ“ÈQLò•&;¬ùõ¾ñüdï™”šyÍÍ…óœ×õçˆî9ÚÃmëqãÚ5EùúB”ިΘâZòPŽò °P‡:€ïÞÝ`‡™¹Ô$î{Ù�eŒ=¿÷Í\B0bÒf;Ö$7YžK3|÷ÏÌìôRXzÝaÇ€<„ï0px×)ŸŠî©Q°Ïgk?å÷ѽ„«wñ]]c½ëIÉ´×x„ö¿Pü[†Ëy[<ž?‘ï-6«±Ê_þú™o}÷(>=í|>X¡§£ÿÁH_8Ówõª>÷^ûÞ ~·¯»îùÃûbì]`Á×|,†Yü°þ§Ã¡|dÁ|œ÷|ä}o2}aU}:r}Øw`ú Ü×ybð}o5W¢7~ä§5æ÷?è÷,Ó¢~û—F°§²ÇÈ×'ñ—^óGõwÀg0"ÈùµÿÊ‹Í7=8x#Ô'0;ä€43�˜NÈK ‡�âç.¨59Iø‚Ò2ƒ$Ø~p€{1"*È Žå&-8/è{Wè.ZHHý7(x ;=(=Zy/"y H„ä&§Ó,I¨}ܳ„Þç„à…W¤�qCVUØNiÿ‚úÇ~&è~^¨`¸&+Udx`»7U½w#¿§,ù'ˆ4Xxmñ†Ò9hØxw}y(}C¨.EÈ%È,�8@„èy†x�r•�RX8Œ(GKò�³z‘¸…“¨{2£s‰G"nµ‰¯Õ‰Rõ‰´ŠÉ2ŠÃGH„—�v|2:d%!o†HTÔZ2�Ÿ2‹Ê²Cs‹Œ�‹ÛwÒhse7 Ø“h3#<«3Œ“f…1xŒkX‚'Í(Ïè }Bp@C�~e�Q…�Ú˜z2˜ŒÞ¨8µÅáØÉAŽþdŽoVb­8"ëø�í¸‡´ØAñØ;€nJh� âVù¨�×Ã�ÿã�›�ìVŒ�˜…i�›‘�¼°�øÑ�),ÙW U™†Ð²†jô�hÑ‘ñ‘hSŽü1’$9oÔã 'i.¯âŽÉ�-)8/Ik1Y÷Hvù¸�ˆÖ�þÈ“Üá&Ɖ¤¨ŒùDi”Ý�”I© nÒ1MYO9�Q‰‘S©‘à¨k‰ ¹M"É• "éÈa©”) Vc–g¹1ìB�ƒ(“öA“oy“q™“sÙdÄ(�¢ˆ…Ș—‡ ”�pç—ܘI9˜S˜‡ùšj¨˜iD•Ù9J‡qX5ZI”©P!òg`™$ìHi È™|ø?Ÿ™,H“‚(�¤©¦Yvpÿùr)¥Rj�ÂÒ$;ô¢J06jSss4Z"êè!©uo°©r~÷5ÉaQUN ŠØ3yÇÈ:”F’•$šR¶`¢k‚¢-V`~:‹Ð£ôç”JB£ƒ£~·£àÓ£@ÿ¤1¤»–H)AN™XJJ#Lê¤M ¥R¥T,VÚAXú™0³¥ñÔ¥Õ=`Š™b:WÉU¦9Ú hŠj:.lÚ¤nz=p:-r >t\kq§F*=zz$| Wš¬&£ˆ&[2Z¨54À—£Šú=Œ ¤B ©ãuA“Ч•z©¹�©šÊ©�ú©Êªÿ3ªgYª[Šª^B«Ú2¦'«9:«·Q«½r«µ�«y°«ÒÒ«ßó«ìÅÂJuë3:n¢W†–¬g¨Í[Ϻ%†ŠÔ* <ê£Øú¨ÚªcRÔ­ÃÊ„Úá&à*®Oš$�ꩃj© ª#W `Ù šÍ«îšªÜÿ¯óêªdzŒfj_Ó¨?ª¯tÀ¯þ °§ °«@°Ød°|„!â(K°²¦¬ËÚ’Ëv²0±Ït¨›±�š­û<1;#âJ2µ$àÚ™D®Sº²Uê²¢ ³Ù‰p4‹ª@¤E¦Å@¯ae¯gª4@;BK´Ùø¦}§«3§‡P§hq°zñ´žµsÕ°ú°Ï"¨.H¨­¨—z]»¨û£`«­b+�S¶fûJ\’¶×‰=l«²™Ë²ç ·é*·ŸI·9ê®wBy˪{«³õʳ±ú³@;¸PÕ¦…««‡Ë«‰ë«‹ ¬jḿ¹®’žuE¹~³×=f¨¹[k±‰ÿб Û¨V ©¥+!A¶’ºª‹¶@³ž©,0¿m»Q…®†›½-‰»~73@´»Ô»òڪɀ#æ·ÝC¼�j¼€¼µ V°‰´iXK¬M{Ô;£Åx½S«¬Ú nÜ+ ­.3­áëµ@Z¾Cz¾‘¾§»¾©kEØ¿ª.ó{õÛ½R…¿Ê«¿ñÈ¿¡vIÿ >x{œzW `Ì= ¤ ìÀùkܼ{ÜSs!½ ­ÏTÂÞFµLk!œ#¼¹^¼�Ÿk­¡;*<‡’:.<¨k¶2|=4Œ�sÃ9,ÂSÅÃÿZ¹û n±*ÄC¼ E¬tG WIÿl´fšÀ€[¼•°¦Ç‹«ÉûÇŒ¸› ¸W¼—�y3·Å›ÛÅÒúÅ<· Ì=:¬Ágì¹'<¾)Œá.JWqÌO׆ì[Ç�ñ›,z »:|¿:‚p÷ ÄuFÈC\Uœ³,„J,¼ËÌ=�X�ûÄ”üÀRŒÉš X¬“ñÉ µ¢Ü¹T[µ·{ʱ�Ê$<ÊhÜÊjL¾°Ëœ0Ë ÅwË•ËݱËs„ÇŸùËÌ)¥Ž¥“Æ nȬ.ÊÜ Ìü¿Îlľ‹ÄÒÌÈAlÍ×ìÙɶ:ÉýZÉF+ÁV ÎXÜã\ l—¼e`lÊbŒÊ|l˜ïÿܹˆjÕº ×ú£“aÏ÷| ù|œû ªvs|¶5BÐj+ÐòK¿�ÐS¥Ð �h ­,Ñ@4ш\ÑŠ|ÑË;- ÍÑ�,É ¼ÍQ<ř켛L ¤ �ȹ«<3¥ÇÐ3ó�½$!šÚ¤Ã•ûÉz€×KÚÑ>#R2âX„Bx›#í ,W7|Ãl0³£ÈzDu /MR`¦*‚_Ó£¤]Ú¤]D†Ýš4¢1‰j¬ã¦ý±!£Ó×µÀÚà¶:ÞÛn�DÖת¥1t]~v½Yxm0zÍK|Ý×­Ÿ‘ ؃ÍK… ׂآؓ6ÙØðØÇÿÙÉ0Ùó[ÙîrÙÙ™Ù€·Ù#ÔÙÓòÙÚú7Ú¦­¨MݹÚÉŒh®½:°mÚ³=ŽhcÛ¸Mkº-[¼=oMÀÝÒÊ2ÜqsÌw]4î’Ü=°ÜšÚÜÀ™˜‚MØÙ‘Úèu�I‚Ý£bŒ}<Ý­ �mes%Þ@ÞW›h˜}‘‚­ÞÄÞÒâޛ߂(ߥMß(äá=Y#¾ß›ÐߥýßñQÛ}=à‰Và±uàb±!ós¢sÅÒ<Î�Å�u#—’ɶ�áÛ(ƒÛ” .Z2"M¢%"~"% B ª ÆâÀÝ©`ÞŸ qóÜ” 4>±ªæ:Ú[*ÚJÿ£>®@@^—¶˜ß�@ä°½²]´àKéM¾ »M/•å2å{ŠˆØ£ZXŽ0@4"3^¾×`ÎÜ€ýÜe~æZ¢WkâSµØÛ=q~s^çâ}çЭçÛçÝ èüQÈàCè9bè6Šè6£èKQß ®Ú¹0äuöÚæñ”ŽäΈéšÊäˆæä²ðžžRþ>Tþ‹çWW§/©î «Þåªùå9ð!NVb>äy Q9ëÒ�µ>W·žØ¹žÝoÞëÖñëfç…ƒçÄnµÆþç�>Ä̾Èa•hðíÒ®èÓ�>V@¾î!Ýq,B>æ‘ÐÚÙÎßÛÞí±! Å/ÿâ¤g‰pänîÙòéa‘îÄuëW§g,‰öî²ïø1ïìÒêÊ-øÞ¤ú.0¿3 ÿÞKfîO/WÝ?âѾq~dÇ…sÀ~ˆç3†Ùß=ÈNÊþ=#bVý¾ññ½4¿ò èýâëÁRò×sò™òú½òEÞò»ñé0ŸP2_ 4Ÿ,%lóœnàçŽ<�?WA? C_8ÓRô#4"3fãG»“®~ï3ïô`µïQ?õ¼TõÛtõÝì¶C„r3^?Öö,q¿Y7\öÐ=cnu¨iÏ=©ð5m¿ oO ¿?÷“Äñw¯y¿÷}¿ðÏД‚ÿµ’Žøº¡øó)óøù¹=ùO^ù )–ùɰù�o9Òú$úFúnáN à ÉàÁT ö`ذØCˆÉ$N¤UÑ¢ Œólä˜ÃãÇ0!E Yò×I”•T’a ¢2˜ÃdfÌxÀæ,œ9s*TÂçO˜A•$x!ÏT"E®bÚÔ)Ó>Q¥Z´(sXFGYµ*ŒÕUiÈ’aŪ"[VåÙJR¥æbÛ–èÀGq[ÍÝTWä¼yìåËËï_:�×"\xÒa‚q?ª+˱¬¼zùN¦\ÙòeÌ™5ïýû×Ög+¡o�&=q"Gއ')Ö‰óÔëÇOW©�úóçÿ\Ü­^ï>U·a�� HÔ¨A¤©~3tùдDªibD½Q«Ö¯amçŽ2åʖ̓Z�nÂæ�Ö:“Ûö)¦jÕÇ#%Ï.[6í>¤I“Çx=+W¯¾kÀÊ2 ­´hkË­·í®MîŠì�Ê:óK°Á†«E5‚ñðÃÆ›�ÂÍJ4ñDÍ,äå3[B³B¿ÑžK¦ºÉm[ &´¼„ƒdX‡ûÀá‰'®ØKŒ5^�n‚P~7�Ýy:’Mî8+ÅTnˆe—?ƒY ™a¢¹:›Ĺ«�yöÈçd€~Kè݈6éxyaÚé[ ~k긪÷j8³.qí®uþº€°Ù»n³éB{;µÙnÛm¸É�›-Ì²Û ¼5ÑÛ#¾ûü}Ëÿ…pÃDü8…o¼oÈ#·or–Tnc£sÄDzÃ�_¢#ŠæLÇÔùâe1‹ÊÌU³ãÜlvµÓYÏœóÿ3™-CÛÄÊ€´ oxÁyZ[¢†¼G(/@aÀšÖ¸ö¯�í!bÛÙ²×®í¢{l#\øÆ—‹ò à|‘Hßúrо~ÁOŠ|‘ýõ9š$Ž7ú–ãúç¿§ðb`I'—¹tN(¡S ¥˜¹3>â�E IË$¨: öÁ‚ ¢‘Â4ˆ3òÁƒPaÔÀ;!•ðt'e–V‰¦±°x.<ž‡¨v «…¤†Ï»¡-rH½Z¯‡Ø3ÈÙ‚“6•xï{3b ‘H6ŒÜ-o]ÙÛv7Å)VÑmõkËýŒ’?†í¯_ f1Á(›@YL€—# k‘&6Ò$š9YçÁ ÿ²®‚®»`uü(» rp�Ñ�qFØ;EB�‘GS!$‰g<¢ÀP†á¢aól¸ÊOV/×#HÙJ©½Sr/•Þ+"ÜŽ˜Ä%6‘–ì³¥ûp ?]Œ—lñåA€y)anª˜Æ<¦S’I922ÓŒDc+Ô”ib$¥&¨&Iå¸lâQ›zä&½¤?æLœ·û`îB¸»s&Ò„(lg$?âÊ\¼Ð’ÉÃäò4iONâSz:´Ü>GÙÏn"ˆC„ø êJ„Æ}³ŒE-qˇLk-ÖêV‡@«æ¡<éYÜc¼p×9n£Äì¨G¤Ì�Î�€Z©|VºÒ––¦ul™[a&­5qäÿ’¼‘ �=Aò”�>MÒ‡Ù›tÒ‘¨ŽüË �:I¶(•—Ìd=«à¼ÍtÕ“SeUùi¾¬nu Dô*²ª*غ‰•‰d5+Öü–Ö­Umu,\92×ÖÔÕ1wõB^û¶×€» ``É7جV5$S˜ÂÞ8.6 vt¬ É2•²O±ì0;ÎBŠ�„CmädiT� Uµ¬uªka«Ùæ3”qõá?�P!îV¶,ò’>�ÛOá*´¬ =„qŒ\)—¹nuîF «éÊ‚ºÖæ^µ»WîŽñ·¯)a54-ò–—7ç@zM¸ÞÆ6×=ÓŠo ƒTYËÞW³äÿü©9÷»ÈÑú·´î”$<;´T#·v“±í¤‚m{UÜ:X«æj')žÓÃþ®úúÄíxÄŸñ–Ú[b¹N‡®Ò]±XôºWÇÕw»錓h%ñ&Ç:~ �}¼H ûâÎCŽìF&»$£PÉ9À]9•ôduF¹/Sp\ÉÕ2UËPå²Tù0=}ÞV‰¹%³„·¾ /øÂæË0q9,ç9wªÎÞ™´Px˜gšì¹®}ËŸ7hË-€54x‘èI,šÑBàv·›2õ²WÈB!²¥å‹iú&‡\r~� jÑöwÔ~1m€Q›TTx†[Fp—ik0ÏZ̺­Dÿ q�æt…•Í.nóŽì %ÅÞãsõ]>ãÕÏ×tß cBw·Ú5ï�פmwÛÛÍ÷�ÅMbJÃ×ÜFž¯Sê»éN7ùÓèä/;IKo*ŸÖÊ÷Ju– ÌïÌ$øß –5›MiÖ³üàþnpîk8wØá†øeBšÐH…ê¹ðånrb ´g‡ºÌ.‰§TT§Ê�o¡ÊO�v¼›‚V_ÊÈ�·~ïT½\ÔSè‰;H‹$þ²ÈcÄ‘IFGB§ˆ„ñ”a+J87Œ …°4ÁduÄ”»&@,›y<ä§7½gÄ^ö†ºr¾ T—×mð¯—Q#|ÿÿ{Ú³ü‹k ÛIÒõàùETa�ÊØËþš³§]\ã @Zÿ÷¡Ó¾îøRXÞÑ>ø¾·1Õ€|‘`­k{9y7ŠßãÃâx¿@~’Çå‡ay3bžb¿Kç—ëyÐÃÑ#=Ó[•âóÕ Ö‹?×Ë=Ù›½à«”Û˽ؽéé½ßó½à)Å >ÔÓ8D>)ëŒå³±Ó5Šš‹‚>œÀ;>¡¾ê{¨ëc!¹ÛÀ�Ø>Jé>ï¿ ð»¥"?Ø= K¿�{ ö;÷+ øãù£?ûÃ?8Ò?¦Ð¼£‰A¾è¼“ø<À@«+@YpŠÔ[½aÀE ÀŒ½ ”@¡@ üÿ Ì@D¯8òÀU0>+Aøºa¾>p>D¤è3…¤>ë#5ì£$ÄÁÑÁ¼ãA˜ðÁñ{�À Bó#¼¹1¼Ï:Â$$‰%lÂ�˜<° (”C)\*ì¿ÉÀÂ_ÐB�âÂ5óB0D@1ÌŒÖ+C<Ã4ô�Ûýܣ•tyCà‹CÍ¡C;ÄÃyó °3ÁæCA²ûà ÄA—BºR»7|KÄêXŒs{ ïÓ»J ?iú;I,¿à8¿ß"B\á M¬Â÷«E' ÅÊ»C¡m¤¹ÝèFGTH”¯IBôÃDÄ[ǤiG2|G$‰Çü›Çý['{ÄÇÜG%ÂX<Àl»1dÂ|½3|†\d„„̽…\�†l„8ì1ˆ¼‰|;cÌC qy’c+FtÁz„Áiž  °ÄFÔ(IU‘…n´�à» ¸•ÇShÉJ¬­ÂÓ¯õû–®Xž¤H›Á£ZË $Im|˸d·ÿ¹,Ñ“Ž»üÁq¤Är´Dò�IuÌXÌ™$Ìš4Ì'TLÐbÌÍKÅÿËŸ¬KôG¬LÜ´ŒZÔÌ[äLt$ ÍÐÌ…Ñ´‰Òl„’ü6š;=êZÍ­T‘×´‚ØŒ+± ’nUS?…=@]O‚hO}Oÿh ’’œÖ8R€,ÒF…8U< ?u’ CR˜„`Ì8ÙSc\QNà„&I—ªü¬“´M‘X+‰z”#)�% VÅPK„�Žù£¦À®xyYN@Bi)Üh’¦ØD’x¤ðIC‘§»Ã»¬ÌTË® Ÿ&1T’©J�½ŽôHZy…‘ ‘(&Ö Y•Ù’U–“ ’”ÝÉ•eÍT|L˜]™�CšµT'U œ-�Õž.Ÿ ÓátU¡m ¢e £ý9¤UÚaÚ¹pZ¦€Ú�Z¸¡Ú|cª¼ËZ†Å ®¯]°Å±Å+)[¤8ÛIÛ0 ¶ÝJ·­¸u“5”M•…ÿ–ÅC—ÝÛßè[üÛ« Ü›•„œÅ��=ÜúY1 Ú@u„Ç]…ÈÁÉU�¥% ¦]ާÕ×Í�²©u�ªÅ2À5Ñ×Í(ÝÓý�Ô¥”Õ¥”Öm ³-´=²Ù ƒÚmÙÙd-’Õ]¹å]ºõ]»^¼½B½�Ùî=^Ä«Yå ‰ÁýŒyy^ž�^ÅÓÆÍœëÍÞyÛÞAy`8²ÞËßÌ_εÏ�'ôM^õ%Òmß®…›¯�ϰ�C’y×å ØÍ ÙeÌþÞÿ}ÛàÝ}‹ÞýÝ*^^®\¿�`ÀÍŽ .œÂŽÃuº¹�ÞÅ­žF¯Þ«£}YÊe�‘úÞÿßßé,‰ö’®½K ]ÖÚÊ(ÝújZÉaÜáéa… Ùâ�â'.bÜ=â¸UOÃÞ©Û)|ª&^ཀâåÀŒ)”)./²\æ%,°Ÿ,r0/æàêã�*㤥�×Óä4>á5Ná6ŽÚ)›62x=.­¢›c¬­ãѽ <¶,=.>nÊáaû}Ý"dýbbj[D^�`«('ù8'H^lQ`J^´`Lƶ   ZÁôµY þd+åZ åžíâÀÙéeÜêý¡Ù‰Îí0äÖDZ´ˆŠWî^+QcÙPƒvã[î’\žž]~Q«¥ãŽ]»ËD‘ÿ<^ZÙÅMÈ_F;eÖ‰ì侂ܽ æ´º]j®fg¸æ&Ëf3uŠnžäonàKÆdX!t†a´3h�V„+ÎYw†gÄ•gåZ{FGGÀçÙáŽb*–¿a©è–Ò ‚~ �Fh Ãe]>X‹èeÐýåŽ�a©è߸è]ÔhFË© �i>dï`1@é”Vi%¡âm~i'F>K.^>çÏêÆ�6è+¾`Ã…^SÞ`ê5j¤Æ¥&&¦ö §Ž ã-a©–å‚>h[ºòŠó-ºô]߉>±&’"Áh³Ö1´¦'µnæ�Æ^2¶Ýi†¹Vé$¹é–n ¼¦ä{”i¾–bÿÚà ƻÀæivÆbç-ì >ì¡®g0¾gËçÆN€Çæ…ÈîƒÉ–Ãë˜j§¨êÌFËÍŠÎöe´í¼¾ŒÑž•Ò.ëØÝhާÖZíࣵK½×öß·6â¸FiÚ®ë%Æín.o�å톸îtE<ÀìÁÎâÂØb ^î/¥0î±ÅöÐ}vì-ij3æ^ߦì¬Ðî¦àîñÕìÎ5ßÏ52ˆ.ÆN©¯þ$ëÛ;íòJmµ›oùžï¶ÖëØÎïjÞoGîo¦Èí˜ö<âð¾.ppõ¾áNðãÖbÃŽ„ÄupTVìçNê —î ‡ì á ÇîÊn…†¸lE°jïqÎ.ñÏfö kÿËZñônñõÞhÿŠùö‚_»/iåÂÂÕùˆhØó P�Ý"†Y[bë)URU*”p d2CÚrÜÈs¿ •#á'jµP—ŠÂ@Øà;5nˆ@êÏy�+4^3Yr³XpŠíðï ”3®iGÆ�ÅôxŸ‘ì¨�ý] ÿ‘ôÀÆ®ìà‡òß;Ÿ8˜Ñs>�Ãøó·| [C÷D÷E? FÏ=G·ÜÜö/ ±t Áô�MNZátÂðtÚuYu"õG1uYÊ«SuV?WgX×ðSŸõ¹¨uÚ�fÀÉõ Ùõ¯PÛƒ÷´š ìrB—æc?‰ÿ<÷ˆ=�†>oöé¸(hø[×Ô?9t Iô?YôÐhtw‹ånÿŠIïîJ/’K¿ªL÷bt¯u7vçòåõ×,uÏò„"«{Ï÷µÙw,ï÷ÃcòtŽÇu±Ðuƒ÷uÆ„ú‰Yx¾hø¾yxØŽø_˜ø¨ø‹ŸgÕ�ç_�ÿ›ig›jg›kÿ…l罓/áWñv¥±qrw)y-’™¯ù·¸ù&Ñy¯äycóù^³÷¦hõW?~Ÿ÷x²ïø¿�Áxz©�d¥#ª¿ ‡·ãCÖz®÷zfûŒW¥|iÿxjykyl/ym{ìŽ{•Çì°w—w˜/wM?÷ÿ¨èô8ôûœ÷×L—8¾Ÿ7|¦@|}Wü¢g|s|~v;¤ü�@øË ÇÉ|ËØ|’&bÏOvŠ_v5Áx&%ýK‰v�7�ï ‘7’·“ç,n�ôÙÿöÚ§ûÛ·ûÜÇ{sˆö)Xë ­ 2pàa«ˆ=&Räcñ¢•Œsqì¨ì#Ȇ"˜(餦”±V®j¹êÐ!/�fάdófÁœ}:vy2RÄV²† c4RJ—2mêti€¨R§F5jõªU—.±†ÑÚRذbÁ>m:VÕeײmËVܸbæÒ�f÷zKò5qê/`¢D‘NàÖ­ªÄŠiÿÒäåø1㙊kÔXà2æaš7‹ ”«¢Ð¢¥Æ}üxàÀƒªk‰täúl²g£&háH†w Xñ¢ÅÕyr2÷B¾?SjZK+L™ŒoâÔ¹“xgÏBË*œô0x¥iÓrõºŠ«÷gϺ=›6<üøqåÒ�{¯Þ¼}KÌ=}|OÙ2 �‘AB‚ *ˆ u6U–f™m¦Yvž�&Zh¤Áešcµå k ¹æl�ÌF[m9©–rñÖ›o=83#� —Ë‹´¨�r(©Ä’KÑEÖ`%Ö]ÇS…Aq×�wº5”R­7VzSŠÕÞXï9¹eYóÁUŸ}÷E“ÿŸ~ûõ÷×’r©�F¶ œdù ^6!… i×Ê…j( ‡¼xbk¯Åv¢ªˆ[‹9Æ(#�3ÚH\Ž;’d’�ÍÙ’�Ó5hä�IF”f“k>e”V†U¥ª`)––¦Êç¥/µÚ ¦bŽIf‰%:çœÁ «&|¿{l›ƹl‚s>x#žÃüôÓž}ŽU\tÞ²-·dNR(‰‡ž¨èmµ°ˆ\ŽÆ}©¤ÂÝXéŽ=FœsÐÅ™‡¡6Ô+l{þñ/ÀÄÊ ªãµ*«ª¾V¬ƒç¥$¶Þ ¦®Þòûȯ+ ;l©lM–رÈ&Ë,³ÎV-žÓžT-Vfˆÿ-\Úr»­·à–ˆh¢)–{nnéªË®3“òo‹òÒ»éK÷2–/vûòë/Àÿ ìpÁ·š°• ƒÕ°ÃnA,q­¸VÌ+¿Dzq°S?õ±*!›¬-$/kòFÄE«2PÚYûrÙ>83ÍdÚ,.Ѝ-jîŽ>´Ð�œÑ?>¤Ò41�¤Ó½BµÚ²V�ÖÁXO©5ZTuÛpƒÚ4CŒ¸¾çVF‰` pӉ;ïg‘e—åÞ-Å/4∀m²|Ÿk|„å1}C}•˜ ö’ÛG#Ý{/Ò~á›àíôåçá:úŒœ¹þ)9âÍòU£È?ÿ"õäï9^¼ÿ<ÿ›Àôÿ!¤rº°€L]²V‡¹Ö½N;± ÃìâS»dÝ.w¸ã]ï´‡è �#Å;ò\£<æµ,4Î3ô0#=ê1Äz°Á^*4h¸‚xï{Õ__Èg¾ó¥O}ìë�ûT?«Ì�~öþv§?~õoy„‰ (Å)R1S�uôÅ@FÀ®%V‰ |&ئ Zƒ»“á@8ˆ;âO!!tÄ7Ѽ²<BvZanX’ëe�9ÈI »>òE‡æë¡ø— NkˆF)¢üê·ˆû­$/Ú_ŸÀ¨T±“ž¬"Û¤Àž4}]<�ìL(AÙîA¼ ý˜5â�ÿ� açø”:ÖéŽ)ŸMÀÇú��$!ÇG¦ò0}Š #©¥7¬@r’¤d,,ÉLöO“Qü$8Ã9°Ph”‰)èÅT*‚v¬¤àƒ>øA3C–´´åñpùþéÒ)¼´SðÌaÊÒ˜5D&! Y¾=­ïQMÜ aèÈ0TóšH¬äî"Š=nòÏ›œ'HCrÈœ¹@g=ó@0†GŒ¢“<‹GO{Ú±ÌÅó‰¼\–°�tDaMUøK&‡/-& �L*tz =“C›¨ÑTL´¢GÌA‹1UŽ:ñ‰ß)XÃêÅèw|ÈIGjæFלÒ%.ÿó)[à(ÀÝB]ʈ)-ÞÈ?T‹:�#?�²�Á®å1tÂŒjÚ‹ÉÒC�lB™J¦õíÉlQíßT5™žù]ÄCf›ª)B+Ú‡²G¬¦=­RÈ: ³¢•#jÀˆÚÚ’·ºE®¢«]ñª×åñÕ— üë>›h•Án °Ž9ìe;Ô<.–_�­ÍC#+>oQV;–�ÑC3ûÄÍBÒ³­hCKÚ± ¶¼aU­-X[�´ n­Ž�í*hÛÛš·êÒm÷ªÁ¾²¸§xèp [Ã>±ÃYnõûÜ�Dw©Ó�ì™*›±ËòO»än½û+ð†w¼W2/ˆÅ‰^õéµ±U§ÿVäË·ýn¸²¯qð‹<ýj�¿¿u/`Iâ—È-€rsÌæöjÁ nâÅ’Y’Y0¹ÉÕõÌu}“]�jÖ;ÕÔ°s8,Ú*p¹Ë¥ 1˜;9âßµ6&f+ŠÝê2±ØÅ`‚1Hd<"{ÈÆ¤dHò‚Û¿wÀÇ-pr,d¢òHÁF~èÅÖ×äE3úÉA‰2E¦Ñ*æÊµù¬FÃÚ.{™¼aþôÇ œ2Ÿù½ižíš#Óæd½p¹�én7ÑÛèõÇzìŽüWÆÀµPlr ½`DóKÑŒ>¶£#é‰H†”&Œ¥QƒéˆjÚœæò—A­í>F’’¤k´�ÿY¢GÑ¡Üæ†‹‰d¤d°»Ý7B$ÞÖg“úDeÕöèT–š\äQx…·Ê`讘ÛÜZRµŠpMs…+š4�yÐæ…'EEX¿¸K$¾í�W±ÛÞ^¸ñ$nØ�»àt@·ÛÔm�v»›8Ÿ–¼½Bï†àíÞ^5�Rö=“~Çèß=Ä›ÀWBp“œ; oâÂÃÛp¬<ã-Ñx[¤bq§Cê¿:=îí�Ohä�(yÁQ2•ë„åì~÷ÏUs­Ìœ!5×4¾¿©sHðÜ7>Oб7p¬˜œEÌÑû—tÑ.ý*MwºÕ×"õ`Q½êhÃ:äO§õo.ÜzwŒúŽEÿ�Àù#fOJÓwìjÏ;‹µÀÛÃ÷�`îu§ÈÝÑ·¾ Çbèÿ;QÏ¿Á‡–+i9¼K² žÅ{¡ñÂ�<ò6ùúq�3—'yæMn$#u^Ÿ=úF¯éÒëį I½hW¯–œÃ…ßñwL9{½ �ïD¯ ïM¡p£k:=U;X€ˆѹ*ùþW¾c|ÈUžÈ=ß×E_ÁMŸuTßõ•Ri_x]„K´ÝB<Â_üDµUAhüO¬¸Þùõ\úõÐú¥‚sh "XEßáÞPèÞòÄŸý þŇþQ‰wßÿÝ “`óåI íØ™›rž«©K»éE蕊–¶*ÿÄ)0jš" âSúÉ“ú� í)RXÅY¨ ,°à&¸ wÜ_«äUì_ z¾a~܃tåHßaN0 »¡22Zµ-á*4á<á,DaxMáTa¾5Æœ<Ô:‡&Ò`aÄßü ƵUÁ ¢J Âè`"aØ ž"[è v�ƒÙ¡ôáaèa2ðáýᢑžÌ™Þ�¡ž½ÁÝÍ5âFÆ£DbMbû]f"ýuÒqG'~bª¤¡ ®!)"…)¢"6¶'l#7T¾ˆ„£8Âb,¡qa^!l$ah™‡¾àU¼�‰ø9…�ÿ 1ö�1ÖV$cz.É3ž! J£(R£Xð_6.dxpc7ÚÉ3D¤D†OŽˆã8¢,ÒâB �-6.jÅ;¾’<ª=>Qâ)Å=6H>òÏ>r…?þ£zTã?da ¡ÂLãT¼dL~CöäZ8ä6”DNä~T¤E 9fd:öaG2ÙGºDHZÐHÂ\IÐI@JRÇJ.OKö£LòLM†Mf NJ‰L^£O®%VîÜïôÝc1“HàÕ�|Þç…"Ùâú˜‚WXE—áã‚I¢�É&ô%;õ_x y”‡WD�Ôœ%”°¥dNæR˜pÀe ÉåŽÔ¥]²^ö�^žÿ _j…_r`*ˆ`a&…b‚‡b²fV4¦cÆA#eæædZæE`f if‹pfg²Ûg¦OhöÇh>Ð_ªd`ZÇ`öGa’æaÆGlJçU˜‡cþ�m†×è¦w2$oZ„ozp"‡p¶›tåå:2Ù^²f—¥œ¤f¯¬Ot®”kBf,&V`gmâçwþgO†'Œg÷”§¥è¥ô…z>‚“‰¦{r|6§N˜ }²¦h¼æa¤…~^'mr€~(ˆ:¢[^¦ÉÅå!(Š&(_,hƒ"çƒVA„¢¦uPèjZç…âç†Î¦Vdçv†¨�þ¨R ‚�\mhŠBÎ~ ²9ÿ¨u¾gÁ �B§…Þçm~•R0æŽö'�niˆ é )j„€˜Žé‘hqf_£1©rBè“ÎhƘG}®Sk*†RnŠU€%—î)€z)˜Ę’i™ÆK’>`šºh“²)ª@é›zEœ¢ÒœÖiÔY!ÁL…žò)¦æ¦Ÿ–›‡ª˜¾Ñ :˜±-Z{&*ŒL'š œN)�úgS¤Å¥fª¬®å¦ú]mxj€j¨.Ä<öDZ™MrÊ©“¢Jª6ªV<êQ)wR*žZj&ä¬FkOÖj§zª®î*/R¥¯2°¾hÕ믬ª�*ëð1+Àê³®Š´®+6¦œp…-ÏżÑÅÿÛ±M•Ã=QX„Gzh’&egw²«ÀìZœ¼b’ñ ½ò‹½2¾2�¾’…Ãü«c,Á^ìÅ,VÄë&ÌkÕkÃ6ÙÃ^ÄJê–PlÔX,Æ®ìºjìUpìÅlÆ,“å¨QhÒ¾RMÁ°,Ïö¬ËZÌò‹Ìöʱ5žKŽŽÎ¢JÏ.-Æþ¬Qm¯ mS΂ÑzåztMÕ0­Ö ¬Ó†Çr…Ô†ªR]iV�ZnIÖn­ÚÎêÁ|-VL•yŒ­Ó•íÙ:IÚ®-ÞîiÛ"ìž½­FÅ­±bݺ!ÖîlÞ.�ÌYq�íßz…Ü ®QtO®Ò".您âŽã–ãFÿà†+ÙN.¶nÒFIæ¦în®Xtî|. …n½ŒnPnΞÎݪ®îJkzH\Õ^í^›Êî.ñïZø.í^bå6«•¯ó>/S ïÜZííVjóB/öï(ªÊöVoö~/ø2oTL÷Jløžoö–ïz¨/ú¶/ôª¯{ ¤÷º/ý¦.üf‰üšoýî/æÞ/¬ä¯Éò¯3­ÿ2 0¯moÍ'°/í—NNšîW°_0g°o0w°0‡°�0 —° Ÿ0 §° ¯0 ·° ¿0 ǰ Ï0 ×° ß0ç°ï0÷°ÿ0±1±1'i±/17±?1G±O1W±_1g±o1w±1‡±�1—±Ÿ1{§H¤ñ¯17±¿ñDZ'1×ñß1±ïñ÷±1 ò2!÷°!ò'²"çp@!ù,6àÌÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹ØÈ±ãFƒ�BŠäE²¤I’ªRª\™2£Ë—0cÊœI³¦Í›8sÆôÈ3H‘!O åŲ¨*�H“*]Ê´©Ó§PöôøèГFYFÝʵ«×¯`ÃRœÚ±êÈ«%©][T¬Û·pãÊ�;‘,G³AÑ’\ËV+Ý¿€ ¬ÓîÇ‚@óêå«¶-áÇ�#Kž,Ðp2˜3çØÌ¹óf> Ó2FZ%åÓ¨S«†Ê3³ëמcçÍG4_ÒÁL¯ÞÍ»·ïŠ­_ —í™¶íµ¸uÿ^μ¹ïCУ Nœ³ñ½£K·tν»wº‹ÿ�.}ºëêÖCc¿­ýè÷÷ðãC?žü!óçÑÏVÏ‹ñ¯äÛÉ'à€Z”@$¨` 6[F„Þbá…Åd¨¡2v(̇ &I�$–h"B*¨ ~9D(!…^ˆ¡†vè!ˆŠxâŽ<˜¢Š°è"„0Æ(ã-4Öh£28æ˜X�PFÙÝ�ö"ä�E†p$’I.Éd“:J)昻Qiß•. æšy´éf’ÅxÙ¤0a’iç��™Iš®É¦›mÂ)'˜Oâiè¡té]u´E¨É£~ª h›�Tjé 8։覜z¥(tŒ‚æ(¤‘Nš‡¥—.9§¦�¶êêRŸZÿI\£>ªI¤˜Šj¥˜†Xè«À{S¬¡ò1ê­¥Nºk#Ä4ël2ÐF‹€+ kíµ&Pe±Çâªë®Î>-´Ó¶§¶è¦«±³ŠZ+©~~‹j¸ÍŽKn¹Ž©«ï¾5¸Ê¿lÊÀŸbðÁ&$¬ð +ÌÈÃoéß¹1ee±*¬ò«qjþ0ÁlpÃ$3 qÄGN Lg•ñÆ0KÖ±Çÿ‚<°È#—¬óÉKÌÅ0µlÔË1=ØÌ4Ûl Χè¼3Ï>óôKBE´ÑXÓ…´ÇJ3ítÉ<3u_îÍT5KWg­ö[[l³×_7öØ�­\ñÙ*¥½öÞ\)ÿâ7ÍI<ËàC¬ó0ˆ7LÄâŒo™oMxç�˜|WÞ÷߀»mÊà³þðáˆoÉ8㆔núã4Ež’ˆþQnùëHù­Hæšsî9# #úèD˜~º_6©Žñä­óûñ8ÉN»À‚n°á%#®û‘¼÷î»!¨›ÍmÜwÏzñà#/¾KÊ/¿ Á¶?ÿyô¡SÏûõØÿ}áYaÿýÝçχpàƒŸýøTHù–‡>ç�z$“ÞîF¿ÿ]„~¸þôÇ=þõ¯u  $6ÈAé ]Òthf€¶â„ékÃ&1‰\¸0Ñ … %h?r#< a½ÀÃæ/6=¢ÿY”¥JñˆþJbà zðW0 atHhB°a,|! ¡%ÃPÐÐ M”=¢Ãõ°‡,âõSÄ#1‰'YâAÂøD MŠ#ôX pÂV¤‹-|a gHÃ0ޱ#eLÀy˜F5ö€ˆErã£D9„Žu ÉõDE>Z±s9[XÉE Å�ÉaYDGBF’¬MbÉK61“š,ÑÉ>þq…�tá CqÊ&’#C +=ãÈGzF‹.l£gY’Z“™Ü¤y©Ç*úñŠÀÔâ0‹iÃcn$™ËìL3cÍ\H‰”ŒãøBhlÖQ›Sì¦'¿Éÿ¹YRœ¥$æIPiŽÈ�éÜL3iÁІ¶³�Έ¨D©Iî2:ÍÄ%$\§¯]öò“œû')“ÑErr�£1¨ßšÐ…6”¡…¦D%j¯dTR|…NFq‰ÒtyTŸ¾ì§?Ã9Ò’´‰=mˆJÁÒtºô¥1ÕâL#ZÓ›"/§‡h¦p¾g¼}ý4`{ j?E*Ì€štƒü…F6rÐ!±è‹ô"ÆKaUNÕUÕ /^‡U­¾æ‹Ýëµv™Ì°‚tp�H¬bGYV’šò$œˆ¬dÓšÔ¥6•8p¥×\iQW»Nµ¦º­h­º·¾:R8€�'-«§ÂzS¨³Pìbƒ¹EÇÿ Ô$’�,e»J˺U?™ ×f;›‹»‚V´¡%í¦x$ˆH(² À’Ù‡êZ·™iÅV"óè1!¦"ý“ûä(+TÄÓ¬²•iÖL§BÃîò‹Á¬°Û¨Æ7–ZŽ;²ãÄ…ÍA¶nœ%³Žlé“`ÚÍoÞ4‘;m¦OßÃܳyIýaS‡Õ#t‰[­FÚÌÖ‘�õ~�°ZsèÖ [Ù8…f çÒ¿íL¦á ̓{-Õ Öv뼊B#”zõ²mäç4ó®$ž¶�«m¿kÃZÛ_涆Ý$=[“9Üu³¢‚ƒ2äï×.bZ;ÝýpxWTÞ¦·½ó¬ì/©ß^ÿº+rC»jj ‘ÿ.¶Þ0¦Ávámjø·;ñq/×#ÇÌÅÓÍ™dj¼Ý�t¼�5o »úÞâÕ·ÉùílΤ|ª+×EË~aúΜa^NøÂl.TœçAçÊxw®;Eqü ÝEÒѵÈqãúKO O`r§«Ï¡Þ𨩮Æv^}¦Yߺ߻npDÓœadï§ÙÑ®vIïˆ'"ŠeЧóöŦ�}œû ë®ô�«†'EñO¹VŸù ‚[®ðÈßä\x‰¸‡—hÖ·ìòc{ýà [Võ"ϹÉ#Îáv‡¸åO„ùÄh~ó¯é<„>úVˆÞ…¤¿{ÞQƒz–¨žõÓÊÿìY,û§“\êN^î—¤ò•óžë¾o|¢ƒ¿«áãìæãeøñwž|3ÈljôE�¤FlÖLÍT}ü¤aq5z ø€dÍÕ\E‘jkK¶��è±´H^ÐJ8$([‰å &x‚(h‚¦7›US´0œ±G]s ŽPƒŽ7[´A0÷6 6hƒc–|¸aG€«”PþæHh€j„€Å7^ ˆ} ø€�€1�@R�’4e’¤�ȸH (DÉ4‚$Ø0)è Üf-h//ø/1XB3øƒ8x$:<(T?XƒA"C(b„:„„I‚pwjLØN88 H/ ÿˆ TX…'�X¨ ZèF\èF^˜�(I8†AT†ÕG‚�€†)¸†m8.o¸ qhshƒu(#wÈyØO{è}ø!˜Kÿ·`„Š=�LÔ0ŒÄxWX}O Q˜ 5‰À`…Q‰+¢Íôf}°‰¶Ð‰n4€d(‚Õ·†¨8W.0¸†zC‡ ÓN9Xx80=x‹¹( »8"Eè‹¿ølÝè"ÄXŒSuŒ —ŒËØŒ‘�tÑ\lŒÖH7¿KÜŠCR^åŽÜ–ŠÑ²Š­ˆ€é‹ëMíØ;�z¸‡óX��ˆ�ùøg†!ý8ŒÆèH‹8 �.�èŒ9ÿItÄQ�oÆ�I�J‘9 Éh -iŽÞz4È‘ ÃŽv莴(’¶H’4öp&y�Ñ•’R”üØ’w%Q/b%�ÍÒNÑ�ŒA‰*’�ˆD y$Öø“èÑLÉ4”DY”1v”É@3Y}Yƒ •²ècmBu06˜*iÇq«g�â—\™íd*-I aQcÉeɈPx–Д–’È[ $n©�pÙ“rùfYò�=€+x©—{9W„P›¶)™9pŽL©ŽOé‘G8¦€˜y¶˜¼Â5ö˜‚›)Y™“r™™é ›Ù™2ù™Ä€–Т–¤‰“¦©“²Á“¶%ÖØš@ÿ©F°9”²é_›e›·é1‰ŽM)˜©E[œÂ™BÄÙÈwœå™Þá�ʹL5Åœ€âœ™�‡5�Êš• عqAÉtš]©Fq)#áY$³H¶b+å)‘ç7>¢"ªžµ‰›ºyB�éËøB±DŸ ÑƒŠYƒŒYwÈùþÉžú:º£ M– –D´!�3i� :šú<¡zˆuéHz! #  /k›²6¤(¢#J¢&º”(úž*êˆÐÔ¢\30õi@÷™ŸV£ßq£Ã";Ê£ö" nB ai üd–՚׉¤jKJ?Mê¤Õá�Öž¬ÿ‰¡R©¡WÚ¡¹¥<Ó¥^ê$JaºO»iƒ+êBhª9kŠomjœoºŸ½Á>æ�É”?ù•_™º‚ܦ ¶çaÉ[Q •¢Eb ¾:'B£fWÁ>g‰äcqç"J“©5Õ¬öâ%‡w!†öK 6q³,Ï�­ÚZ=±Ð­Þ{öœÔOP®æÊ—þ‘L#ƒ¦�ˆ•XÓP�–|‘65�¡ª F3­Ú=¯Š_Ê0´j#r«‰¹d㵫Sç«Æ¬-#¬CA¬ ‘H!ËJ¢rÃ35­ìQÒªbÔê0´.2´¯Z´ s´ÌF°çÇ´N« PÛ$ÁÚk‹±–aµ�µˆºZk3q6a¶a˱2­àT­!‹¶#«¶l{²o›Oš3®œC·u ³ã"³.B³®h³Ÿ„³~«³€Û$=?+]ÿ²¯ÜÓ¯› ¸ øÊ0°I[°ù¹ û«”Û°–‹i¥¹Á¹žÿçŸ 2¡+º'Ó0Ñzºk@Ls¶N“¶$ûº(k_U·›#T¶k·|�·« ·7Û·Œð·;¸¿`¯�q¼ 6]B˯Dë¼Ð 'b_Év°M{½ ›½R»½Wѽ[F !JS¾æ»> “¾\’!€‡oí»ºïÛºñk²m»e…»²´û®‰U®ú»m¼;0{ ¼,¼¦jwÅ{¯„›¯@¶ÀÜs‹Îkœ$¼Gl½é'¹Ø‹#EAè‘Zýã½¾Ó'¾CÂ_3¤0h'¶B#)œB·sÆ #[ ¿%;:m ÇŠÄ«@±6“Œ²…ø-þ±Ã=ì»üÄܘîÿvwL{<$ØÆÄü§U½PŒo†°U<¹8²yoEC¬†![–LkhÆ$ŒÆû§ j|ÂÅÐÆì«>'7%¼$j»¶¼“Hy ´É Â}왑ðÇà%þF„œ·5ûÜÈÙWÄì�œL“¼‡MüÄŽxž\«V|Á¡t£,A¥œ§Åö¥ÊÜÆÊ¸Ã0ilº·€ºyöÆƒË ã%»\=¾rpÌa 4Éh»ÈÌaÄ¿þû»Ï,Ä�IÀ�<rJ;Ö k”¬¸Ú<½�Ûͽê«ù#ÊÀEÊäs'Vç¬É,öuŒÆÎ óÎÎ0¶ó¥´"£‘8ƒ¾K’u"ÿ²ÏtÖÏ‘1©a½$ÉÜDÝÌÿû9K ;K¼‚{�9xͼ©3¤HŠ SÑ.âÒ�\ÁŸ¬ÑÝÃÑ[ìÑ]\!=Ò[fÒ`†Òîüʱ,Ïnl00-22m#4�6�U ¬ÓÈHÌ=m#?mCAÝ»ÎLÔÁkÔË#ÒLK 8M-ÑØü5Q}†kÉÞŒÉÛ<Åý´Z]AâÜÑäüÑ`�eIì"c |'ÍÊ)�Öð¬Öµ| m�0 ã%q s+u½Óã•ײ×Ô×><ÔE}Ô„�Ôtaâœ[–Ø‘à&SM/¶Ë4=ˆmËâ%ЩýÜK¢!Y’%pb�_DÀkÿ‘Û2ÒÌ«XÈÍ0¦²Ü8#Vc®÷¬±ÍôŸ9@3êm0æj)�iŒÁŸP¨!Õ§ƒcÛüi"1ó{3B¥X–"À BÁ‹r!ÜáAÜ,fÜåm´ÊM·Ì-THÝ6ÝìÂãáOvÝž‘ÝE'†§*HÍàÍß!ã�XÞh“‚Þ/ýIë]®í ­ï�£�!ß:NßåjßR¸Èù]üíß@u ®ÈÎ< s žX .Ä î¾n_Þ&É.8~0=Øá»Ý"Ý"~ $ÎlÅ`â��â0¢âÐÔ+w÷ÝÄä 6$3þ5Þm7®áé=ä§ÿÀÞ ¶?>§ž!äü´ã`ä̘tIÞ[!~λÒùä•WàzLåså��å‚­È ª]_æ'Ú fWæÎb»)ÆáÕçÊâ,;Ýk^ÝBçœaç‚ç‘{#¿íâ}Þ1!�>è&pÞt˼ó�è<¾èîíHð é)TßžLz—>K®ì`õZøK·ó¸ Ì¾4¤nêÈ—ê¿°êoÑê+[ÜÕë�.±Qëý¤æ¨Âæ·àæLƒëÖ=!Ø-ì!`*+n#Þ­/.ÞýJÞdnÞ“ÒŽèŠnŒŽí�ì1ÓÎíXíí|¡ßáãã¾O-kîWÙª.å¡^3oÓî•ÿÂàSøŒù­ß¬nÃ]ï~ïù7ñ®ï�î1i~ë½þámâô%nð'Žð Ÿç`»çŸì&_×2ñ4ô6(߯_ííjÔñ�ñEÞí–>òJžéá±éÌŒòåî²çÞò�0å0_å2ß4‰‚ï8?ï†a¿[v‹²ôβïDoë ·,ÍäæÜÌô"žu^$ÿ5) ­Tÿ ü‹õ‚m‡¯0Öøõ¯šòtOºÊÐè�,�’¾qk�îmmµ»y“Še®LÀé÷ç³ÛÖ·÷Aïòî�l>3(2†/fK’©Š0EzÀùSœù“_$ö\2Q_ìƒòEãÿ[ÃjvnrW£ïÌkúæê%Î(f¿ ¬OäÐNΨ|ªû³ïçcû7\®¹ßâ»a¬"XÐÔÁV OÍbÈðÑÃF•M¤ˆÌ"0Œ¿4n„ ÀG�!EŽ$YÒäI“T®,ØÒåA˜¦NͤéÈæÍ<9uR¤HÈçÏA…º\•ª!ÄI[ ÚÃéÓ˜�2¤Éj.¬YyN ÑÕ+Mš&ÄŽ%+V§Î¬Z· cÛÖÊ[¸冉jjê,«y#�ÍéÌïß>�3 ºÉðá»/Þª ãc`¼$O&Z™`Ò»4§Å £°�=†\©Èô\�*mÕðá£ÍX)£Ý¶-ÿÇŽ¦É% 3飯#6jlÙãТG£dÞÜ9ó•,-«Ž væMœ|ÿJ˜¨Ñ£¬—~ 5jæ™y9çjìõ«õ²ñMðͳ¾±m¶p㢮{W¯UúþL°ÀËá0ĦZŒ±­<‹l2ɼ�pÂé0›J3ÅÖs´Ð–û¨´ÓP£N<׊�½‰h3?éÝx{iµV€+ñ‘ኻ(£ä:zîG ÔM·é¨ƒÉºS°³‰¾í¸#ÄÀï¦ÏÀòœêïÂô®â,.»t¯+$å+‹>ûÖÂO¿·P£ë¼©þÛ‹/ý"°@Â4,±hÌA#œP BڰG‘@ÜÿMD‚|cíÆg« ?Ü` q Mùm*á$ÚÊ8äzô0HRKiHÓŠl4*$•t„É­œ|Ò;—ÀkhJòª¼ò¨ª´L«K/¿ S̱Èäì¾3ÑTs×†Ü 0Î9û0ÐÎMð\pOÏúäåO@-³�×™ í̳EKT¥]ÅQ¥ ÍP¶'µ­Òt1m‰]‚ÈSž@å±ÃQM- UE1ø`5�P¸!Tvø®ºÈ�ØŠ“ûeŒ3n¬±[:öM+þ°L.»î÷˜Vù‡it8ú�yf$‡Ëê/�å2NgÖ›äg ‰zhŠ6Z.Š“¶…¦û«Ë¡ã»©¡T\2ÿX¬¨dk®Cã„“[6¦ˆ–Åhr¸åSbQ;–‚6p[UBãšë`‚aænfšiFìŽ 0@©³NepÂ7q© ÄWšâ¯9¬±õn2;pj…‚Ëb‹Ã[oΛq°nЃÙn¸&‰`¢^Ød“#ž¸âä–‘}v±yòøc4E®ŒdÖ¢)å•YnØe,O�™¯øjŽèf¿rÖ™çõ�~ú¡‰6ºh¤gš§ý‚Zh©m¢ÚêC²ó�¾»v²#ܵÙ&Èí àF_£ºñÎ{ï�ûþûÛÞ®%‰SÜâ÷¸­DÎ&ïkHå‚r¹ûiDsú£ CW·Ñ‘Ît#A�KTwÿ„ÞA,*#CÒ,6;ÚÕn"·ëÈt—:�”¬w¿;Hð„‡ Re&Ç;Kò¬c3¬àŒ6:Kô83½é•…×Þ@·´¦æi\ŠZY¦Æ�ªµäjY‹ úTؾäp3‰_ÛÞ·ûåosüãØ-üÖ®ÎB€! âžxÀÀ@Ž3’›É]˜Fp‚$äE§Ò©bƒ"é`K>Ç£¸®„° e§Â²Ð|X{¡cGšÂ†hË—�úø,@Ì…�AD#¦‰ÒS"}�=¥m¯{Îø1Âçˆñi±|\¼ŸÙW¶>b©Œó;cÕx7½ñÍ�ÿTçH�:ÿVáŽ_C Oè1þ1�÷$!-xÁ –n‘§B ç¢2H6D’&Œ�%;Í­°ð›@'ùɆr”ÃKæÉx¨UÒ„•®„eœ¢7ËZ2—IÓ¥½GEðYQ|X$Ÿùº¶/"³”cLÛÚÌX?4¢ï™û“æȺk®"›Ût\¸Ç´�v²Ü["(AŒ˜³�èD¤×ù‘Fä‘ñœÅ<)¹K.ãžl¤ˆ>ùéO¥t†3ÞÊHù2T"¯,Êkóœá<`Å2+³@D¯7QŠU´SLFÉrÅYd± [ÄÚG×'60Š‘Œ&e&J�i·5¶”𭱿áêHÓnRäÿ›áäé}úÓr õn†L§"� "� 5L•£a`Ò¸'n¤-Q�jc´uUÑÒ”\¥Ño¬ÖF¤²,Œàmo'"úM¸@[Ý —'R4Šs½h]3j‚¼ÜE¯áëùŠ ÒcºO§:\æ*èg¿4"šTµÝ4ᘥJ=ˆ–s14WÐ0gr4kÎÙ�Îbž=jhw7Z¦æ´_K­FVkÏ{ò©O°ý¯lJ[M±I¸Õ-YzëÛå1Nàp‡‡ë·âB”,K,r“ EîY”—õ¥X¢;•鮢º~ ©vG:Xµ�¼*/KûgÞ—š,½.Yo{oú^¡Å¦óÿ%L ïûdfäƒÉáï:ýëN¹�VÀAíâTËÖ&8[ Þ$V »£¬¶ ¹mñš“ø\˜·¿P‡=üá#ñ¸o91ŠwÙ˱¼ø(1žñuÿº±Àn—¤ÝýnJ1·R|¶Ñ¥ÕD¯ªŠ<'÷ÂWIòÝ}/û (ßWʇ M•yeOÎE˦å2�½l`0#¸s †ƒÝ)CÖ…R<v3¿(g9Óù/væð‡‰kãŽØh&N®\éjWAs¯Ãì«¡kFEãX~Þmfxõé|™Ò´t•¢EĬh;œö´6jÍŽz¿¦K@½í�ê–Žp«ÞÄ€9Qà_…S¥õÿdl�j\›L×n³A}=`_XØ~!vŒ�gêU�Ä>`ö�Ý\h[Eº%&úŒ X‘¢‡ÑÝæñ·É[Uq3¶ÒEº4�Ð�uãÕ�LfŠ“á�_Ùé—Êô¶w½ñ]}Žßþ¸ÀgGð1׺̱Mø Øe[°à¶1ÇpY5\gb_Ù³ÔøÆ;®½å>û¹Ñæ¨0=jíìbûÆ%Íqawü胻¼“–9¹inî9ÝÉÄP²�yÞSwkäç@_†ÐKm*~b�(6dRXcCnya#�aQ£ê ½(:¦ùƒ™‘®tÒ/”0Ñ'EºD Øg,m5Až€ ÜçÞ@uAR$”ÿ¨ñP_øKZÆŠqä¬~§s,}óÿГscjÌÐ^#ݤì`’�Dc-;·gD ÿ¾™J¸eEEM…`ûãSá±Ü…üó'—:·xBFu¿êRä0ù੼YÌã–Íû üðŠ1>äà åcˆÃ(ç+=èܯ™¾¿¨>¡¹>Ë>í;îó>a8½¿8™¿ „$ôãõC�ös¿1+b1�õ°?ÎÁ?D¡ý35çð?\$Ààɼ†Î£ ÏóŒt@‰ÀÿéHB D’ d!×ãØ£Ù Úû@Ä…Ýcü½êAÁLŽâØãó&œZ·©ˆA‚˜Á烄èÃA¿ÐAbàÁAóAí Âûù>©*B‹¿òC½xZ¹¨‹õ{ÂBx?)$–*L†ûÃBýÑ?*ã¿Áš<„/„§8Õ!§ 5KZÑx@7´ 8L=9Œ T ÄCÔCÌùÃêD²hŒP�m4ÄDÄÌ…,-æ+ºHœÄ] ¾­°¾‡À>}ËENDO ¿P<ÂQ´%œô‹ 5y�×`ÅšB*ÜX¼BYÄZ,5[|\üÁ]\�òE•F`x²¨"ÆÿsA4=‚HFÒZƘhÆgÌCØCj¬F¦A°(Á±ÐFnTA[`AEL‹qtÄUøs¬A‹¹ÁtÌÁuÜÁvìÁwüÁxÄœyEdE"ðHÖ1E’a“àðÇGH„ÈWŒEý1¤'ã¬ZäÂæhHí{HêÅË Š´ÈalÀblÃN’‘¢ E $)°˜ÃÛ©Ãd¸C’4ÉAI¦HŠ#¹›`I±pÉ�èÆÐ8Ä]HDÉ  ©‰œ²›ÄI{;G”¾ž¬Ä‰¸Cv|„ <YPÂÑ�íë¾N§CJ¥dJ“qÊ‚ÊùÇ( È)¼JƒÌÊ ÚJ¢RH¯d°<˜/ ²»HŠÿ‚˜HÌ Æx ººÁHÒ`˲Մ$šX˜àšÆñ»Äˈ`«Å8 (!¡ð˃pLGL L�0Ì�@LÅœˆ¬hLÀ§F4 ÌII¬LJt†±�½ÍìLù M·M!$Âf0BAB¸ŒKS#©œÊجÊÙ$H¬Ä­¼/®ü…EêMƒùÍqcá$â$ãªQSN�0ƶL�Ž•@��§èTlÕÖ…Æ-ÉU î|ÔHÄ•,WŠ8WoŒIpÔTd×å“AxeRŸä {¥MÐ�àW5Q‘W¥–¸”Õ‚}MˆZ©u¯¬ˆÚÜUühXÐyØ)³Ð ÂP]œØ#¨Ø[¹ØŒEŸ<ÍBŽ}ÖåÔÈc¬Œçœ­k%T5ÔmMT”]ÔÚcÙÍ�W˜�Ôl¬TBD×›U×MeÄvõTçU¯™×Ÿ%U(uÇS%J}5ÚÓÜRdHZÚXZ;iZ‚Õ”Ú© G«5S¬µ ­uجÍMÈ÷¬Ó•IºjmÂZ…QÈݹÙCr�,œ�ÿ-4ª�à'·D }‹K·ìšäð‰&}F�p“P’é�^¡Øžðl› ØÛŠd€†Ý½ŸŒá`†aà£|™‰Á‰¹0öå…šMšÈÚŠ³°Š(Úø1úÙîKÕUm ¡zŒ.™;qZ¦I˜X/}Ò§>Ähh`6$m¹Ó mSÓÉšØEÖ•!­ÛÍÝQ°5QK²Þܤâ�‹ã¥ÀäÝ‹aÞŸuÞœ€^#ŠêešëµŽ›Ð^Zà^ï�ðŘÆßò}LpIßµYßö}_Љ_ž˜ßH¨_,J…û=„üÝߢ Ûø_Œà:àÐY Œ NàÛY`~à ŠàŸ2¤ÿÏú FÑ–°! ®;ÜÍ]¾MfÞäaó)a¹8áÔKáJXaBh^¼}Þÿ% ë• ìuÖáïE�áÞ.!_ób(.b�`_CpßÃ\%¦&vâ¼ÊdµÁ_ú¡bUÝZÿ5'æFöâ¹ã*ã1îÃ2n`î ¾ 5€6¶ÙåÅxÚ`:NŽf<< =æ¬êã¸5@dB¾KØ3d½@d—˜a>¨a°¸á±Ø^žèÞHÆœI.çJbpÒ)ô5åX0âNFb[å‰åŒâ)ŽÇþe ,-f ¢˜eèüâ˜c\¾2Þå^†�‘¨ãÐ fh[ÿc†$dî`e¶ããÔÂäîfE¦aF¶áìç.çV^töaJæKâ $bµ‘gONOP¶©�ÁçLÔçTæg+neBzådׂ h¹]½ƒ@h\^à5Tã`®`Øuãb†H‹–c†hÐAKŽvf�&a�6a‘ž ’ ÆLgDé<€a53…DÎ�EF’#}dš>g‹Ig»L†�nçó=ŸŽçM>âOV{V£¶ßµAe·Qå}]jvå,†åG�ê..èZ>è[Nh…îìæ­5‰æŠžÓVˆµáà±Îè`˜�'c‘DZH’È I5ÿ�¨Ý¦ÔGÔØÝ@Ö®‰küDÔd ¾^é–ðfpO¿v½šVáäÈÁVnÂfgzgõ]ìynììæ ò†È~b¤v²ax2�jËëï>ŨXCÒ¾âîØÔ&{[í3ˆÖ6™¤€íX�íd бíûÂíÜÖãÞnÎß&-Ö âÞˆã6i¹îænn˜Èë½näéÎÀê.îÐÀnœVg�ænwFlxêšoŠ(ïó.åôÞ€õnïûzïÎV•é ð}„‰5$n}Êo¶ÝoSéou‘‹΄ pÇh¯×,O$ïà^Máž‹ 7î­An»Üp¾îp–Ökÿ—ækq r¦nÀÖß…^çKîéï Òo”s±‘qC&åĦl§m‡uoÏ€o¯ g˜òÝòÝÕo#ÿ$Ÿ Ök×vr‡è)ª*^“àm,�æ?¿.—‹/ÿ… ¿f2IOs—iHž›íÙž8Ÿó¯sJlïo ?Oi@‡gA¿qC‡ŒÌKtUYô¹(ºzsô¹�v®‘ôIwŽJçã%7Ö׆í'çtÙ¹müÈíÝ^¬ypR×r ?u�HõU?éåæ‹æ¾ëWÿæ—ç˜fó™vsZ¯u>¸õœÞn]')^Çóÿõ­öºnâ|žl)¦cÏqÏHvÿeïqØVgOißšŒ¯j¯væ¸öµƒl·Øm�Ÿn§íN7§O×í‘u/À2t7õTPvs Oî¹~÷³ˆw3î–¦w5¿whsß]~ïwÇu€çé]¿ó0àä<ÇÔ=¯„§ß…?å†WoBgïc ‰ŸxE¯xÔ¸ø�/û"÷xJ¯·Þˆ° ¥fÔ€D‹q:Kª Ùßý½øèP ~õµéAÙøñ‚´® _‡Ê  €¼xšHlw:ŒYIò‹¬ˆË¿üõR“8wÎïü² 1ª‹£·LrÒ;„=9c„¨E�ƒÑ ËŽûïû]Ùa‘5V°ÏE¼Ï{´ß}ÿ�Íû¤Z•óê5YCØïWp· »ç¾Ü�޽ùéàÑ¿×6µüÐ#ü­ï´HüÅ/¨Æ‡çÇ7ŒÈïù¨üË·üÌG�Íï|Î'–Ð�Š£o-L¢�Ô_ýÃh}Óxýä8Ù_(hp„ 48ð!Ĉ'R¬hñ"Ɖ †éèqá*S¦Z‘l5ë$Ê”'=z„äò寘2…Ñ\f“Μ:qÒì)LР †Ý@Ò¤^¼€T(ÒÔ©¨*gE­z*Ö¬^^º”)³Ø]b•‘-›ël."±­Š²jªTYc�ô¸én+«§Øšèë×Úh‚÷(l˜eG±Šwÿ¹jìø/d·*Ÿ>åcùr³ÌšËrîœç3hF¢GkÒt÷î¡ÔŠVõ꺧Íe;™ÅŽíúWD£MÍèû7ðà¿�"RdI“SUçÚõuÍ›³wú¤T(Ñ¡F“*eº;¤HÉ)õ^�k+×Û`+)î¬ mÚµm¥ž„+7kÝŽ§óZå ðYƒfXaÅ-&Ö ö%J”‰„ „j¶™{ž�öÙh¤™vZj‡¬¦Hk·Å›t:ÕfÓm¹µ"‹ ÷"Œ1fDbÇ�TÒrÌ!æ$·‘(Ût:U÷Óu’|—wH-uäS Ö§—yç9§^XcuŸZlE"ž}såÆ~zùÿY`FC`�ˆ¸‹‚ :9‹ƒ¦D(á„ÍThá…ŠVÚi›tøaˆ"þ8ۉˤQ‹‰n$#£�2J#K6&—cJÍM �0±)duEyä*I °äwMÒ7”æ¡“këµw%ZYÎwÊ[QÅååBvá%f$ –) š=x`›ÿ½çœÖiç�e]ˆ¡ž|r¨k@‰8bt@šxâ¡)úmŽŠ;®o�~´r8RºÒŽ—z5è¦ ìuº7»Úm¿}ÿ{ܹ£¼»Ê Ç2ÛQÃ[‘ñ(#äÅ)]:SI”>ô!£‚ôN€¡Á f-pÔ3šõƒ½”ĉ&Ý%NDx'<ÉÓ8Qñ¢žö¤[OÖ³ž)z²Ÿ�£"@RÅÆ�„�› ϪP÷°·ñÔ"*ÑYÒ1¶t%.-³Ë¸P££uO°âDžA3ÉLF:+©›Ý@Ó�“‹Ä³JZŒ™Òô¢9h¦JºéMp~Sœäç9ÏYPvºžïôTãDiƒ6NŸ`á§?£êÉMn„  1(BšP†²ò¡E’èD)Z…Z^4£|Øh*<úÑ΄ÔA#ÿ½aIOšÒ(®´)-ÍÙKczLšÖô¢8M‰N¹ÉÓž^ì§@ ê-†Ú§¢©FSê\˜j4§VªR½l©Ú«*«zÑêV;ÓP¯^¬kljS³¢U­)šDÊ«õÅU™ËTéFžÙ‘h>ðs{Ñ+|ø:S›þ%�uÄ`'áÓŸ"6±W%ªƒŒzÔ"%1Q’ì½(‹Ùí^V³álBì†A¦mu�Û†è6 ¼UŽoaà½دFÕ�›àÃõÛpðt¯áL+NÍ…3¬åÌnX½NñB;sR»¢¦EqŠsÀZÇ·31–qhÌ5ûÇ(Ío�2ËRù7%B�€ùjS�d“ñ¡šñ‰ÙhÌòHýéÐqq÷Q_=DfŸU0àöy_2�Ÿø‘Ÿ‚ÄéýÁùaûOüÍ OÞ_IäŸþÁÿù _ñ�Âñ]ŒòÁóýQG(``Q 18 WDÄ –yð &®Ç&aBtà^ÿDúÍ– ÊÌÀM�BàŸa­ |¸‡ ¾` Î`ë  " ÚŸû, v̉Jq„�^èP!X¨Ö¡ºÝÛ5áî!¾H®ÑJ`UWIq!ð½ |!Ò :à ڞ֜á¦a²¬a’´¡ê¼¡ûHÈa%ÔaÖÕ2‹ô¡)ž¢oüá¹br�!“!¦"*"#à0àb!I !ªáb¢G�‡q¢'‚"Šâ(ò *6£3B„*z+ ¡^¼âvF Y�Œ-â"–¡7ñ /þ D£0†1n¢t#2nG’ÔË·<#=Öc4&ÿÏ4¾O5V!ºÙ›9ƒM!â/ýÒÈX“5ýG :¢X|#$æ ûˆ£#�c%þ¢@ £0FI1¶cø­2ªêT?rÆ?äES1½$ĤAÒä-Žá.Ü$BŒŽNÎOR¢OR$ˆ @AZFåFÎá;n„¨(%SÞ% NÙ”™¤ F…5¢«½Yb%1i%Wd"ÕäB‚…!4¦c’å�e/& ¥Ud’´%ÝeÅ[“Q†"]&‰]âÿ¥hê�^F_¶bTvÓT–EU&a¦žÈäL&æW*dX2¦c6&dŽdr_ÇTæZ^¦¹%Qrf\~â\6D]nØh6g&E½€]Êu� 8†cHŸôYgc´Í´�V® ÿñHtöå)ÇzxŠoT½‡ú9§{¾gp@'¨H§ŸQçqq'"yçK‚§ï)cS@¥U˜'X §ìñ¨G§‚*¨| }:ŸéüÅ}> "™€~$Αž&5(bœg‘”Ë~ ‚ÎÞ‚ž(Š6èwâ¤G€èuˆ¨r‚¦‰êMC©—¾'‘þgoM’Jè‹Rh~>ËwH�Žh�­"•v„•–Ärv©áé—î)^ŠŠD}Ç(›_žé’¦é…¬éb´i¢Ô_ýíh�Ä�ê!m)ŸV*=úiDªy¼Ü êŒÆO“2À“^Ç·¨ßâŒ%b8j�Ú©–êéËPª¥Æê)bêhê\pê)()h0©šî'›B©¢˜ªÆi¨*�f)HR*�Ê*³Ê­ÚjVમ~¯^ˆY�¶f«¢¶ˆ°bBL™±^R"Ð-k³ž«Ð=ën*¾uj7}ª‚�'^k¶bÿë¶²H·Â)B€kˆǸ @¹Â*º¬Þ©kS°ëä "¡îêÅÈ«tÑk½ÞëŠä«4~k„…«EükÀº*Áv, ªWŽç%¬°Ô¼f”ú™kELÙ,Ê‚’ÊÂ,Ïö¬¸È¬ƒÒìåÛÍ•Y¥¬Àú¬Ò.m£íŠ ­o-;�,.1­Õ^­ñD)´by8Õ^Ö†­ØŠ‹Ö®«yt-§�Æ×ZÆØ¶­Û¶_Cx¨D‰ç…×ÔJ×¾­Þî­ð„Ü Ýš]g±Ó”å-ß®ÞÅßnm,Ômµn„.âN®Ø*®iÕKàþÚBTá& å~gîØZ®z�Hd.,m®u.w€.ë^­èŽn¦.„éºHpnäznëæîäN™ú©Ÿzí¬î¯ð/ñ¯ñ/ò&¯ò./ó6¯ó>/ôF¯ôN/õV¯õ^/öf¯ön/÷v¯÷~/ø†/Œ!ù,4àÃÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹3. À±£Æ� CŠI²¤É“(Sª\9±£G–0cÊœI³¦Í›0]rÀ³g‚Ÿ@ J£¨ÑH“5¤©SœP£J�JµªU†:ôô ôçP¢Ki�K6, §O¯ª]˶­Û·unåÙÕë×AfÉ– ‹¶)Ü¿€ \2ë\uDX̸€ãÇzÇ>~Ü7á˘3kÆlxnbÆ�'ˆLFt�ÊY7«^ͺuN¹žë‚^lš´iÔ:]ëÞÍ»wìN|v„Ú‘M‡Yî4µïçУ«Î1�õëÄ‹ÏF®W9ó¦Î¥‹ÿO~-õ×±gÿ`œ;Yïašç.O¿¾ý™ÝèߟÞúzöÛ‰f›hËÅÞ|÷%¨à‚å·Ÿ~ýò_{&GàwA„Çà†v¨�ƒF8a€“ 8Y�ò¹äáŠ,²@R#ʆh9Ôh£8æHÈŽ<ââã�¤ù ä� i$H&Ùâ’L’÷"R1Ž0ãd6Þ˜#Ž<öø£�ytéå�Cš"æ˜I*Ùä™hîöäQNùX•5^‰e–„lÉ¥—]‚)ä˜d–‰@š€ªÙšmÒ§œÐIžŒ~©'Ÿbúù§ ”V ¡2Z%¢Ätêi£�2"ê¨�š"©¥¨¦j¦Rjj啞~ÿ *ž£’ 驪æªkM¬ºéØ«9F#l¬�ÎJk­Œ”Êʲfîêì³(õª)¢ÂFC,1Æz‰l²�.ËJ³Ð†+®FÒR§œÕ^›m—Û*Ë,’ãÆ+/Eå¾yî•é»nívûî¤ó,pBõþzo°Ãê»n¿|z îÀ\pÀâ˜o¬û2<¦ÃðFìñ¸I%uÝcÈ£¬y  òÊ+o˲ʚÄ,ó4×ÜÁÍÝ5Hb:'æs]‡},ô[!#5²c%/wr±]¾Ì²Ë/Ë{ öÞS‰ÿM¶Ùh{¹6ÛÈ:ý¶&qa5Ö_iÝ8ÞyÏÅ÷äQùmÉI®öÚÛáùç‡'¾8Ý[wu7ä]éMùê3Yæ%kžòà�îyèq�žÑév=Žzê’³.üJ‰|ù…aüxíàDâ|í¶Ž+H¼+F¢i�%¦úðÜ“T¼ÑÇŸ¸œòÄ2ï|$±¤¯¾íž[ãþûÓ3>Ôˆ aoÿcÛw¯ƒÿ:òä‹•ùœ§¾õ±ï}ðó“HtF¿ÐÜ{ùÛŸ-ò½±…vôÔÑWÀX°�t_ü’•|˜ð„RH¡ H›b�0Œágˆ‘ ’ ƒ>ZÞàÎ×A0„#ü�NÿNˆB¦�…Çq¡ibÃ*8ñ‰4Œ" û¾ÿ‰/y9,ß ØÁ†ÐAÄʉ˜#q=Râd˜Ã'BQŠÉJbV@Ç:fxÌãІ’�>‡€¤Cø²QÉL}uH¤‘Œ¤³.$1}Ì€È@š��|¨$ {ÀÉN’¦“�\d‘h(ǺÔÑŽsÉ£…ÆG?Φ’ƒÔ`!EuÈô%²¢\@#ƒHº2‰“Ñ$.ÉFa‚’“ŸÚá§vXŒG³¤ÍYŠ $(#ïâH…�s’Ži)C‹©É™B”“ˆBàþâ ãü'†«üX+3Ô F`¨KÛæ?5áM\‚“©¼|Èg®Õ…–L]ŒrÚöÊ×™fõ}[ÕIKX¯®¬x¼g$Ë*Ô}•j=*[Z9Xö²WȬf›š�¥Q¡•¼^ñ¤W¾îÕ¯rÒªþ²BØÂÎæ«0 «ÇÆzM@ÿf²Fé-/‹YÍf–³ñ,] LÑ*Œ´/3íi�YÓ F2’­¬a³ƒØŒŠu£å�GûÙ²µ¶•·–õmf››×]Ç8‰³ÓG�Ë4ä²L¹8yå¥!‡<·�ÑMÃt‰SÝwŒ¶ú´ízeRÝ&¼rïUƒ˜×:è�›zÙ‹2Á%W¹ò•“Äô�ûf ¿ûNE90kwŸÜ%œd¿ ^3¸/.špA“^;Q¸½~/†ß6_Tuf+óLŒØcІàÈH6œrð98Ù>çy‰Etæ:ÆØÉFȲ4¶Y™!ɤæ’gZ2æ#B_>²¢ªU-æu·ÿVnÞb$À@ç6ØÙH–úqO‚\—!×¥Èu¥CšC d85ùÉõ‰2G0BeCx1W>r–�°eit9fƒ³&Ç|Ì2“Íi^3›£ç´­Ô+;�Á`ç6à¹Rzæ Ÿ»â箚¸€t¡«th@YÑŒ¾K•!]#,k™Ë¹Åtš5]INƒÒÓDõ—EÍæRŸÕÍsÞª[ýjJÅZ³J­�‚`#§y×6êõ¯£ì¯ ;‘Á¤+}iMd:2b†™ûbæ%ZQØé¨žjm×ùΣ„5l€üÌÏ:&1åô AñŠ/Y݉öE²ó;Ʀ4² ¬ì/3;�Îÿîde"äï4§Õ×Fµªîê„{{á{nøp!^s¹â7´çœì댳{ãÂvt ¬\lIÛÒɶ÷²ñ½i}wº/,‡Ó _níÂa{T3g5Â�gœËZçõsaÄq-è#ÿèw„ÜçþA¢—GÑh÷PÄfœxÏ{äoöòÔõ’ï*ÍôˆO|Ö«„ä •àÛšô¤+Ù°sÛæ‚úö<޽µ²ñ>‚{#æNwöÙÝIŸò]ŒÓ÷¦Ëûéõ¾·^DßÃ'ñ‹�·ãqKð™J>Ë”7ªåÇ^v—fóÃ5�çsíöÐÃ�ôr¯;¢Çƒw½ …õ³ñ;ì£.{²Ð^¹¶¿}ÿî]¿{‚«Ì÷¿þÚ†_s²£‰œ‘œ1öj¿å·=o>ô¥_tê§þ!:%Q2LrN'rPGrR÷e×ò}¦~Š×-‡·Y£² ˜�è'yêç4ì×mM}$اDöz¸ zÐçü§Y!6eõS#ePƒ6hY€3H€rôuÏ„BØ€p_‡s{¸'�Z×|öxov�ˆ�8y·AÛF|ïwP÷E‚¬g‚='qL¨‚ûgzÓÇ/X41h386xƒa‘ƒw±†<o®÷w x1#„CH,ÈWGˆ„ãg€Ø„¼÷„¢…RxL¿gø2ÿˆy RBdtk÷#U%ƒI35h= (Ø(èçÓI5ã+l§%¸Pi¸è6oc6,…b …‡š0&§· ’HDœwŒ•äR0”‰i¶‰“щy删($¢èÁU?A‰ö³ŠæÈŠ­(6¦!‹GF‹Îg‹æ�ºè<¼H3¾HÀøƒnv8Æ(Û•Œ*&3ÌX†‘8FИ|þhW‚‰Ç¤‰œÈ„ÃXp‘Š43Šo!Ž @ŽØsŽ«ØŠU Ž®âz³ÈFµ�ò8�õx÷HùxƒÃ�I#�‚Dˆõ6�ý§ ÏÿxBј�Ó8ULd�_†��¡�î%‘y鹓%‘WÕ&b/Œ—fUh’7�‘�’+I-y‡/YŒ1É“3ùrÜ´ŒbÒŒ8i�:‰�çÔ“—ÈF�â�Ù‘ÛÈ2çs”IÙKé–�á”2ÅNb.SùeUÙˆXgZÉ•<ù•¥v8ˆ™’)“u6¹!9iBL Z–ä“14—×ø�ƒ‘*“—ÞX‘àHŠ%~逘5˜Ro#ÉD%™˜Ø¶˜œÔ‹�¹#?¢�Ì™’™”I“–™–yI¶™�Ö™wu\^B—C™f¤™mº(:s£YÁœà圣ñšdÿaU²i09À#ƒÖ(¢‡›¹9�‰Ó•Ê݉£ßÙšáy¡ä©¡„É¡òù¡@¢¥6¢qŸ;r¢´¢¬Ð¢/*`1ª€6Y£wÇjYº££f-7Ö(+(”Bšfêõ‰Ù™;ÛyIš9šv“±£up¡cñ¤ï±¡[Ú¡TŠ˜!z8XÿJ5Zj¢Ú¥1sŸø¦39¦ÊX¦�h£hª¤:‰¨mzciƒ'q*š(ø#vj¤x¡-Áa!±§} U¨Åp«¸ª‡Ax¼Ú«„*† ©SÊ(ëÉžZɨ�B¢o)¥ó™¢õ9©,Z©á³ŸƒÔŸ3êdfŠz�¦raT#ª£Fªp }rZƒV§ôɪT£;Q_ !«Kê§�a«¸z«ºú ½ê«Z¨Qz¨ÃŠ'ÅŠ›Çú6�Ê›Ëê¯Í*‘^ ¦Ó £Õ*£4º©.¨f!mH¦(ŠÂ¥ì …›àlÌê’¦¶Vcò>‰affñ ú!6'% Q=‚(˜®l°+Ó(5ÿp³8;S�H}гÂH¤&)Y‚÷efƒ(‰ƒ`6R3<"„ðè4áð´2C RûŸ‹"H[#1t¢³“©b²—½‘fÁŽ! (×¢ë± ²g9²îS²“(ë* Wâ´:ˆ0ËF4‹•8›³:Û<ë³[V¶�w8º–4ˆrW›J»#L;8OQ;µ¢dµàe#Y‹¨2êµ¼¶a!¶d ´Vz¶V׋¢k+&$[& ·(;·_\p·J¸)r‚I{k’}{³ ¸€Ô³}ð³E´†{nˆ+'Š{¹5Ò¸„ð¸k¹“K Tk$–Ë[˜ CZ»¹© YˆÿF'„ÿ‹›¤kxœtºÖºº]afJD+Û²w�··«· j¥,Ó»�¼ƒ+ºæ'´%—dÇ{%Ék½ËK3K„Mû2Ð3R+½•Ëû±¸™;¥ÚkÒѽµK›Gv¯á›˜ãk#�d¾2о]ŤN)»´›K†(÷š»!j¿¿+¸ª¿…û6‡[2’À—•´ì¸ ¹P«À”[µ¬Œ½šK¦]»½ÏaÁ(¼„ªÁ2,¾‡ˆ�h+¬Íšº¦ Â?a¡iÂï{Áƒ#+<¿ô{~{¿Â›cXÉ¿ è¿6ì'8lY:|ü Ì2 ¬ <½ER½9ŒµF,ÁHl œ«&:á½!ðĺÿºÁkŒ,2ãÁÇtKWŒ,¥2WòZŽ]<£‡_¿W2ÆUZÆ*§Ç¼ÀËÈ „´s–Hæ-¹tÃsñÀr 'u|džÄ ,Ä.‘\%¼µ*f+|¢–�{È`l€Š¬‡¨�ÛòÈ52S’¬¶” )°ÈÅç¸o œ<žœ# ¬¨ìIÊ dÊ=«'>à4¥¢ÊœÃÊGæÊ¢Ë[!Ër°dµgÑËÇ p†?ÐË×ËÂhTÂ|™KlÌM<•·P<¼£ëÈ1É ͨ;Í|RÍ$Ì‘ØG:qÂבÂròÍW)ÊâÜIäÜæŒÎ�¢Î8´î¼HðÜòLÏâm1ÖâfŒà<|"7yŠ_1‚³ñÁ;", }–Ÿã-®úØúa„U%Jã¯ÀÌÚCÂDî_›qßsšßY²ß![+þ=hK&àSܱ¥Ë#Ž˜g©àIÃà Î#ŽˆÞnEŽ6§•0�Þ2]Ýâ•4â$~(ƒá…¤âcÂâ9îâ­´t !ã„@ãDÝä2sãË’çIÚZ>ÿ~6@–š0äENb«�äæjú ²€ýäiåÔ­bXÅWþÑʨå%Ãå]N_…acŽßK'Vjh~ÞÎÛá“•>nHp.â%nÂâv.&xî¾ÅçŒá瀾9ÊHè¬`è;Žè6òãÂä+#3ŽÎFnß_L放ä–Îߌ€é_¦éþf�^å^ ã�1#êBêð‘°âŠÃ®z>ì _àÎð�n㞃ãqè_#Ð.ßQ3骱ñžÈ­± =*!d#êœNÅæNŸnËY~L·H-ÿ2/ÿl}1ï“NäDÎ^6�ˆ8¯ïÛÄóháó¹ôtþ4oð ñâ@ì‹aìL�ìê® õÍ>õ9Põ:½6Ô.$xŸñƒÑ¨ø� öÕ�,cbëòˆhòé.èëŽU8òöt÷êÝI("æEqCsŠ÷Àu¥é<7Ÿ4i>ëû^ë±€À1âˆ/AO;‡_ô-~ŠÏøàø /Y“OR?X‰ÿ.¥Òþ2æÜù+ ƒ¦ÁÛ_ßí,áDGtP¾„_¦úQÈú(/3ûI#z´œ¯= R�ÆÁ@ ,d"ˆˆM¤8ÀâÅ‹‘4nâØqàÇ09DŽ$TòÙÉFU`¤IS,˜± Î ÀæÍ›‰tFà9ÒÀOÑ¢[‰‘‘FSIM9ÒÁiQ¥N�:Èê  ñäÚÃkIBBóŒÍ³’ÑY—šˆ¬eÕêTœ6³¦¡›fdŽ�`¥í-[ô¢À�#. LÕðaĉ/f|XÀc;‘%3l¢Îå{5Kó‹±cG¡E;$â®ÈÒW~æx:‡×`‹kT;¥ÿʳ-] r mÛd…ï|1-ì�3ÒHˆòB‡CP¬èWc$Ö›|‡< öä³Û~uÇ”I³fÜœ;{Šthñ£‘”.mú”ñU¬Z¹ò„ V,Y³Ðri-"Úbå-©Ð›«®»ò*I³¾: L0ˆ[ 1 3ÔpÃÇ�l²çº¬ŽÌ6㬸²M47ZtѵÔB˜/©ì¶ë¯¤Ù€ P7Mxû  ƒ®¶áŠŒ°³ã¼JÎ „ ñ!ˆ¦£Ž(ë6bm;×¼C >—È3ï<ôÐ)®|J(*ÅCJ)¦žB01ü²Új¿ÊF¸Ó"ÐÀ7P0ƒºìÉAB DqBÀ+ÿlCFu´Ã#{®13ñD£r;KÅIpñÅÓbœÑ”}«3GÛòÜÍ+ ‚rH#‰C1I�b’9')‹.Ê)Ó\éºRAÊÒ¤-;/¦/ôiÌ2Ù;ó=c×LªMû‹S?:¿*鿱TU‹-·¨Êg\r¤«Á0ôâëPD½ÐQxã] ÒH'­”ÄKwÌ�Ó?mÆÔF ö£SiK7{dõGWq²‘XñœuÕZÃP®Içž”®×΀½Ò·a ù.¼¢Ž…)Ye™]/‡öЄOZúܼï*9÷‹ Nn�´(7=Á=P\rÇ5WP‘5´8D}pW^¦EÏ_7lŽ€ª«ÿ²ºL5Ídk®#ŠÈ°Â[ ²Ë¶6¯¬Q{íȲí¡êÙ¨[‰¬´Œ°ûî|QÔÛ[ØFd°hß^%ygMá÷&Œ9�-Ÿ).œpÜ“ ß�jÌ›³×¡ ‹ÄM£ G¬V1œÆm»Ù˜:H«Œ„<˜–[.R;\kï'°(Òy%GzlrÊ+·¼iâ {Ú_©«¶H¬/*œ®»öšÆÊ6ÛT´{X›m;܆»¹U¢Û¥»ñ6qoô�O¸ïËþÆ+pÖkÓwSÖDCׄoüñÈ¿·rÃ`nš{R:'+ç�.0¢s cJ—�Ó­Luñ“Ÿë` 2dPƒtà`mwÿ»ÜMdw*é�#~ç3á ¯x+ôS\ –<åñáj™ô¢—‰éQo1Ö#ÛÙж=µEðf^ù^ø02>M”ÏnyKßÞxF1¿� p \ g“Äé�XŽë ä$÷? 0s¹ªŒ�ä9£(0 ìÓa(Ä‘LÐa+Êu.¨Á v�ƒlO‰1BŒ”ð„jK YxÈâä…6‹¡ ™GC„ií†njà¼:ô˜í¤0›ä¤aSÄæY‰J4BM©>±¯îÛN#¹¯ú…æ~ÍQÜ]·Eþ}‘�¤Š ¨+Î��;S£ØèÀ›˜®{¨“cëꨑ;â‘ zÜãing?ÿò"‚ ð ‰ÈïS0TÞ }E8IF�’m4Ì%ƒxÆS“œÜ¤'‰Hµ¸…r£Tâ)OùD…õ ŠDk%­K̲9ZÙIré¿]†±—cÌ0͈ 4&0¡»ÌèóÆeJ�)Fì;iN“š|J6QÄMxSxà § ‘ÇÈš³†7ÌÄ:ãNÄSžÂ£g=C:Ä·á|úägùüiJ€ª’•ð›cIŸwÅdÑ–ûëbÿÑE]Ž¢›»hF‰¹Ñv´’¤K&�Ç‘Vµ¤�&J¥IM:°w%ÑÝK}×MΔ¦Ä§‹ÈY5Ž¡óy<õ©%/)TxΓÿžöL*ò É#‡”§•«…1ìFX�9ueöpQ@|k<âU×ëµÿ_~l^ÛQvæ ž‘­ìì4ÛÏ�NÌ ¥]èÉÆ÷ž–]êµ÷ùcmo»ÛJùö¤Ãí•q—{5ç6�jÕe×.xr —J¼-šj�ÅÇÞ®Îp˜Ýªï/¹Ö/IsÀ©9ð!¼(×îœ~ãÇpò— ‹„RäÜŒêÞ4½d‹$ó°ËבôubáÀpv´— u­ÂÙ׌„”[ö÷ $Ѩp®éàÈ„n�Ø:U¦Jàk9$ž!lÇ„T]oVÏ‹A¥�†ç\@ó›7ëuá<¢éºó%›qnVþ™µ=�Cî”:Rõm]}ÒYŸÑÖÁÙu7|=ì¤Çõÿö<´§�lkg˜Û÷¸ç`î�WIÏIj¸¤{ï‹ã ßçx¢Ã„ðp9|âå°x†5ž/Ì×yä 2y Yó”Ù<ç‡é—E�¾†Ï;}GR¯ú µõ~=ì�‹õ³Ð:ž,ÜÓ½»Þ;§²Ó”à;;µ[¶3>A¾¸[>mr¾»ó.½[(ê£ë{&ÁÛ¾é>Å[Æs¼œ+¦‘¼ Q¿Ìk¿ �?ñ‰?z›½«?ޏ?ük ýÛ¤©ë¿ªû?dd§Û믋 °;@Þk;}ú=³kÀŒ31€ô t <3ÿÉÀáÙ@×+€¾C‰¿ì#Ì;ü> ?ÿ. cA šqY?†Èž�ÁÌ¢Aæ#½ÒcÜÜA¨€ý›س“h@"¬½ä:$Ì=%ܽʺB¨ŠÂà›Â*´Ä¬q4ÀH>åS"º ¹.l°è[ŽÃê#Ãë‹„|·Â[Cð³B yC.‹ÃóÛ:Ì;\<ÔCEãÃ>\‰¡?•ÈŽA$ÄŠc= ÃDB?¤½ù°=D*ÀIdÂJtBßCà“ÂáƒÀâÓ§·ûÄäÛ¡“©/”¾TCð(Ã3Œ‰4ôYlCZ?iE–PÁË�à ÙÅ^,€_|¿¢ÆaT‰b,œ@LFet w¢%g|�½ÐJ˜HФ¸aýÿ%\BÔF”HŠœÈ I‘ÔDg¡E L Püˆ»é7ºŠ„ûBÅ0dÇâxGíƒEî3*;˜Æë¼ò#®:àG ñÇçÀC÷²�FbŒ‘Ô¸*–£‰…Ä rHþ+uÁ”ÎøÈ‰´H:ÃÈŒÄÆå!;�üH‘Éo¤Â’äDTBÉäSI»aIÀÓˆ—Ô@uœÉUä¢*yEš“G�äÉðóI} Ê\œC:üG£Ô<|H‚\J¦$ §üŒ/‰JlH‡DDˆÄJ¿ÐJJàJóÊŒÜH±DÍ,Ë�$I– G�¨”ˆ•,øtɦ¶˜Ä˜I¡ÉŽqÅì<œÁ¾|Žž|¿Ÿô2ÿÁ ôëÇÂ,Êì9J½!ÈÝiÌÒxÌŽˆLÉ,Dª´ÌB‰HÑÔJÎü.ÏÔÈ& ÍâMÒ4ÍÇ„YÍ0h͹z͹LG™¬JÛÌËÜŒGÃëMÊøÍ ÎLã ÃLNÄ,È=äÃmÓç$ <Ô4ó˜ÎÅÈ Õ ‡l¤«ü•ëÐÍÜNŒÄ¯KªQK×¹ñ,KòDMTͶdÍ·tM3”ËØ¤90„Ï»¬IÜDÃÝTCûœEœƒCó#N]ë<|ÖE�mÝÖkÚŽN!�DÅl-G- H�IýÕ6°Ô°ÁT?ÓÔýàÔ¶ðÔQUó0ÕSýÊT�RdË»pÕó!¡Xõ�i³Õ[}Ž\Å^íÕÔP×6ÖIÖì)ÖÿcU‰dE”eÝ�qu iEj]¶Ï¸VlÝVn½oí”pmŒŽíØ;WêH×_e×pWl€W®�WV ×‹{ URÕWD@U­TU‹(ÐVE”Wõ<ì’ÕÊiV„­U\í']mØðUu•Ø6 X´±ØO@Ö!QÖ–‹ FiÙ»øØ Ùì Ùg5YmíVßøÖ•e ³%‰—ŽHÝ6ˆ¥Y›ÅYžÐYžR²øÙZ}%Ú�4Ú@ÚÓØÍà�‚‰ƒ�Ú©uªªmX¬ýU­åZU2֝Ũ°Õرʼn²ÅV�Íž¤á.¦“1YÛìW·�‚kJ!ô˜ÛÅàÜÍ]|Ø]ÞMÄvø]ÿàí•n^âíã=^¾U½Lm‘ÜÍ]�^àé�Þ"!Üã=^¡E„æÅ]Í„Þß�Þé-Ðw_òMïmyH_õý5ò%_x_ø•š¨ýƒÊ½õU_«=€jØ_þ%^âe`a%›m(`öÚó}oX`¾^ã=Ž`¦É ®`m¸` N]Õe]�p]´�]·5 Ú%[ÛMŒíåÞí]Ø;ßû�ÿ^î˜a–�a[^78áçõ^ð•ÞêýÙ¦a>áîåáßö}‡yXây ¾_y`ß$†ßøµ™ùÍ!R‚b(ÞUþíß`žX6àF`ï½ßÚ`àÿvàŽà q” ¶` ¾` æ.N† 6Yô¸¤ŽŠ >áÞÝó}âôuáb!v¦3‰Ãn T¨äóíap({ØdNfd!>a¦ÈKîá.Þß$Vb&vâ3†ââßS¦â÷•ߨÍ!DÖbyàâR~ánc.J%ãö\Ï­å4Vcoˆá6†à7n”8¦à9¦cDQÝ#¸ã<öŠqª>®œ?î�@€AÞÞBƇC^åD&]öä^Ž–¸If…JF…QßR®Nîdndåe#–çR>e&nb¨åômeSžbX–šI¡er¶e\îb]æevðåÿIæmfc%æF0æcfãd^fFiælxfm¨cÕ¹ã'ÍÙ9 Âfªaœä@þææ çq†^á]dNÞ§‹äv~çxžÞy®çMŽáìÕçmàgèÅäy>eómè‚îWFh*VèIy‚¾e«�çˆæeŠn‹ÆèOHà!áhdNæ nf’6éÕåà”^ihiwÊæÚ"ánd &äB¾éà�’sÞivµÙ?ûiKîg¡.e¢¶£Z¤Vêè%åN⧆^-6èjxå„¶™«Æj¨Öê†åê/öj²ùe`k²³öè6Në8&i’–f”~R¸–k™ž ˜¾‰»– šÖݽæëÿvÈiÿ�až¦)ôðéí5 6léj¢^l}mì‰ êåŽìö�là­l©>èö…e°êÍ^ˆ¬Î_Ðö_‰þê°ÆèÓ¶�Ô¾Þd>Ö–cׯ`ØvkÙ^iÚææ—öc»¾ëÝÆ]›ömà.^À¶T+nv>nJ.쥆ì.Nlç6Uè¦é‡¦–lDÉjËÆìªÖìïïÎï\m06ïÒFoïU`c>ëÕ–‘Žï9žoÖ}kû¾o k¨ÝnŽd‹þo¾F¶gppNi¦"kˆd¨©$Oòpæqô•‡éÕŒýõ_{+OòþÞÞMî‡ëøŽSßyˆ2Œ›ž^ÿïâ€^âÉÓö^ȉópX Íóñ=^-Ès©á]Oèsx¦l(Ž´HãèÄÆgÜÎmDg!f&gòëry!r#/6®XòÞþÝô}ò½ˆrâ�ò*¿r$Ïò-WðÇör�ó0ó2WåCFó­.å5Ÿ‡6g�7‡^9‡:ß ;<×s›ás?ïlA÷,B'jC·‰D_vâYt2nôC~ôæò'r ªôq vLç]@çtiðôáu¶r Àò¼n^-ß].?õ/? ;gõx0óq†õÏ–õ5¯õϸuàÍõ9W‰:·ó_ׂ=ßÝ>÷„?¿î@/öc¯çd·-fxxAjÿ~çuÿÝb‚¿¾^r'w׋&ò” ºø¦xSßté…òj�ò¢6ÞP/÷Q?÷ÜMw|¨øv˜Þv†w'óxwõxNsþ�u|ï±~˜Ñû÷w€ô<ׂm/øƒ×t(>åBoäf=tˆ¿z ‘ø6ù§·øbÏøãÝx+ïø ùx y‘'ùR§ønOùN_ùOoy*wQ¯RWwSÿ^éÍù�oõ�žwéúýúÔpsŒ6z�Dz¥Ïó¦v@¿_©Gvª/*«ÇzË¿Ýíµh®?ß‹{ã{ { 1ûíAû@Q{¼g{„÷vpïqgr7÷lÈüµ�g¾_už—÷WüÿXWó{/|[?|XI|^ßÅgzLwúÎŽ|†Ÿ|zªüË�~©ìÌ/àµçrõí|�Öx±}Û.5Ò_Ó¯ ©Á«Í_}·ÿv¸w¹y‘¦ýÔ·ýTwwÜ÷û3çýz÷ý€.cˆ4*h0„Jkøî¡½ˆûQÔbÆŒ=qDÕîãGy"5‘|hò�D‰V²Làò%€˜2gÒ¬ió&Μ:wòìéó'PlB¹-ºíhFTJ—‚)OԨݦR¥hµŸ„¬ZpíŠsØ¢F�’íaö,™´jÓ°má-\:rç.eÚT¸¼ ¥U«FµÛDŠìkÍfø°XnÛ’ÿ* 2/¸H’ŸQ>yr^¼Ì>6;î ùèÐ .0!£ÔªK4XðtÖ{M¦ŒhÕ¢�º9zòèØ)IM–QÖfÙò¥K Ê—3oîü9O¡Ø+Fбnã�"£JýÛí*E­[»rý61Ù²gͪ]Û–-ܸsåb÷­òÞ¾÷Ì®ða†¡Ç˜}�å%Y$”=3ÜC˜iÆYg‚šh§±›j«•æÚk–6DµÝv‘nuÔp%YV›=Æ­„\rÐÉ8#�5:'udhW;Nq•wß�'^Vä•wX ä˜Þ6ë±×ïÁ_óчÝoxéÕ�~Tñç€xÿ]vŽA† ‚ ¾ã`<›ù¡„‚Û…§e˜k6dø9bJ#æV"F¼ØãH*žÄ¢‹À˜€�‘J:©¤8¢g>õÝõÔ�A‚‡‘F`ž’—¦çdPF)%•UZ©é]~òå——¶ FXV (ÖbdÚΙ“UÆ ›n¦r,²ö™�¥axgžò¹,ˆÄZ‰„Šb¢Â­Xœ‹�R:.¹åúd)¯˜ÂŠ(§Üy:d¨F’ºä©Nª*e­ZIǺˆÊÚåT_â*�®ÙŒ™i™¢9ìpÅn†l²-Ûg³ =›a´®MÛgµ, Jh¡'f)OpÃ1.Œæª¼2¥/Ùñÿ2ÌÈ<ó\ÑØ,ç Á³s&=ûLÐAo04Ñ}ôI+½ÓMWñ4Ô%ÖQÇùÚk�p9æ‰h¾y�{n è¡S2º5¥ïr:êõ¨¾ºÛ­g *˱Ë�Ë0¿<3ÍrÙ Î:óìsÏhMtÑG­´Ò˜c^óÍñ<ôS[}uÖXç½õ×`;™8Ùzrx¶ðÒI×öÛqÃ-úéÓMYà©á}ýÞŒ÷ñwûŽgi‡ï¬ÿ¸Øò÷áøf Çñ ETÊ»Üæ8ç¹Î…Nt¤+]’’4» R°e.±Ýípg€šÝLN¾ƒð‚'<â ÍxÇCÞ8‚æ9zÏ“žÕªg½ëeÏka[Õ¼÷=ì�Äù2`¾ó¥}ë{FýÞ—·ø1Ž~õKÍýÁý!Žþ è‰ð€ ÔÜØ@SŒŽ¥³FÁRÁ5²‘vÄ 7¨»Rèƒ!ÌDI¸ …)< ™çÂRÍjÄ8$"¯·‰Æâ†!èž >´ý0ˆC D�¸¾$æE‘LôÛ�žE;A+úãßâä‡E-rÑH*üb"†1’ñÿ�hLcs©KŸÔÎvqä ï<ˆÃÝ1�$ä£UÈ ò0¬"IÃ:’‘œdÐ*i´Ö]2“R8"'ÁáI'ùωOŒbp‚CKT^€¬$ ¨!ÏyÂR–´,ãÓ¸€]ò³Ÿ5éeÌ4ÌÞ ówÀ3&ñ�‰Be²™ÏœG4©HFV3‡‘”$ÃG@KÑ›àlŸõFNù™³~èL§&ÖiEUºS€­$Ï<éùE{ŽŸÄ¥?sšS Úá—V"èhŠ9Âcš0™€lè Qb°†‘"í*/Z»õP›Æëf&Q%JFŒs=þ»ä2GÊ ¡4¥c<ãÛé¸wŠ/ž1ÿD=ÃHK´Þ4‚:½+?EE$ ì«~ýkÅò‰ÁV� ECYèÐBB3¢SÔßSQ‰‹ÉRVOv›˜U�&*o¢ê¯µk° 4°•'Mç\éÊÇUºžFzë DÕ´¦¥­úÄ+nÛ¨W"õճŬ@[X¢ϨÊ[æb§·ÔÇ.²ü£le9tÙeeÖh›Íª“|[ ЖF´$ - M;VÕ”µ¶g\mK!÷Ò®ÀV¶³]�yë*ÁÜÒw‚»Oo= Üw°²®ƒ ÛB*õÀ…ƒ¬‚ÍÂ`è>ønÔ•°ñ(œ> {ÃÑð—Ùá{8Ä(�¯5øhâ4¢8*&‹]L×ÛθÍåªqVnì×ýî¸Ç?r��‹T"x¹6œs×`KÂO¥Œ>*¶”Î(Ú6̼-sÙ˨1ZÅüÖ»¦ouïlÕl[œº¹ÔæêŠR}É+°ºÕG\*‚¤H,¢JU²œÜ伡kDƆ5 Q dÊXÆKò¡ØÆî ²«¡'*–h'©~¶.yÉWGtbÚ¸6¶kâÍV·šË–%+Âÿ-n&mæ>·©Ó­îH¡ZÕCä6«©ÍXKfÖ¬5”n�kBèÚ¼öõ¯Ý—a�ŽØÆ.v²û²lý5['Ðv·´ã&oDZÛ×®‰¨à}oçÜâ÷ºC.rJµ;Úï†÷ÄIïHØÛqøn�¾qÝï\ À8Á ~ð„+›CÌÖ�³q󥜷8Æ�¤qŽ{üã#:Ô¡SòU£|}K…MËÝôrµÄ<×»>d¯k~spœ:?v›¬šúl'C—¸Õ«½,‹_œ&¢º;Þ»rntG½ï~ïIÉó!øÁkUWÏñ@hm¯|‡qßüþ:1Âð±—ý’ú²’ÚSÃvÿ]í¶–§ÒR�žm»ç½ôäÙ»¹ÿ®úÕ'=Ï<áámøˆîWñë±uã÷=s°×Üæ'{·xùùdž›Pçßúùø„~Y¾¶øbbúéõ`=öW/*Ø ž%­F•!ÁŽx�Ø-Œ_ ã¯ÞûL¬ìAx܆?dÄnÇ?Lòcº|¸ ªýe„¾tHõ•žõeŸöÝöqŸ÷±ø5Vä�ß„ƒNàÖ¥…,íÅ^¨_ïùŸ°½_Ä•ì ýMÕ�ÜŸaäß<íß[  ´  >Ÿ6D ¢ÞÞàÈ% ì-à4 �=àh°ÆRàâÁ\a`Ch`Íq`yÿ Ƈ* fˆ f Ê“ F º` Ò�6´ ŠJâ ¦›ú ¯AàJ`’ÁîìJƒúž“õ ¹9!ÜÈŸ\Œ`#Øv´�NxžðQÉr¡‚ažž –¡#¶ÙvßJ|Ÿ“„’ÆB´a8”• AÚÌÖáL2‰Ò�b]bNÀ÷åC«¢ &"é-¢‘Œá#îbnEb>¤a%:à~i"'ÊÐ'FC(Ò^i�"dä!üíaZÉ*–` rÞ ¾U,΢“paÒ�"âbõ5"/Ž£©u…Và‹ª‘ž¬ŸiœÆ:®ŸÝ”•"•ˆ>½„|ÿ>æ#ª°ä¸bsøQ¤@¾›‘£Aä rÅ9JI:®Ï;²#DŠÝ�Èãõè¢LØã`ä£>: ?ò†?Îì ¤HŽä-.ä{4$ݦ—GZc�„$Iö$BšcV #”¨#‡°¤QD<¢Ô‹Å$ÌdM~ÀM:ν™¼ø¤U’#PJ€P¶QºÆQeR¦ÓRŠãEºÄ=ÖdTºÉT’ O^¥[–aVn¥Zt¥A|¥Q†epŒåÞý“Yf$Zr$­å¸´å[¦ŠÊù�ª ŠJÚ%;â%Iè%ßÍÄ£°XZn†`’\U&gbb>Üb:ÿIc:fïÍ£nHfêÑDe¾—u€k¾ffN av&mFÝgB[h®Çh’&À™¦F æõ©&Œ°Xk¾¦kƦ¤Ìfm.gÈÝæ³åæYt"oúùfF'_"q’�q'Q%y0§xæ ‘$¦ ¡J'XÞIu^O‰`§pj'krgw"'»mæxæg©9gª�§“¤çú¬g†´gÞ¼']1åjÎVq§}Úˆrê'„¶ñT«´ŠÿàŒÝ(l(‡r#”HƒF¨ˆŽ¨¤Ph…ÆÇ…ÊI†^‡v(7$‰Æ¨ŒRЉžè[¤(…¬hÞ´è†z(ŒÎ(�ésð‘�Â…ÿÄQ3i(�ú¦(© ©“>©OðÑ£X¨ü é )i‹2iŒA)—v©MH)ŒP)ãX© a©‹rá�z©šB)˜"‡˜ö ™B�™n¨>¥éšÞ)�¶éK°Ø‘jP3d�ªá)¡©žºŸV©Ÿ  j�*¤Êè¡&‹Åbœ>O£:j“F*§æç¤V*÷]êdª¦ÎW§žªx~ê{Yꢺ©–ê>¡ª¬:éô}ã¬Þêê!ù,*¾ÍÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹hÜÈQã‚� ;ˆ ¤É“%1ª\ɲ¥Ë—0cÊœI³fÆŽ8A†)¥Ï6ƒ J´¨Ñ£H‰âÌ©sÏž?O&�JµªÕ«X³:\Ú±©Ó§Q¥jK¶¬Ù³hråèõi‡°&ÓÊ�K·®]—k7¶ èÝ¿€ ¦›×cS·}ý^̸±ã 8¹Iž¼­²eÄ}kÞ̹óÃÈ“%[¾Ì®çÓ¨S;ÖÆºuhÑ£· ™M[ŠíÛ>UëÞÍ[+¶ßÀ[»~[6íÙ·oÛYÎ? ñö6‚¯7úvï=þ¬ñÌr̫LJ,ÏÈûœì3ʳL1ÌËLóÑãYwÝk4í´µíèÎÔTÿ|rÊ+·ürÌ#í5tJcçôÓÖJMõÔVCŒõÄ.WÌèÅq}-·n …-íšc7 µÙg§ÿMïÊ+¿¼5�wJs'~ZÝÖÝŒOÞìòÙhû=àø îvᮘâ ?ƸpŽC.¹Â”‡cùå˜kN4;œ{úìŽ�>7€š^öä”û\ÍïÀcî�ëuÆn4Ev‡VíÌ¿d;k¥ç õ8ÔWŸºïÀÿ.<ñ„~üA^e#þøÉS›5è§ŸÀúìÛüû=¿4îxKomõÖ÷~röÚ·®yñÞëBÂ7>ñ•6£IŸúØ·>÷Á�y‚¶!† �­È`+Ö%Žâàƒ $1ÞAÂw¯(La²ž)1Ä-èéPÁ f02Øð†=È¡iÀÃú�‡Sráÿ¿AñM°‚b¸ 7¨®Š„!a O˜B®ðN쓈ÍrÒ�Z⥈IÈ_ócÃ$æ�™1œH�–af$C–¨(Ö‘–(tÔæIOZ³!#ùãv† ÿMqÓ›ßDX8…YLr ÌœFDgeÔÉD…µóƒÑ|<û!OzÎÓž xH>µ´Ï~ÂçŸ æ@“eÐTväœÙ‰ CuöÐX¾sšñ¼“E/jO�ŠDŸÛñè{@êM‘†“¤%=èIšÒѬ”�ˆrg 'ZQ‹bÔ¦ÀéqtšžþÒ§ÃLç8—±º%q]£B·qT‡&¢²”(L)*Ó™>Õ!ERG?¦#¨9щ…Ī0µºÕ t=_�[XÍgTH6t]-�(SÛêÔšÂõ¦Í)]Ed×»Š#¯à)­úêWIÅp‚–Q úÆdJ\qÄ@jÏ�4Ø*w൰­£l‹AÛöÿ´'¸Í-vË[øö·Ÿ]¥e�ˆDS÷¸:³¬8xÆ3bQâ¹Ð%å ¦K]G™ãº,Rp“™@Ñ’6‘¦-�Tk#ֲʵ°}­lëHÛbØ–=¹Õ-owû[à¦G¸Ê$®Ž‹Ü�)—g&°€}–²”I—ºÓµ.v¿§Ýûr7´ÞU‘)o5ªÓÊð@ä ƒyÛ�Þô®·„í}/+â‹ÛùÒ·¾Ø.a‡«_þ7¹–°€Là7âÀV°9²K$�•›¤œ0•Jeáñ²gµlm»Ò«Þ¿#Äï妉)€â;xÅù%®‹Mã»úlÆ4¾š�׋àßéº;fp�¯üãA’2ÿY�T‘S{äò&ù¼Kf²“ŸL[q“DÉòqQY¬ewÙ‰_s� ¼^×é˜ÇCtq€ü18�SΚQh2¼awÝõµÒµ4fÛgýÙA�fó ³\\Cûײ‰žñ¢SÖhÍ=ZÍ‘Võ¤Ý\i=>ŠÂ˜–›9}g·ëÓõ¨Ù[j�ZAÉ�´5ý`VWpˇî`¬,fFËÖÑg¾î|W¦?r“ÒËä)%ea꼆حPò>�­lRÃσ4­¤=jc™•Ä–ÎVfÌÚ^µÜ­X%sŸû‹oöõº#5g ×YÃÅîpl�Ü^|QߌⷿǪ_1÷…„Ï€^páEãýðO]êD(K­¹Íø�Ýff�žÚÓðü¸‡wJÒ{$,áG ÄG'ø‡|�¡|\Ç|Má|ÏZ•Ñ&ÔW}Hõ ”}Û§}Þ÷}±r€äW~€X�~Ö²~L&<îï'”C%d¯ƒú§üGþg0&(€7B€­`€á—€ì°€À¶C¨X@¸ x�±`}øAØ�Ø}à'|#8~æ€(,*˜^,ˆ9.ø‚0H52HB4X|Æwƒ�‘ƒÕA:3ÔxƒTHm„B(|ë•,F¨s�‘„豄 Ñ„(õoQx�T¸�²å3Yÿ[]]è_x~a(o÷Ze8g P3ÑÔ† ø†¸&rø;X.V•Cy˜C$,©Ó‡´ò‡š!ˆÔAˆaˆÐ7V‰ˆ�fU…8PpŽ˜…Äâ3ÂCJ­Fê72@·‰+CJŸƒ¡84n˜¥({A{�S‡k²Š=�Œ¯ø*±([~x|G8¶¸¸º(VÕ…\"…S˜� $Œ'óˆÅx2Çø1ɨCËÈ0ÍèŒÞ�ÖŠõG�£h�1G#aÅ¡�t¤ä�àX€âH9 W� ¨ aØ‘Ž¿9͇Ï玓ÁM½8}‹øAö1�¸:³}è’Œ³P“ÿØa–ÿäŒ)†í¢†ÓØ65HŠ 9qõo"Ö&è†.É%zx‘g“‘ ¹‘Y%I.å9Ü„•ƒÔŽ&ˆ’ñ(…+Œ*·:~“Ú7“L™C59 <KgG€ƒYó�>y�@Y�pxE9VGÉ%Iy.K9€®h‘›2Ž­§‘çHT9�Üø8y“•�¹•$ù|]9H)9�¿X�cI–Vc–ó€–‚ÙkÙ–rô–Â#—èB—S³†ï ŠE(”†÷{¹jÛЗJò—˜?8˜Aè”T•¯)R‰‹é„�©•_„œ7DJ"V™_t™aÙ’œù3ž š»)š5IšPdš˜ƒšç¢šáÀš®ÿiƒ×ˆ³¹ï…”¼†0ºi#MY˜iuˆ ˆgQœ‡x7W™É©ŸËù1Í €^©$•uW-%�Ó©�˜#“çB“Ù92nÙdp¹2Þùà)žœyiç¶y#¸Ùžaðž†b˜KuæHŸfaŸ»h{õ36�é¢ë‰.ÿy~z#êDº™ 1Õ¹ i‰�lé ¥ ¡§9JS¡?98ZžG��DCmÒ#$|ÀWz¨@,�Ó^x°¥ó|òuô"j%j)ä(¼å…±ÎÓJS�SH=B¥r |T§DP=@Jó�‰ÌµÄ€¨:ÊV¨b*[-Ó2}°¨ŒÿJJÄ3uI•Bí1ìñEÀg(îB5)-£B y¦ä–NŠMS.Qj"S*§VŠ¥y£¥\*^Úv`:/‡ªVdS ª'‘¦8±¦:Ѧ±ñ¦b§s*§vzAxª§òÁ§Ì•zw2†j¨ë•¨ú¨�ú1�:2‘*B“ŠB•*—zC™Z(›:5�ú~ŸšGÁÉ«FÒOj0© !«J¥­+YJ[[Š]ú{_êwajcZ¦w«&᫬òã¦y§&r¬Èš¬Ëú1{Úv}Ú3–3¨ÓZ¨Õj­Øº¨ŽšA�ºšôç­kE©ìa©¬€©¿§©=‰®öâ©úªíº[±ÿ‰¥ÊV9-6"¥2§÷Ú)Úb,°Ê¯²ê¯´ °¶*°Ò”«lµ«6‹Ë ûÂ:ÄFÆ ±¿—¬wRÛ¬Û§Ðê3ˆê±²­0²áY²Äð­ý®Ü0®6T®îp®á�®Ñ°®¶ªQû98 ¯¦ÊxlÂ%>« @[zÙ2´EÛ¯›ð¯s«/C°PKh:µQµ pµ–‘µ:´µ\뵋0kl ³£ ±gË´ud­Ýð±}À¶n ·q{²àš²âº²äÚ²æú²{³ê:³ìŠî:9;›PЏªú³¬Ê¸±2´Ïð¸G¹I;¹®[¹ºj°%¡¹›ë^ÿṕº9$ºKº`kºb‹ºî¢º¬Ûº›¨²K»ÜJ²%+·tk·d€·zË·~[�Ç«q;4‚Œ\B…‰²¸zç3ÒK½0«¨[«„š½üb¹ÜÞ‹,qŸÜ 4¤D¾=À3\K§›¾Ü*׳£<ëÕº¡–,û(Ùú£Y¿g³=nCF=Ç»wë»y ¼þK¼œ±‡ =¯qJ¼Ä¤d¥Œ()ì7 ¬¯±úÀHÁJ;Áˆ«¸ë½¼¢s…0�#,n[5'K¥{¬Åӹ¿ÓÂ…š,0¼2 ²çRà “:8ü::ly,» .»œ*¼}+ÄÕXÄMÿª,KÌÄãĘ(nl5S\ û ¹’°[¬½O{ÁÆ&)cŒ.eü*g\9£Æ&|Å(¬? ÇÕ ÇÊFÇ´Ãk2Ãz¬·TÓÇuòÇ›ÆÃûëÃýkÈÿ›�ŠlGpÙ˜½Ö©{2ƒê3¶+<ûªCxëDÝJ Âã¨}CÅñu¡$F:ÂYS†µçÐ$¢3c[Û¦zÃz%´¯ûª#�؉Ô0ÜÄ K6Ö°›IŽÂYÔV…tzã@ÄMƒ„w'ü�Z´ÄÔ·w›òv3ÿèØu²ŠT8AÙÚ7˜�Ù¨<2¹­~óÙ˜Ú94ÚTÚ§�Ú6´Ú5t‡®-"•±Ý³í̵2·ýZí}p�°^¾½¥À�…ÂMÜÃmÜ6–ܾæ(ˆ‡ÝÎ-FÐ-ÝÃMÝüâ(×½x–¡ÝÓÇ݆âÝlÞt"Þà “mÞŸ‹ÞéíšÝ¾œ­£?߀#ß=@ßâ`ߘƒÚþ Ú±ÁÚ¾¤C:òßÎþÈ®0N Nu .[ Žþ�.á^`>v¾uÏÍwÔãáÔâö âû�ÝEeⱀⅢâ­Éâìà≹Ð1.ãÛ95nã¯tUþÞp Ú[ÿ*Ú>LÚöK÷]äùòè�K>PM¾Ì�Ì ´í ¶ÍŒLVè»Íru”å:RH]^ÜrtÜa^'U–á¶áaÔá"4ÝCSÝ0âÜ%çtîvŽÈ-nãMâ �J9Ä",„žãSgè%‹èx è‚\(Œþ¶Í>äø}n“ÎßaTéátéN-mâÐ'§0†šì3¨ÇÍà ^êbÔ‰:óå)³êtÒêd~am¥²N ´Þ ™„ë„¥ëL‡ìzöÝ4«ç(zÃÞ&Æ+Ÿ^ n5<¾2>äB8D^sÙÞÚÛîß–nb²máîÌã¾.åþéÊx¡^u£¾î"bêgøî©^áÖÿš,ô®Ôv綾ïûÞïoNâ•ð¦7è¿âì/n Ï%Pó§� ¨æN/�}2¬¹2íuæðy6S�/íåxd�ñIžCÜžUtÂ[J£4mrÒ°H9%Ÿ^íÕ^èn/ó¼ò¾Íîaåˆu}¢~Ìì€f5 íÌø^(¥-ïì$p^âJ¼Ý_(Õ[ÄýºüN+oI/ ÖÂôMÿôóõ“õÞPõî›ö›“[ïx^oC…ö{5ö`]ö¬qöj-úá@­öæö:ž2qßÛ,Ï …d÷êÒRyïë{]}ÿÿÈ�ïƒ?ó´bø>¿ @o(�ÿZ�ÿÝÉ2ùUQù6zù±ÿÒôNoòç®ãžMTO[V?¢Ò(Kå_ \úÝ´ñ òßuBö®ß°¿Di6´Ïlm&PÐ`#„Õ¾cØÏCˆ9$NìQÑbŒåmäøÍ#�5ìV²ßIv)Í­ÐÒå˜1¹Í¤yÄæMT9uºãÎ'1 AKí–Ò(»I•bÃF“Û6¨7cMÝÉsÜUY©mmø®äÑ”vì ";ÀY´iÕ®eÛ¶-S¸Ø´Í¥;ÄîÝ0yõ¶ãÛ×ãßoŒÎZ˜@W†Ñ/6ØØqІÞ$£lÑ"OÌî|n™¡do”‹‘!]Ú4é©©c‰cÝÚrʼnȘm”Âÿmºt±ìæ­Wo+àÁ3÷äNÚqäˆß‰Í‘£ã"V³WݺìÙcK|Ý#£Fçòþ‚Ä!’¤I”*YºlS¦Sn7qểysP¡D‹‚Uº´)M¨¶‘Šªú¬ÂJ+®Î‹±Ê2Ë-#”€¸˜Êm®»ðò-Œ¾ü,°Á3,+å[¬¸p óìÐDën8ÍŠ[±EÊN³‘ Õ¦jmGMññGÚjKé6 .Ô†·Þ6 N¸áPD.9Ę£,aq_)HÛê' xà™´†[Ʉާa>ó¦ŠñÄ8cÄ8îxÌ¥Eþ&è’MFÙ•3Ã:èbž™æ›qÎy›�Ãè™/Í÷ ¤¡‹F:é׿nzuò̋ڛ²ÕK›r§¸6ÍëÁÆAl…ȮΨ³3x<€µÛ~Ÿ¸{P^a» ÂÛä½ûæûo¨¸Â¿9Ü ÄãYü„Æ�/ršœÛ*g9„-)xœÃ�çh:úŒîbý;ÝwRǧµb¯‹ffGÿ»ÆØîŸË�ÍvÇ»Ëùn*>ÓÜðpP´=®|><`úÖ·�öä}‹Ÿüè· ûE€p 3œcú÷¿*q€* Áˆ9jŽ�ŒØ_S1 F‚‚óØÅ‘A ä�ƒ®Z�@B�ÈìÊ)¡Nػߵ#x.„á–dx 2mNá©fŽÒÉz¥Á …6�ŒM‡G4[Ó¶Äó9±†ìóÉݤ‘·*ú >€#�à´ˆ?.êÏ‹¥Sã†tŽBe< Ö8e,ÎŒÊOkZÓçºÃ©8Î1u ™G²<ÿºe0‚Ñÿ(BB–ð�)Lä"‡ç'ãÉ0’t›ä5ŸÖ­Bo‡Ò»õh²IÒtxB¥ D)OR²#|Á< Û˜È�†An«„b+Ý÷Jø�E~ó›eýjy¿Väoù¢/ÙA$‚ “-ÄDè}ƒÌÍ(S?Ì<‰3_M J“š³Pë²¹Ámr33Þ!8SÈq¢�g+ÜçÏ\ˆÎª3y«¤$Ôâ=vT­žå>É OEòs{¡ìÞ(‘(>1Ô|NIèB%ÙÐ�N4±¤(¡,J[nqy@GøKÇ…U¤k‰‰À¨Ú;½ J]ÉÌÊt–ÉÒÏ œ*¤LQWÍ;º“ÿ�'Ë©NyÂSÚ d ÊñGgoÆІ–SžÊ*Zɳ¤ÚãfŠ]§ ›çTKòpªšbö´JÄØ Ô”jC‹AS©³²­®ÌÛ#ÏE'+£¹¤+M·±…t¯ƒ‰_éؼ–8„%€aWÊR„W¼Šel Ùp^ô@½ë�iMÉ3Yo¼¥Å, 5ËYÏÚ,´¢Ýiëæ“Ó*&µ« VkÛyCØzU¶V³çL¬ŠUíáVÁºë){;V3ªò¬Q€Z%c\;q*¹™›«cœûÜèêuºhékƒK*TßhWO)-¬BËLñŽ7XåÍzÓ»^õ¶×š6}˜6�0_ºÖW³ÿÁ¯?>»_Œ6ˆ¦ jõc#ÉÀM…gn£ŠÉÙÂçÁS"W‹8á�êÕ·d…±BÕÇP{Ø –�ˆO£\�šØ©Ï�GŠ-¼bê.Àºçksvó4XwׯßÅqŽi@Þ ÒÇçr�KÓ!¿÷¦ ‘o“ŠS_Ç,ÙM~ò~¥l[*ãÀÊDÁ²ÍX»TIryU½d&Å\[O–ÙŸ]¥u)+Ì[±´¬oÞ0}; QˆÑù&v6 ž™«gxòÙÏÀôYZüׄH.Œw‰ÂÒ~8úÑ;Ž´y']i@™vÄc‘qzdOsÔöÝ,b:ëdýBùÔžÜL€£1`WKSCXŸÿ¬ŸU©2˜ªcFµ®ÿ½ð‰•lÖ°pã, SECÙ6aviœ]âÆœØt ’@ÉM.Ý1^ûºÙƒŒQÔíE¼Ž†´o$}îJ«›Ý’Ý4eá�TÍ» ¢&u¾MÝß)÷»Ê¾ru²Ì›�Ü�•œð—mýÃ둹ŸŸgÄ=ñ —Ø7öq2¾ñ#tœ4ogs÷Œb°˜üä*¦ÛÚæb:©FÁÃát¦îI\-⦖d9|„Ö‹g¨á63´�X T£RŽ éBè(Ç!“®|”gYɈP‹[ïò£œ8‡•>IVšÀ•“‡7.+2pPm%h•dKkÊ0�ÿý· È&D þÒ<ªÁø]!|ö¼)*¶÷àiNÔa”—a_r¥�o¯v´S®\$ã°hàvY$Dxjùµû4Q<ãÏêxÖ#+òW™üˆ*oùg`~—š—Ø¥—úqšÑ›§‰ Ó³ ÔCÕC+ã�GA6¹> �=¸ ½õ²=O½„X´Ý;‰ÞË+ȱ6˜¸¢› >"0>¾ø‹ 嫿ó¼çŽà�¼%£¾­°>v0¹ì›.îs±ï#–ðsªñc©ò{A¿.Q?k?h<ýy<ùÉûÊC üË¿áÉ<Í{‡þ³ ¹™ÀQŠž<À!HÀäŒÖó4ŠÿØ£�Ù;ŸÚk…Û{– ¬ݳÞÃß A>y¾#0Aü�XAFhÁÔ•ÌŒŒBͲAjÀAL í©¤ª\’ „§!d¦"ü—ñQBªbB'ä Q›?, „È›û³<ýCœ-ìÂŒøB0ÄŒ«C€"É2C4äˆÕkÀT“ôÈÁ’£Àxa³9¬ÃUlïêÀ~øÀ?Ä™(”á+>�9>DTÄçj¾FÄŒG|’é+ˆê«: ÜÁí3(Ôð‹·Í?i!¿òÅÇ!ż­ÅkÂ÷{BŸHE)´CVtE+Ä?*ÑBþã¤H5t@×+Æ7ŒCŽT/ ,ª© ÉêØCèC“ÁŠDBÌÆçLFˆN@ÄŠq!ë„DÅ€rÜÅyrLÈ#É„Ê,ñ$O£< ¤DÏÎTÏÏÄG÷.ø …OˆQŽùtŽú”"‹d×ìÊýÔÅ¢ KËÛ<ËܬHÖ¼HbŒ@ýÍd4£eüÈf¤K{°K¼\‹ Ý� %‚ õP<Qÿš¼NÈNÿ (åAïdQð¬LDó …PÍtzì!u ÐÔQ~äÑ÷¤IÓlˆ í�°OÄ8Rý4%•&µ¢=ÃEË]K+mKà|KˆËҚ˭ˑ¼Ë’Ó ±Ð =ÓÁHÓ„6eE7…S•Sì³ÄÈ!—L<¡mPA‘=­"!’¥”ô\¿™TærÏÑôQÐèi�ÖE݈!=¶)5RüäÊHMþüÊ8­TYrR5K�?íÍ ÄÒ�ÔRáäRâ4N EN YU2mUOyÎ �ND”Õá Ñ'�X[]ÒsÔÕáÕŸôÕ;Ž`½LÄ(šb½�c�”ÿd]BÕGBÍgET“™VjÍ‘ÔtÔÖÜÖ×TÈ$íÏ[×¶²ÍrÅMyÐÍ)åÍNõM·t×Î;ÌCS�PT�PK±×œ)SW…N~�UǘU‘š�%ØÅÔÎ9ý»³»•Óšé ±FiAƒ”¤¨6[€,¥ V(Û߈˅žr˜¢ñ“²}[V°�È@Lj†Y|‹OÒ×|iýñŠ º¸G]éžp‹�5ùŸ(¹H€Ü`³›ØÊÝÛB•ÍQ:P7éùT3‹¨—œhZ�­�%;LF)Ѽ�Gú×}ÝIcp;Ú­Ý›Z¶©Zƒ¹Z¾ÈÚ«ØZÿåëZ£P °Á±�‰·=[M۵哶Õ¸-[¹Í ºm »=HЩ½-*¾�ØžÜðܹ \Þí]w@Ü)UÜ“`\Ç…ÜÁ5£É­\î½Ü)‚Ðp1Îu Ï-¦Ð%T ]p0]ÍBÝÔeÌÕe]z]Ø�´Ù­]Ú½]ÜÕÝ‚)_ßàõ;áM â-^˜8^nHÞ¼ØÞQm^üx^¢ˆÞ¸­ˆ¹•˺½ÛìíÎ¥Pé[†øÛÅ \˜x_Aå€ÂÅÚóu§Ä•ŒÅýŸö�\øµ Êí¤f�?d³_õÀ_ó‹�ý}±þ=”Ñ%]NÝN¶VàˆÝv`žZ Æ ÿ­Ý ®¥TþøZÛv%[³ a´Uµõ&¶•·�ÞéE…ê5ˆë½ÏŽáå™aïýÒõ½áðÍáñ½Ñ6_ôí õíö•€Ç5âŠ_%ž+(lâž½ßü}‹ã5˜*Ö ÎbÒ¤É6à.n]0c–ràž.#¡“$Nâ4@ ÞŠ¢)šfaÞ`°íà9FÞ:CÞ‡<þ£Ô²ÅBá?ä‚äGÅ[í½ãvBä®°áÀáÐaöãáòm‡ÃâôâE^œ"ç‚ádËMKPVd+ÝÜ(îÜR.˜S¾â¦UeØbÕ=`XV`Yf&” [†�\¦Ü]ÞÏ^¦†_–afÿ8.f9¦“Næenfzæêˆf?Vaêeaëuá¼Õæîíæïed_m _1Üš ö†!fgLvßGÞd$–ßÒÚQÌ(Í]‰Qf‹)6åŠÝÿÅâP;]V.à.Fàãã0f`–:èJ±»„~±…Æ*sŽVŽè-™è`.^êò`VfmæhW’†ÔZÅ¢ãî�á’ÆÞ“^^…AD~o¯­çHþêIžµ›nÜœÖä’‚çù•g#js�ZÜE<[ÙŽðg€ÎIˆ‘»’èö1pÃêºc›­6˜®&- ki)<²þ³[´Öèµ!äx듈kdžëºfÞ»&äÿ¼ö$¾Nä›ì �iS�éÂ~žÃnç�^ìžîä¶ûäÇ.F7‘ì©¥ì±l�•Öe¹·{¼¸ãìÇï êØ%ïÇíIÑêâ.¦Óö”Ô.à¢am²~mã=æŒf奿¶¶í~Àíüžf’d“Îf½Þ‡àViz_ìe%ç˜öá䎧åNlwÆÆþiú�gȶn»ÃnÕÐîíînïöð> ÎÎiò6ïICïPï aoM6í…FíâPí-¡ï‰¶ï?¼h:Ië�¦íãðo[·kÇkîìë¿/çÐìs¦ét¶éuFìL¾ð _âäpê^ gO Yÿ÷îwCñFoq›X pq—×aÏeç ç’.im7fŒòÙ¦�Ún:z.réi@ðj.pÖæ÷Û•þf(–`™òr®r¡¹ò ßòæ~ççŽgéÎÜ0�lÁÝ(ó©8óiMóïf)’ksò~ó‰•sº;uÒno®®qø¾qù^mjñsûô—ígëÕ$ò`‘ë#çí$÷í%/ªH¯áI'îÜP,L�pIFgJVgK&b ÿt õÆu¡.õ1OuË©ìíØî>põÎZs 49§õbµu u Øw~WÖ£€¯ë¯^$(øŒ£¨ØéºXªB7Ò ò€9ÿ<äY¥]k¸xk ‡÷ˆ‰VVŽî`PóÕ‡q ‰Aåq#{ìc £)M h�ƒDò %"BŠ�Ðytd W¨œZsa–Œ!&3©Ép²“>Dšž&2ŽQšÉ„¦Tb*?¸Jy´ò•°´¢fIËZÞ’‹¹Ô%/ÍèKS˜S$fˆâø�9ÒÑŽËl¦kÍir´£$©&!¯iÈlºc›ãèæ7ŸÄGqRI’åô×9Y‘ά³¦ð$(ã)Ê!ÖS8÷Då�Té–'R%Н�e,�°‰¥2Õ¢w,¨ îv·FPµªºüF ®6BT6ÝÄܲLp`ÔÏT¡GÓ*M�ú ›ôÿ@dTR³Ho6R¥�§KCjÎsÎÔ¦ëÄ)ƒªÏ¡²²¨®<*RÊÔ¦Šu™P•*¸ªZÕU#«jt(pº:�¯‚õj•½cYÏêGµ²ƒlÝ•[á ¹r“‘&çJÍI“Lò…1í«_qXíét°¤4,; TÁ5*D݇Qí‚ÔwHv²›pjµ.‹ÙÖh–ªœõìƒ@«¼­s¢¥Å.31ªÚÖ²Wh¯-ä6šë­n¢´®(ÌmK4¸mð·¿°Eˆ'=iÝM7¸7}'q;OÂn ¹Ê�_>›ÈX~:ÖŸŽNu'‹^phw»èn#¾KE`Æ¢Ä&æjÿ^fUÚùE%.~qjeâ¼öÒøTïi|Û­ÔÐ×¶{$KõÛ_ÿÂ7À=p�ƒ;Ü`·§yù)„+aç6º�•.»¼�a+xÃÞ.ˆE<Ų™ØÄ{ôiMVœ�#°¹Í/†±zeÁÓ¹J7V–|¹�Óõ¶v ²‡ÌßÿnÃȦ@r: |Ã%qÁÇEsrOeæê"Ï�ng³¼e¥Z×Ëõ0kÂü¡6’¹Ì±8ó“Ó¬æm´ÙÍoNAŒÙ1ã:Óº:w–_žãJ>§ô¾w €�MhC#“ª)£CÙäÂBúÁª“ò>û Ùw\8©]>mv? jQû8¥.3ªõÿ¨j5·šÍ¯NÁÓ-g�ÕºÝa¹õêF:åùö¸×@Ö-K‚=äayÀ>ö_ÌdG;YÜ‘N,¥ß §K_9ÓÔn̦ýmݱ"Š" þpwÅì펙úÔêþøªY]îs|�³v7ÊU露‹<®·}ï�ß@ »Èý–8S®Éd—àÌNõÁ—›–C.¼Ê˜¾Ä­�ó¥R¼âçö´7­Ž—\Ý!/÷H^õ™œ<å^ÿ‰~‹–kˆÌ­ZÀ¡ÜVF4‚-Ym‡L�…@Çè›Ý¢îv÷ÞóŽÅ¹1)ö–Io �E/)©d�úL¯xCwŒBl#Ú�Y6P¾ò8ùÈÖí8ÿÇa ‰ž/Ã/ï;�¾ô»ý:êMö…�ý!eçÓÙ»—ö±]~ qûRá>K¹[Äð�É»ÞSÆw&ý��‡ïà»TxßOHñ‹7rãyÙKž&•·üå3ÏR D'ô—/½éñšúñ`õþj};^ŽØ?Z#j¯}¼mƒûM苼/‚ï½|¼ï]n}/þñáXòÉÃò^ó9_0ž©9ž4L_û™Õä]ˆžöá[pŸrxN€é�ù}�ùí ú©ûÜû•HÛéÐÛÅ�Í�ïíŸôŸ8ü_ÌÞK)Ë`»äÅ:Ÿ–Y ¡:`Á푲A÷Uݯa YLÿ‡èyà’_.Q¥�ܘFDžûÑ ÚBÌ_ý¥Ìýå Ê úÙ} ¦ áYE„G>_€uœ áÖQ`M$€îatô¡r,a{XÐÏø!KD¡!–Ÿ‰]F f!õm!mÀË•²à7¸ á•¡ðùñÕ ñÝ üä ‚FçÈ¡'ÑaÂf_î¡"!b�"âÈââê׉@µÃXÍJ„œ m É  XêÚ>ÜÿŠ&ÎÒæÑ�úX½!FaÁ_ b©b¶"Nì,Æ".–#¶„Žà¢.î"/.@Ñüb0†H„Ì=Ö#†ÿ£… cʤ3’L¶Ôc=þâUÅÚLP#ØPY›`c3i£5(^;.€7ÚaÕ‰^õÑ8&@9šc 6!©Èâ:Ja;¾£@Å£lÌ#@ÎÃ= Æ1ZW2ÎUô#îÊI΃@êAÊ„A²˜5&$)b¦ÁCFd‚ãMT¤ ]dFªãF¢cGâGŽßCnÞKUãCŒ•’è`cÌ$†`ÈJNVK>?¶ E4£I¤¡�ÆUEcFÑ„Qš–l‰!Ó€•ÕO>dt¬"+Näåµ%R&¥S.%K¤£G>%êE¥TZ͆]å(n†Vneitå îØKŠe�å�ÌäYºEZv¢ÁÝ[½e‰Äÿ%Í¥O" ]*^åGðå8úå_Ö"G:‡F¦×ææ!&¶ñ‰b"AYÚ£cFdæÞ>Næ%Ž¥?ÊäIffTl¦y@šgªhÚ†h¶ i6S]¶ã]®¢j:k¢kúá9fS‚'m¢ãš6p€z®çÿÔo0|Æ'g•Í„Ôx€í\U|Æ'�£¬çz*'DTÜ8(äFÜ$hO €H”D!ÌÌÄL(uÀ¦KÜÈz”§†–çy €ªg{(Eì'|ÎgÇÔç:ÝçSä§.‘(#ô§Þhʇr€€>�¨F ¨‚ªƒÊ‡ƒÆ„jŠ„R膩‘öH‡ÙŒ†ÿ¨�Ž(‰šh´ ¨&©(*°¨¹(ŒÏ^Ìh�¶Ã�öäVè(,èK5è�©£ éTè‘¶©›þD’ö×’þ�ˆŽƒ‹Bé�H)Q©•Ž–:žné‡vé—bJ˜~D‚Ž)�–©�ž©F¨LLèš¾)¥V*o z‰r¾'‰NUwéé ñ)œè'‰fé@À —Ùiêª$*™bJt­Öê�~šâ–¤²©¥öê‘Æé  Æ¦:é~zªf�jˆj˜�ê~šª@ ê ªª[°jc‡˜¶TI8άÖ*­Þj®ªÔ®úª¸º)QYZtiµÄ§±VÕB�•²ÂÅÝü)jGÌÿèR¤¢©Q«7G¢&*¶þ·v«£^ÌHj¸Ž+Ânh¹ë¹J«2ñ‰ºfVwµë2Qi-á@¼’¨Úƒt¬Ç¢ç½v£©õÉ–,ŽÚC¿&è¿úDÀv ¼,Ì¡ÁÎìÁ&¬Í>åÂjƒ¦:,D¤+|®+UQìYl-eì~n¬Ç~¬ …¬)t\Éš,˜nDÊ**r´,ÌÆ¬Ò,ÍòêÍvmæìΘSEl‡€˜ÐVËÅ^ìÝôÒ&­€ìBàk™=-ÉB*ML­uXíÕÒ€Œ¬€ÖÎ,×z­à¢Ø +ÏV%Äþ¬ÄjÖÙòIÚ-¸°í#r¬ÛÂ->È­‰ÑmØíLàmuèÿíÕöíßlà®éº[á6¬ØžÙr×ÄúÒX=®­-“´mÒZ.æ–˜ær®LxnÕìÞò­ŒŒnÍž®ñ¢zn ,/ó"S$çsM°3?û³BÃ3=;è@tASÞ%ò;/´EÛñE ´=G4åaè6ÃòE‡t-gt=4G³�GÃ17‹4K3òEöíCaߦô+‡qKß4(¿´ŒÜˆNM¿DEã´P¯oO‹O�ãLÿtP5S›nQw s<õ üô ,uS_õÍJõQÃbRÓ´Uc5X‹«VG5Rï´R¯tX§µZ¯5[R@!ù5,*ÊÍÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹"ØÈ±ƒÇ�9fI²¤É“(Sª\ɲ¥K—!7~ó¥Í›8sêÜɳ§Ï‡1Ìôô§Ñ£H“*]Ê´dСŠ6�JµªÕ«XG>*5«×¯`Êå¹uf×±hÓª]ËVàŽ·puÈ� õlÛ»xó굩¢¯_¸qçÊB¸°Ý½ˆ+^ÜÐï_À;.Lø0ã˘3£ÅÀ¹³ã¾�#K¦LøˆéÓšS«^mµ³çÏ¡%ë =äôi¸s³ÞÍ»÷Kל?«ˆ=š´mÓ¹uû^μyÅУ‹˜N=Žõë²k�À½»�ïàÃÿOŽ;�ùóÎÓ«_]:õé×±kÏÞÝ»øûäiœG¿¾¿ÿÌíA÷|ñÅ1}õEp~äígÞF¸W€ (fxà *¸`x„(¢ƒ Hhâ‰iQha†Øá‡ Š"‰(Öh#V*È"†¾ãw2Îèà�D©TŽïíHF� þd�Dy^Tiå•8QhÀ–\*Éd}.„)¦d–äQ:0e•X¶é&JZr¹¥—.&(æ˜e’yfškðæŸ€FDa�qÈ9玠è¢w†™§žPJi•~jé¥5h�† ¤ †º(£�>ªÄž’&@)¦¬þ©i€„vÿúi¨ Žªh£.˜Šªš“²Ùê¯V. ì°ZÀ±Ènˆ«­0Tàì³D+-ÔVûµ¹  í¶åí·"+.XÃ; ±È«l£Ì> ­´ÑVk-¶¸mËíEàæ[Ó¸übU®°Å˜®º.k«»Î¯¼\ûB¶ö Э¾÷kqUÿ.`a‡€+®&„,2Â(| (§ì°rNQ¬ïÅ03•ñÆ vŒ«8ç,òÈ›œ²ÊôÒp’Ë/ÇlôQ3ÈñÀ7çŒóÎ!“ìóÏ(¬ŒÛÐDƒ{ôÖ> ëu§-íñÇ.8ý4Ô$Ç öÚT£�ÖY{ËõÜ:yÝئ‰MvÙfCÿmBÚk«ÝöÛ&…f¡l–Ñ­xJv«€÷z“m¶~øàä�dø€ˆï»øç*5þxäOî7Ã.8Õ„[DáæïÉF¨… ×ž‘èÓ…]ó±{›5êªÇ€yrAõ:d‡K6û€Àa`ûóá.‚îõ!Û{ß¿3üð,?d|€°S'{�6ýù qÄÂúÔF2!¨-Ô¯Áý䯿´Kôï¿ÿ' e@À®à€@‰Éñ£€:pCöMÇ}ð‘üŒ@?ûáOùãßÿþ'À�€\AC²@¸8ð�Ìá+HA fpH]ÿYÐ>¼/~óUýZp?  0…ÑZ! [x‚Â�Q ø sÃæP‡ãa} qqC,âŽ(Â$ša‰M|âT(Å%P±ŠVŒá 9R÷tQ_ŒàyH‡BÒŒg¤[?hĆh„%dâ QHÇ4¥éŽ€³HýQ !8È ò�@L¤"7²>"2r�¡„¤MèÄ'VÒ’ÀdÄ6Ù�Wµ”l”Ñ(7TJ ž²�ˆTåÖ)"‘„ jbówƒjJ—ÈX&Ò™xó›f(C4L †QŒÇ¤C2•i4f:³�Ð4ƒ4'YÍ\—ÚŒ79óÿMpvQœgÚÐJP\“é\';aæÎF>3Tó¬åêyOKæÓ^ûÄ@?½N`ô@-h£šÐT.´�¬ô`3 OˆÎS]!6/z¯†ts£å™ôÀÓž†t {“zÌ1õ¨ç«XÌ ˇFó¥Ô´¦Lñù¯m:ä¦ýÌé'wÚSžþô A ³ÒyÔ£Æ�—«ÌJÐJ5s²”'T'*ÕÿÍ´ªú¼*?qúO�©«^ýiX]0Ö¢–u gÅ¢Ñ2I"QŠRPi^+[Ù<¥öG?Ȭ6ë0‡p³„hG›²˜¶õ9ÎJÀÚ$¸– °�­fKÛ�ÿÎ 4¡é�n=ÀÛ;‚´ª�†p‡{&ÔV�hleKÛæ6· Ð]ƒt£.+1¶±ûy,•" ÛÚÖ²ëÁ¬f7Û¶Ï’·m(3m PÛÕ²¶®MÂraë\'Ø64�ÒmxëßþVª ^qæ·äÎs¾N0t› Ý5Pw#Xº.v{õXîºÆ»¯zÄûЖ—€F/ ÔË^µ¯�o}ï ™üî¶·Tü/€�#à ¡®Ànb‚wÛ7øÁˆpÄ&Ü'ÈÃHž�†ÓÃáÿ̼ñˆO»„Ôç½ñEðŠ7Š_Cé—¿þým€U7`yùMŽÊåñŽ}<]èT×ÿH>χ_•$Ûù›‰cN“Ïûdó¹m$®rw6„e×Nî«,Œ‹÷ËÛ?8úÑ2sàÊ\­3?1ÍjF0›ìf_)Îæ™së|g;çy9{Ž2Õ ,å@ׇÐ(N¡šh¸,š¿�†ô%½6JSËÒ(Ät¦—»i ‰RÛ­e j’ºÔH>µoR=g'šÊ¯>P¡em6DsÙ� \´~síhÐ5x5ž@µLlý {ذ-v§ƒ\$dkKÙVl¶ ž mïJ»7Ô^µŸU�^WZÛ±žuHí@që–Ü0·QÑMæ­[aíÎß»á-ï¼ÙFö¾_¨o~÷;Þÿ of;üg”±ZÄç¬ákènÓúÛ;h¸—õûprK| Ÿ´Å©Ån¨¡ùÀð&vtÛìqO)ä#/ ¾Õ«Þ“cX8ÿ xŸe`mªÅ<3�¯Â J†{ç<‡øÏƒÞë¡C è;;º4“®t3ýã5‚úf—=uª§ÀêÞź´ž²—۟϶Ç>вƒ[ï�Ú7{n¶Ç@D‡WÆp�Î{Þ ý°;Žwé]|ø ýþwÀoTð—]y×Q`øk¯WÐ2G8Í¹í´¯:>çg—Ï{žëµ[óDǸџèùχô£_:§›Nï¼Pl²ëËT2–1lvèL<¿ÿø;f!áÜöSÁ> šÇ~à¥ý®!cdÌúØÿþZÈ¿þƒ×¡Ááÿˆ+0€Õ¢§q\˜€ðUïõ^RtgROõôUdâ.Òâyb! ¶`Zæ\­¤ׇ}Ú7Ü÷/Þ— à'~áG~b~v†~M¡~ðï7ƒ ôçw÷‡ú—ü×õ€Ø( X€Ùq€€¥€È€ X((�7@�J`�Ñ‚� ¢�ØØ\˜!8Y#8%X.'X)¨‚,ø.˜d0È2hƒ•rˆƒÿU;8=胪„A(„p €H-h¨„LØ€O#2"…SÿøSø.€…õ¡…Ø…´õ…ˆ†­4†Q†Ã"Nb*Õ1y8ÚKfq(‡®Qƒ3(‚‡;h*•ƒ0ñ_€ˆD8ˆPˆGp\}0ŒÄøUåˆ$‰U(‰”Ø_�Ò7)Å ¨/ê÷G‘×)¢˜ ¤8O¦˜‡©¸ŠJa!­èŠœ‹�!â4‹~·‹¶ˆ6¸˜‹¼—3$S„„x„¦¡$ÄHŒ¸rŒR˜ŒÂRÌh…“Øy"�ÓH�š¸œ¸>ÚˆvúÅ�ÀÔø�ÒŽ;8ŽECæˆ}èøŠtìLîHuðø(·è.ôX�8s�¾ŒüØ�}ð�ó„ŒPÿ¨ŒR‘˜0Wˆ�Üá0 �ÔÈVës�!ñ‘“‘Â7| JùÙDõ„,§È‘ju$¢”­¤Zr¨ŽœQ’ t’ê•’y²’ÏÒ’““`„ó1“ýh“Òäˆ*~5#DP=Y2?yÝ!”CY”—\ ‘]´�†Ò�p‘��7`•â¨]äØHBê§Z×™=Ð)Í#–ŸD–¦e–e‚–΢–fÖn©pé��â˜õT—Æ™'Ž©œ÷‡•Z£•ía!�‚™Ó9‘†B(žù> ™Û©Ýù�öˆ0øø‹²šÃ(—T)…ê©“x)?zÙŒ>y�~™ Cù¼©ÓG;`!´�Ÿ[¢Ÿ‰Y‘Þxœs™œÇr•Ì™•7áKâïq Ò™ Ã¹ Ò a°Œ!¡J�ki¡1™¡äI“z?tY—°¥\º!íùž&Ÿ»9ŸkÑ¢[0J2j4*'ŠÙS‰¥:Z<úX“©@¤2 DjFz¤r ×i’;IPN*�, ¥§)¥mÿ)žªY¥qyž9šžZÊ¥[ê¥"Z›$Ê—aŠ¢ò7b‘1Â!�²!gÒ!>�ªª:B#”™ƒ,Ø’r<êZV¥ÿ&yº§ïÁ¥úuª»“.ÀZ=ãªÇ""Q ̲DK„+r$G~ÃÒ:­Ô*­´êw$Mã4ÕÊþU. ®84»89·yÔ¢‚°®ìz¢ú¤j(¦$¨ªª©Êªòc¬¯«ô8«ªS«›u« ‘«±«⫺5¬ÝÑ1 Ë£¯Èʸ¬ÌÚ$ó¬O­ÝZ­×JuÙ*#Ûš3Ýú­Ã® 0®ÚQ®fs®é*~ìÚ®Œñ®Ž¯r2¯2ÿR¯öНF ¯ï¹è¯�° °A°a°‚°=аÀ°ô¬È±!’¬ˬ‹±ú£±;­«^+"!‹3#c®âêE¢²Nò ®/Kîú/£*¥z Lk¯©j*<;0>_rÔ|�'´D{F»Gñœ" ´Lë´7 µÇ"µ@µ¶¥î‚µY 5ÝÊz]kZ_"akcÛB›e¶'‹¶ä ˆæÚ—-~o ·1+·ðJ·òj·O[xë¦Ò­¯z,}ëZ ¸‚›W¸šrZ¡Eš´[ú«µ»°c*-ù°Ã‡,»˜ÿÇ,”û,–›?Z;­šû¯ØêW ÿÛ(“º4º%{¶€”¶¨»²ªÛ¶.û¶q[.s+u;w‹·¹[­�Û³ÿ'«Ì¼¦%cC+1éC¼�´½š¼ »¼Û¼�ò¼Å½Ç:µ[½“»¨•›½Û+­Ý´ß«SA©w"¶ÕŠ&Œd¾Âb²dì9Œ»(8ö*ØBë¿�ã4Ë%6;½pj*�¢»Ð»[>›Á€{¬÷[ÚÂ…ËI|´•’™L‹+ÎÛ’ôØSúÕ1’;*×ë,Ù;~Ãz¼6¬Ç¥[¬9 [Â'œÂe{¾¥«.ü}�1¬(3¬0«Ë6L�•2ëJR¿ÚA+ bÅ@ÿœ'B\ÄFÜ¿¾û¿Í·Ä¶JÀÃpÅí¡$T¬­auÅX_Z¬[\\ÁÊzÁà‰0a|Â'LÆ~—ƒT‡Æo"",&$L­¬ ǤÛ§‘wüy { /}üÇ8,,ÂQȳ;ˆlмÈdÒÈE쳿;É~7¸ñĽd¼ÑÁÉÃw&ƒÊ¡œ£LÄÓÅ2ŒÁØ›½¬l®Lu°¬^²à:Cßžà”áÑàÐñàááf0áæÝy"žYla¦íA(>ƒâ"EP-1`â'ÞÊ&9Ãâ.^0ãr1ã,ÿRã>tãÜ Û­ãiPž3*RäA޵iŽÞâqäHžäH°ä&ÜäÏòäQÎS~5aåÐàóÑZ~6"càÔ‚à[ àn>bþdfŽæC®æO‚&Qæiçݼ#2X$cçwNÜ{nâ(®â‚Ðíh²±!ˆž!ŠŽAŒÞIqžã�.é�B2•né äD®6F~ä!ÝL^&óëP®6÷-Ä“êFvå�—å@Å7°2²´në?Ààþ=æFáÙ*¾^áÁÞæ¯áÃB!J’ìaµìfsçûCâÏ~ÜÑèÌ�B&àÜÔþâÖ.Ø~LÕ}LÓíš�®ãâÿ~'äþã–Žî éáÁé!ÐîÜñî{Y¤NïRnïTªþ¬¾Üñê”Ãå³îå2@ì¹¾ëßÑë›JáÀn>ì·Î¢» o'�0Ì.âÎÎçïïÓþÕþ×~ ÙŽ!éÔò‰…ãñé‘Îã4_ó’xó˜þë:<ïóô›*ôò^ê§.4ø¾]¯ôXÞêMßïõ/õTùVoXïäi~k.ì@ìa‘Ã}QÙ,bñwQï4�çz®ö~žâ ¿â"OònïÈ�ò§´ò§Ô1úCCóÖ¡$Ý­ªÊî÷%*-"ré›éE¾éœnøˆï?ï1Pï÷ÿNI¿ô"à–¿å±Þåµþå_UŸðe¾ðžõP3ú¿*§�ÌŸ¡úÂúbâúf PÐàA„,„Ð0Fˆ#LŒ G� Œš`ÀÀÆGDŽ$)òÃI”tT®$ÓÒåÊ•% h¡¹Â&œ,t>àǧK—i„ú ŠÑèQ£”.eª4ÆS¨¤.<�ð  .@�áÀë×aÅʤHÏY%i•4ÅŠõÆ ¨<äÊ�AÃ. yõà Cž 6€ò$Å7‰3lë¶!„-‘éÊøQY/€¿�‡lò#J3¡Ó2mŒ¤Ô _+ÿè{ÙõkرeϦ{Áÿm¹uoæ=h˲‘ºÐPÜxÓ 5Ze^�êã‡s”µht¹AŽAÊ”iø$L•¿É€§#“¦›+p"ÐÉ"°Ï8â…¦!êcøpäȹ>EMµù¬´âê+°Ä ‹¬àÎÂC­µHkë­¸æªë®×úò 0žS 0ÃSÌåJ»á±È¶˜lµË2㉷Î<M´•*̈́ӤR­²ÖjÓqGu¼mÝvëÍ·ßà0òÈáŒ;®)åúϪç’n:Šª[Ì‚�:òŒ»’¼û€¼ÄÂ|ƒ<ójº)§�zúé·ùê»)äƒn¿þú/À­ "Ð+,)¸d�­ázJ.èºÿ /×,TQ0¼óð�+-‘DÉèBQ¯GYô̆Ím©kLÍ«ÕrìqUVyü1È܆$¨#‘DJÉâ�Ój× älhÆ„¢„ ºˆ¨»èÊ,µûˆK’¼óYhÃ,½3ÙKóøäª¨7“jÊ×aéœj¡$Ê5÷ª¬ò|jOú|Á²U‹P· �QE)l´¯G5ä¥I+½´¡O´ŒS ðÔÅ“B5Æ JýµYã«UŒ3¶ 7Xe¯V#“ÄUW^{õX„„%V¢*�ÑIì´ÜŽY“¼‹öfiK:/½õÚ{oM Úä¶[âôu¿ê<ÀÜs±KwÀ=Ý…×,´æuÿ°Þ�Ю ùMØ_I' SàÆF$8SÊΫSÎ> uTK3µbU5¶›¶õznO'øàóÒÀ‡ap›´´4p?µiw|Æ·n ¤ˆd2ʸÒ舨d ºw¸ùƒ ž¤(Ê7?°Ÿûör{¶æ‚Lˆü1Šr!ƒ Ð_€»û‡-o4í­o>ùÛçŒ@¸Â5iF‰ûã×8Ƚer©\I.WœÌm®s%1 B§ÿüä‡)¨kˆêhÒ:×v±›ÀìD‡RÝN+öÛÝŸÄ–ß)x“ËôV`¼$Oy6Œ@˜š7£èIÏ+é©ÞõV”½ˆl¯{}øÜÂw€ñ�Ä|çC¶¸¾í¹YW™_Cê—;üí�þcc^h-~Ñ;Dàà ·@_)Î�Œ ä&B9ˆX#˜kŒæ:²A’tðƒ!¡RHj…¬{ÝXØB#цqk îtœå½!‡Øa†·D›QˆÈ åK“Dèù°‰Ø‚ö¸ç=ÅèŠYÉË×E/ªÏ;ìã˰DÆ·Ðo"öKãþÚØÆ7î�or4 ëxGÄÿåñSSÊÁ!(" þ‘‚�´à 1XH >Ås\$œéÈŽ¤N$«›d%/éBnÒymñäjH’I�²”§t@ñŒ·J´nH„¥,ec=ZÚrŠUÔ¥B°Ø’ô@£æãÆö…æ}ÇÄN!pÆûåÏ™Ïô_4¥éÑ~®Ž0ÀfcènNqŠ}œ  *H’ j ƒ‡T'ÙºwŠð‘‘±–Q¼%s©Uç\4£ÕhG©‰bŠtŒ%M¦—‰F•ê�¥- 4YÓ9p¦5mËM)�v�ÿ§âô)9�jN¡¢“¨1Xçç>˜Ôü,už4qêSUhɨfò…Eã$?gøÉ²„R [å!|¨J±ш }eC¿:KµJ—«h\yYºÖµ‹ˆ5L^Í0Ò�˜¥Íì`ï¶ÝxP(›;™2®"Š _Q\N#[¢*"3+€Ãp•Ù¶i2ù,h“*Z’”¶©ÎzV}™2Ø~öƒEF‚h!Ç »¯\Òcд'y ðHØ—`zq5zby0õêD…A"R®‚-zÜäö@&ìcŸ—æ0ÃE·¯'ýkJÕhÝëâ$»ÜîIº{䀷¶ãõJy§Ù> 72êÿ…{Ý‹«Ì!m8þµ¯RãYÂ’è÷ü••`xžÈ�¥‚a¦,X+ æA‡Áa�L¸Â"¹ð³�Ó C�Ãnˆ×:â¶:ÌÄÆÅèHR¼b{dpxqhbŒL³Ñ8Ì ìqœ1ìæF»ÁáÌ$�„·Áì22dÏ«d&çÀÉ¡yo”÷3e¤V¹‘ø‰–¹¼ÛA5Ìó˜}b`‘ ØÎMQóØìæ¾Hy6€…·‡æš ÏKØóƒûÌáºÕ ƒ€ø -’C—$ÑŠY£Íðh¾Fzº•¾´Æ2­‚M—¥Ó”òîR„ÜUñ²Ë—Q0¯N•¼…T¯Ú ­.¤ÿ”‘âeY�ðÊ�̲~oͼXÿw×½&sÌ<hë° n0²ù¢l0ÛÙȸó¦]m&~8¢l�hh¸íí¹ÒÑ,^´¹Ñ?éÖ˜º–n7«ÞoŠÌ›‘öõ�½J }÷{Šÿø²Dòd%¹š+°Îu‘Ck‘ØÚfý�øRv=ŠÿºÌÁ>ó°Ó¼ñ5w¼ÃÉŽó²ç\€:‹éÎX9yXÜ|mç€ÄÚ~¹\ �Ü™³¯æ�¾9€r>iÀÞ¸ç­ú9�9ícO׎èu¾÷”ô#Ÿ½MÉÓY å‚¿úà]·úR°^­ZÿzØãì[îÄF»±Õþ`¶³@Îͦó³Íÿíº¿àî*.ËKL{BÇ|£�ßÞà_\xùÍxÝŠ_׸¾ÛÈ>íSîó¾ïÃ&?ó;?®‰ T¿ø“¿ù“�ú»?ËÊ?ÿøþC ÿÀ… @ã0@×’'Ì<�jÀry@”@ü©À dÃØ@#è@ÞúÀ $AL«HAˆPÄ,—�§�Al" ¸Á)ÑA|l!$Â!4B¢@BÐSBA ?'<‹(Á)¤B½°ÂÀBíÛBï;Ã0Dô{�2L€3„¿4TC1³Ä 7$©ý+™þó&:<;ÄÃâÐC<áÃì@L‚XÜB¤ÀÛ°@kpFEdD²Â„Ä\¿IDADÄÄ0qAN‚ÁN„ÇOü°Pô ü©ØÁ„+TüU\EVtŨƒÅqìˆYăZ”‹ÁÅ×ÐEÿ`ò$û ÿcBvFbCØ8Æd<�eDGttFhT-%Ð?AŽj| kmÔnLoôÃ) LJd€r4Ät¬Ç\DŠÚÄw|�H”Gœ8ÁÀPÇ¡ÌÄ$0ÊGDÊL9PÅ ‚4EƒdŽ÷b°4†$$‡ÌYœÅ‰¼E‹ÄÈ.ÒÈÈâHoòÈ=9Æbt�cT#ýy#”<Ä€\I8P —4Ðò?@¡I(À�ØC,ëCSûC–t@¬¸¤ œÌBqP‹t�õ¦Ô ŠR ÿû7vqÒÙ€P5’Pt¤PçdÉÀŒÎÚP=Ì%!¥øq-ÿe™Ñ2QïDQ+TÑ€\GAsÑÎüL¥œQÑ\Ñ-È«yQOìÑÕüÇ8H }Í!Mý4Ò$`BÅQÒÒ`RÑÒ'u#œ�R‡ósSÐÆÁÒ¹,ÃEΠ½´0-€ç¼ 2u3�ˆÕ8aÓ’Ñ7®8-�Ï:½ÌKÊËQB�Ñ>¥ÑJÔÙÔ=åGC•O֤Ϭ F¥ÕæxT#•ÔO¡Ô%Ð&%ÕLÕ‹(í¢)m˜FUUâ×-5Õ.EÕ½\ÕVÅÐbºX�U5­UÁ_ýÍ_þMC àÂz©*`ï;`Làù[`êu`’€à$�à‚ `9±` Öàäàð`µaÿ^a6 aÝ5a�ºÞ´ÈÞdá„tá¶�ZNP–Æ‚¸á%¨[õ5žöáO�ßà‘_:¤ß"ö•ûMÈ$Vâ>YÆ&ÎTž¦×-‰Ø¥b“zŒeÄbÝÕb¿üÝž`Þ+^�<Þ¢•!åu:’@ã´Pã]ac7¶Ø.‹¶ÉŽ´þÞ. ßß–¬a@ä&äBþáâðâBjd9ydUŒäXâù«ä'}# ;’ø „°CvINPÞ]·ã½-6Röãà…À“ÜKURVF\W6cYVZÖ [6èg†ã�c% cƒØÞ;fôæ3&æò}‹ómPõd )dÿ>`fgÞœkü7�œHj&Bkv Òf‹äfÇ‹­’ç^ŽœqÆËr¶-.öâ`ÂwFÉxîÚonå|å΋åî1 ”>­H"÷[? òçö‰\Æ5‚þc;ƒôÀã”Mèæ.fv>æ–èô h‹Nd!¦C�FŽ>bHŽd�i qbHŸŠƒ= vÞ^6¿•¦>–šGf6‘‰{ËÐÝý­it¼é mÄÈÙöbŸ)Šë⢠XZ‚¢V¿£FjH±IÙe‹ÂƧŽj„Ö™8Ü똶ó]?Vé‹®^æCŽKú·±É<Æc´æA˜mÚVëµ¶ä©îf‹ ÆNãÿ¹.¿º^©K;Á¼Öktîk¦ùëŽì4LUÂÓ¿lÄäµçŸÆðAˆ¡ŽžÈN€ÉFj˾¡7Àì^~ "äìÎ�Áøl]íã„xlˆÖá1m7³ f¦ˆÕfmôÚèZ„í2¤mÿþoÛÐvk[݉ޞåßF�மᶞâÖk™Kåfæž?ç¾`ücÉh›nXÞãî¹n¡¾€è¹€}¶Ê®ìä覶á§&B©nkôVõþWöF÷ö Ò^ r³úžˆûÆïÈÐï(äoüo#„¯ÈmÎí’†kë–ë:¾ºÞrn7âîgãFç‘�ð'ìül |nVÕðÖÚà·jÿ>..5q6†8ñïÖå9Vá('ïƒ>oH‘ñ’í¾qÈñø67›H@ùq r($òõ;rOr¶vk±3é8p|Nðç9ëºrÈò÷ë._î/onxÆð6$ó}2óžöð>ñ5‡a7‡óGá9çå:oˆ_ÆsÏÞóõÆêöö­?�hô#tÕf! /D?O"gtÿNòxt5離ôp~‹)'�*op xð½& .ÿ/O0·1ǧ GõOó!Íî%xõè�uÊŽsŠï[‡€\oÛ]÷i÷uv@—hù~0c/ CÇïe‡ZþvöÚvôÅÓE„’•ÿy ê‚~ ý�¿/Èx�×xŸ ×x£Þdï¨�¾¾šä}h¯øNøp*™ØA¦Ñ€¦¸Æoã’,Å7øÙÖZ¸ÇÀ@ ‰å[vMIe\´êª«–\æ¥`†©XPdz¥Ð™‘¥i™‚lÆ›JH¡…:a¨¡q0íù¡~®¨ %¢t¢G‰®ÈâI�b4Ü¤ÙÆdir˜¦)§›®J�¢n×�‘à!9ž’]}åê°ÊªÞ®lI©®¹&ü0~½ªÐå—‡ K¬Æ`f²Ë&Ø,ƒÏ>­~ÓÎya�oÜIk&l ÿ›CÞ‚K"n&î–¢¢+:\ì¾QžïÞˆãr™þT¯½Z]¨Ø É]‘S™*žI÷nÜê«bÅšÁ¬°ð\ Ãå5ÙìILq°;&A¬^�l ¯ò³"Ø}·´rVHg†vnÈ2k/÷ù§ˆáÖ<îÍæêÌs¤3º+Óc�É»ÓÑH[ÝU¾N� u©þž ðVK^@°Á\#L6Øt‰]6ë|�ýkņ]ÌvnÃ-7{€n¹» "ß�wÉzW›Óµ~»{�à1>›á¹‘Ë›â¿íœÏ@~ä‘ß0yNH{ïÂåGeAvûFý]xI†.0Ök}ð\e§^–Ø´~ÿ_€íŽÿ¶°aÒn{Ç–ÕÝñ®wuû�ò6¡“Y+e+3Hà¶5¸oŽfÎKHÎ5=çIêg”´·½¢æ{–SÚ§ÆW>Rõ+} ã ûF—56l­k›Ÿ|V‡¿ªEdÀÖM¼·´š¼ ˆFô–·à—Ì` ‰»Ûk£€)R‘Bâ³HE*Þäb-ù¢Î5†1’Ñ fɃPÊ`”U:%>óÉ–Tþ�•õr%`YDYÎr‰h"žÅ©]…9¿Ä¢ Ì0SŒÇC2•©žˆ6“�Ï„f¢¤9ÍTÓšÀ¦6ýÈ® œ†ç"EhÎÈ¡’ê\gxÚ‰IbÂs ò¤§=ë¢Ï¡•Ÿ@<‰?ED�”–|±eBq¹PÏaÅ¡�èDgF‹3£nXæ;J†�"!š¬)I«¹Ç>¦t¥Gÿ‘ã7åSEÊT@ç¬éMy©S"ðT{ž¥(ÍHJ¢¶¨Ïb\F’:€š˜çM5(BªK†öòåC2«YÄb¤¢çZQv²6‰­fmLJºV=ô µ®u«Q`[¹&jœ ØnsëZ×>¯ê|Ï^Ó Üáöô§�uÃ` «\SŠŒ³P,cÍóØZô–*Èå.-iÕ_jV³ý Žg?;’Ð6e´ *íHO‹Úƒ¨öš|Ümke;ùÒ$¶Í­ná+ÂäØô·v îp…[\ÀÖS°÷\.‚ñ'2 1N±nûŠ@_àÔ½@U²Ù Ïv³ØÝ̪r•'‰ˆ¿(ñ€¼ §ÿYØä�© µP.6‚PÖû.àñ&ðí}¹Ù•úä¾øÝÂ�÷[ßÒ¸: 0’‡û×yÒ3”“tX‚£Ìº�¦Á­Œ!„:a½TXª“¥jCsÙ ‡à»7qD›ÅeQñŠ[übEÆŠ¬ñInLæÆä˜Ç>Æï�™Ã_t>Ù.84¢“œä%7ÙÉQ�²”#ý0*ÁÊÿIJB"¼å¼tùºSåe†±Hfç¢YÍJ`3yÝ,8{GÎ/ŽñzïÌ(ÃwÏ;Öñ[y\�?çw·Ì©)¡mhDZÑHft£ m?I3{W”¶4§D—eXn3Õ�ª§¿ êÃÀ¡ÛÞ5gKÿÝ’‹·Í¡L1ƒV W»Ö¨•µI3¢ç ó×±Õu ò­ï¾¿v‹X4 Yëb—²Ìñö·7Lê�{ÍåNõ¹ßœî8�tÎtV‚�e‚g“Ì»»�ís�Ç©ï}ÿ8ЇxÀßCìb\¸§gÂ.tü4<8¿Zĵ‚’»¯¿Ñ[Û¤û.}û´ž—ê£]ADÈxÇ7¾õ’‡"åÃü�Óg^ ›oAç "›”Tô~#½[†úË«~õïT‡oLÌÚ+äöÊ=yí^ï àï5_“Ÿñ òU†òåE|ßóÅJôMúEõYÒõK¢hß²p_÷AÞ÷í@øU ù�„æqÞ¦dŸö°_5¹ŸÊÄÉßüÕÜŸˆä|í_‡ô_¾áÞdè’ ª�Òßñ5Zò˜^<ÿ óEàV æÅºPÕ,†‰PIy`xß÷� N” Iœ ú¥ ú­àI´_¡Œ^ ²Æü¥žC¬^ Úþ©’þÑÞ^€ÿÈ a€ aï`M _|8a“-¡PõÅ­ÔÏÞM¡#âEþËnEjÏz JZæ™ ù¡  ¨`ä°`¹`G´!L¼! Úàlààné LØ^þßdÜ”¢ïá 6Z!ö¢Y bºÅ"ÖÏ#£[DâçL"ö�aä\"÷eâä Få�_'Žá'–a(2£ä¤a ®áû¡"B¨bÚÞ æ Æ"Æ€ž€-!.æâÌaÈùb!ÿãØ("Ã0b#£?"#ÕdDtTb3VB#ñÒééÄÅœ_Gä6š„Æ_žÞ*–c+žã+¦cB¬c;¾ãb6° J¦¤=öbîÅ0R‰?ÆäZdfÌZ¢Az`mÎm(äå1ä°8äi£R�"™" Z¤:^FŽãÖEþЂÿéá,òáMý€VnåJ€ð•dÞQRJªäJ¾d?ò…Y¶¤L>"M¾�‚„æ$÷í$Íô¤%-䄉Pþ�(FdFLdEZ@U6¥È!+J„+º,~¤U²#-º£:m%WáW*`²©ÓX¢dYše{¤%®e1¶ÿ]ÆÁM`6A¤R”Ô��æëY„OzPêåæ=äMFÎËæ7*%c¦aj¤D´^ËiVUî¡�d¥dþ@WV&, ßMeæ læ>&âex¦t‚¦1Š&]–¦iêjÞ€jÂk¶ækÆfbìewÞf7Rdn æEÒŸSfDg­mYÉ¢cbedgr6X:šXf&t†ÍgºdtâŠuÆ$vî¤všfw~çn…çë�g^–çleˆz–¢7¾ ü±çRò&9B¥ˆÈçØÑçGÙgHæ§dîg“õ§ 4'€(ý h(L¨LJV�ÔÁAJY@c ™¡‘©sl§X͹èÿ›%‚“>)D©”â‘·É^œKMÈÓCle0ª…ã‰Õ^Ô”d”iƇsr&Ž®©Ðéh0ñ(Ôýh�ÞÈ�©�:Gt(éŠ0i=)”Ji”Ri·Y)–Ò„–:—æc^|iG…éE‘i™²©¤Nª[¸éÝD�ÊiWé†Ùé�òHž®ÏQ,i¾5©Ÿ& *£T©ì*ª$êY²£6“£¤V¥îê�Z*Á)Æiªø°F�z*šái¨ÂШîi©ö驦**êŠdé'm©VviZÔjÝ*å*¯†+›þ&äÝ„s«Q´L±k k²*Ac�j ˜ªŸBÿ«´RëoX+`ëh+Z8Ayë�«¸,h’ëß™ëO +Rk§²+ˆ¹k²Æ+³Î«³ÖkªÞk«V«¡^+¢f«¢âÀÊ’ÀŽ©eÊ@™êªÁ®¬#¶Þ `„sÀÑýˆÃvÄ‚˜÷„ÏQ ÁDX|ÐNi5áëH(žÇƪV¶GÀΟ˜jZÊF*ËFíuBÞË@̾ÑÌbkÈQt˜P½è¬Qð¬«ø¬z­ m‘Ùïí¾~ì(­,ÝTÓjÙÓª¬ÔÞíй¬¸\-dí°Â×.†×v }ŠØNÙÎ…Ù¢-©­Ú±-¿Â-Éí£ÒíÓâ-æR Þßúmºnÿm¢tíà‚OáRÇá&®Y,®ª¦í†­­ÑF.{ÔMɡ֭íÚmææn”mnFt®Ñ,à†®àŽ®Õ Íé ÔÏíê6në>î뺭äzËìÒ.ÜnÝê.ö*ïÂìOÈìïjmð‚„ènñÞÈñÂRòžíò2ŠãÎäBoìÆ­:QoõZoÊf/þFÚæÞZ‘ü/·ÌÒ|®Œ™À¹ˆÛ ßý¢Å{lÇv˜˜‹Ÿê̪}cþ^p¶æ Õ�p³Æ7l°ö$p£-p[ÄŸ¬ßc‰c° ó�s0|yðÿ pðA�pä˜p“¡0[¨0yE° Ï(×ÿG Ï07[|Øðná0èðó°¯­Cm «A±¼p�1Ë>ñHu0SñÒXñ¹°-Ó“¯E||1 ‡’#1çqÁšñ4¡±«q ñp»±âm±Êα,�±ë1#Oj|ü$ÛQpf ã‹ ¯!+žsè\Tš®d#‡2¥>r$×Ñ$‡@%¯ŒÁM&ËÓ&×h'ËÒ'Û£(×òš’òHò|vW*ƒï*'K+Ò+; ËrŒÒ²-'óZâ².—(/ƒð³Æï±²Ñzrfr²YXóX–¥2w³?2³)ï²f �5ÖÐL30W³1�%6—…6“%2{³¦M�º�Uê ªU½Ê�K·®Ý»xÁb;–l˜¿€Ñ.�@¸0ÛnßÂÅ˸±ãÇ�#ÔË—ì6À�.œ¦³çÄpHMº´éÓ)‹µŒù¯à› {þì64êÛ¸sëf¼Q›ïßIN¼u˜×±#ÌîÌ®¹sÛ»£KŸNý«ÆßÀ; '>Ü8òØËÓ8ÿ¾¸ºùóèÓì�][ð‘Ü»·þ¾9üøæÐÕëßÏŸ4{ìïáßÞiÞr÷±“Á‚ öçàƒÎõ_vÜlÇ]�h%gß} 6ᇠ†¸Ó„¾8 †Liˆ ‡f â‹0ÆxÐ4ÖØž6¬µVÀŽDIÉ‘H&xÆ’*å'ã“PêW£�íåˆ�=þè£�CI$’IÞ·äM–å™hN7%�7Z –;j¹%—ßxù%˜”(ÉdJN¦é知­¹@›~é'�ˆÖig5Œ6ª'™|š 褔6&(¡Gg‰Ò‰Ã§ 6Ú¨=¤–:f™TUªêªt]Ze¡WÿÚ©� †*j5¥šº§}²êë¯?¹Š�›m:+­µâp+®¹ÚsjJ?DûC\ÀVkmN7ÞxŶÜgç>ˆ&+®²·6ë쮽^«îºe۷ݶöm¸ãÖº¬¹Ïò*)»üö›¦!Á»m*<¯§õÚ**¾èîëïÃê û›e_Q°ÁvÒ›0¹ 7›oº ! òÈ”l² §ÌŸÄ¾Q,ðÅÌåÆŸÞëqéF42É&—Œ²Ê@ïW²eaatr™$íÎÒâ4-dPGMÌÔTScõÕæö£õÖúÒ´� zY&6YÖ”m6"h§-ÀÚl¯àöÛ�ôÜ@ MVÑGÇ–t&K»ÿÓ´8OG 5ÕU_muÖ[kÝ5µ � ÖØ�ocöÙi£ÍvÛo»·Ãtwî“ÝGá�ÒJ3ít�‚N81†ÞlâŠs^�ãCE>öäeWnùåd®yAr{.üM ‡$:é|›8ꩯÎzëˆ'¾¸h_¯¶íšÂÙÃöÜ'çû ›ç<üø:Òñz—î÷éߤ^�óæFϵì jû6'Š%÷ÝÇö}ø^#Ÿmb¾m o3{ëÛß'8øÅ/W°ëÇôb?Ûå/Vûã_¼ç;2n€ ¤HÉ6b¼Ž Haa¨<Jmu„ ì&X½)Ýï‚oÒž““œ¡*„@aÿHx>-…X¡úȼÂ0†¤Š RÁÈá°X:äcãÃHQ/ˆ`tÈ5RBnœ‰JLÞú–×¾æ=ŠR¤ß@ª¹+†aSÜà ÓÅ®…ñ� #6ÊxF†…kt!Ô H* 8ò‘ß›â¿^u”Ù�;Ü#aú@@z² ‚$ä D2ñÏH¥*i�GBÒw’ˆ^KÆ'{Ô¢&#ÀÉ~ò“¡,¢G™ÄC.‘}ª\%#]éÈH:l–” ‰-/¤?åq—¼¼ÏÉÍeã›RÊR6AÎv´ÃK ‡:¯æ�vFïðÔazEËm°âž)ŠÍöÉÿOOøóŸˆš†@úς᠃BêñNÜ £7Á©³0…œ›0':›¦Îp°Ó�¯Ó<ÿ O¶Ð3š ¹'+ò¹~ö³ žè@ SO 4¡ UhCôЈ‚q¢ÙçH.ZÎs)�ë´Z;½ñÎx®iž«§JYZ—2�iMozМê´9å�OƒT¡žeœEݨ8:úQ¦†´#-)TN:,²Lu0ú´*Vé4SšÂ”«`ðêvš�žŽ5„e­hRˆšQ£ ©U*HeW§N ªâˆTñ‰×–ꦈrßFKZç –°†=ì[!‹¢µ±je«dÝJÙ¸ÿ>Õ¤QE©=9 ›¼ºt¯\-iGkZ¯¶CkSmøèÆZ 1V£Eê¨l©±ÔxX÷º#©q0;“oz7õ¤Oaþö·šºO¸Ãu^7ÖËÞã†U€õdH'UÖ\ø 繎݇t“JÝv^»ÙýƒqAà‡æ»ß4 >ÈÀà¿FŽ0y›&®ó¦n¸Ä]{Û Ö¢ä‹ïB曲ú 辯….‘öÙþzã¿Ö °€[S`ÃÁÙPpƒ,˜Kx¶pÔ0<õn¸¨kˆuË�&;ù$'!1ÄLLüz‰Åm…qs:­íblÃXÛ0å¶W½Ýdp[uÜ䇹1œnu¯ŽÝ¤u7¼I%ï”ÐÛZöÿ^“°óÍ�}'§ßÿöwÀY5ðÇ‘åÙ‰ö&¦½ðv7<Û±Ùvkºm–o/%Ü'÷ƇÛqt¯;Y>÷;âÝœy¯+åSZ9%‹MÊ— &æ2w˲wFð²àãàûL8µ¾T‡ÿâ•xN)΋»4éh^:i›�§×*ê#·GÉÝpòja½FZ§3׋É﯃}櫪yínnðœ#|ç ç(ÛÛéöëÂýŸr_(ÝíÎϤ³˜ÈÎH½êùîwP~ê$¯ºÉ¯þë{ïŒå.� ÌcyUIžˆÎ®|tÎsÍû|©/~xÐ#>ô‰½âG¿xÒ ÛQÔ«>õ¬ÿ8ÔCN ©S�VW×ÿái”øßdšØÜý¿Ç“±�¬ì—i ñ3¿ÖÍûÆåÈ¿þ…ŽÁè5á†f§‡aׇ}Mg ˜€ãzÜç}±~³'~µ§røÖç—~Žsì÷î'2ðgó·vÇW]ø§ùWS�‚*¨eÿ'8a8\è |—€ HaŸòzß~õ6�YW�Øq�»¤~þ¶�ƒÐ�ð�òwyÅW>g8Zf‚'S*¸‚0Ö‚hñ‚Ô¶_Öw}5hƒ¦°€9Ø€�7x…W)8f*¥Rçw#B¸}Ó7xB `ÇFx8&bíÒ'tBÆ‚LHÕö„Wƒ(RXâR…)È‚ñÁh?ÿ¶…Òµ,3ø`†8ˆ:ø€<ø'–†vµ†¬p~}h4oXq¸4sX‡w¸z‘‡º¥`‚Â2Ú0ŠXð‡K˜v˜'‚Üg8†(…‰¨ˆŒÈŽØ„µ_’X€”†bˆ‰d{‚'{„G)�ˆ`jŠ¢8Š¥H§è©v«¨­ˆ`õ‹±8%7B‹¶ˆ!Øs»Xˆtrˆ¿X…ÁXe±Öh0hŒ·2‰‚Q‰Ë˜‰Ï�Ñ#¿wî21d�DH„Iüƒ�) ù�ß2ãÐÙR'u�‘Ù{�Ñ3%³Yk(^„‘G›f´¸)Éaf&9z÷’y“29“1y‘ïv]bÿ�“ȃwMC“y`“ï�k iyô->¹,t 2�ØP�yC©�ý³ ‘v"‘i‘6©‘)v‘á‘’w•!±‘GÆa’£ˆ’±¡’fÖ’/©w>é“@‰“:™>{“ h&—6)” Y”vr”·’”l±”ÌviN‰#É�R¹=ÉQ•‘Y‘@ɕɑŒ–bÉ[T5’t–dq’p’’­±’nù–—49—Ö•“b°“Ó7azy‘|‰�~é%€)*‚ „Iv†‰Æ‘›²˜zD•Ž ™Y9™”i™x�™í€V%’`–­aá¡–›Á–>Vš¦Id¨9“ª¬™ÿ¸_>i.$pžè9”µY$·Ù(¹Ù ´8”¿Á™ESYŽ Æ)™[™œ^y˜–iÎéRÐ)�˜‘GÕ 'h�É¢�Û9\>™kßž±1žÒ…|“U*虞}©AFI“H ;Jù!ò9ŠôÙÀyŸÖ”I›� 0j•û*XéŸï°5”éÊéjgÊOÚ™­¡ Ë±) ê‹*‘Ê�4I¡6I—­y¡÷˜¡jžJê¹=}]êt›¥²5æ¦%š#ƒc'Ú‡)Š+Ê¢pM±� æ$£4™)u8  Ra$‚˜uF .øœ² D:<2 ˆz¤&rKÿʤ3é¤ÉšZJ¯ ‰¥¡´Å¡Wš¥=°¥+Ö¥"Ê(_ª5aj˜…eŠ`gZHYŸ›Á¦;â¦/§�I$szœï¶5æ²£Z±§–q~?ºOAÊ?ÆQ¨žq¨‰:aúw�Jd@ ©R'©uI©x9¥—Z¥Ír¥$`Üã©�^E¤*¦¸õEÕ‘ªßµªÄ„D®Z°Ú¦.ªŸÅy•tª•¹«*!Ig!¬j �ZƒúÆÚÈ: ŠªŒÚ¬¤õ¬G”Ò¥ÔŠ¡×Š|VÚ¡Ü ¢ª¸I¢åŠª"c¦b1Ÿ Ù®„±)+9‡�9¯^R£uj“æ’£zº¯OÙ¯~ÿš…€J–‚*¤ ªA ZˆŠ°ÊŠ¤Ìº¤|ç°±ÒšF«N˜z±è™±ü#3B2¢‰3&c¢g»�® 6²(Z²*jŸp’²x²²UÙŸ/{¯Í"³uá«dá¯8{ww™ ôP·v{·u[¬>[¤;´ › »qYI‘G»—GöË´Öê´Øš+Ú*µÜCµAbµ[ƒµK¢µºÁµU$Ûªaûªckf*û‰¶öꀹ¶tá¶}ê£ÿZzs‹·²KzË??ë·C»¨Û§wƒÛ…+›‡+‰kLÕj©Œk±Ùz¥�»=’û ”«5–{˜+²ˆ–}ø®5\B‚f"g“,µ7æÿÔ3ЍJK³yB8†cz‘lµá0`I4b�K<’ßBø›¿G^}5 ’G0À¨€(ÍJ5@i§°“ 2”F÷•xˆ½›k ’6¢Rž1jâÛ4ùW…év¾âÚc"-æŠÕû™i «Ù Zt½Ý”ß›4á;¾å›Jœºék4ë‹`íË ¿)¿EA¿;b¿v’¿ù‹^¥µ:ÿ«A £ܨ|À7šÀ <¿ } †<¸|\"aÁ��Á³Á*ØÁ“U¹K"ÂÑQÂGšlšÂ…(,|À/œ 1Ü4ä[…满¤¢‘ê›ÃÞµÃPÑÙ%ñ{7óÿ[MC÷kÄä€ÄF8KÌ?M<ÀtRÀS#ÅSœ8UlÅo‹Å,…¾ÜÂÞÛYàkN2ÌÇ4ìÇöÈ8¼ÌÙ@È.ñ¾‡ ÑÓLÍÜ3Äò‡ÆB'×\k½É6)ÒLÒÛiÒoµ5)ÍdXÌÒ&Ø»/=_ìa¬ÊcÌÊeLÏglÏi ½kÌÓ¹|!q#¯Ô=Ô0…ÍmÇ ÃK=ÌŠø´¤‚’M‹8Æ©ùI†@€ý‰¬�Ña€f¡…ͦͫó�Ý<Òt2ƒD¦�fMYo“Öü ¯ÁÖ R‘Oý€Òr#ÏòìÊx Ëz-Ë|MË~�›½ 6Øë%¡-ÚQ“Ø.¼ØxÜØÄœ‚�m’�´x~–͘±ÿQ‡ùqÜ!¡RÆ1·Å{JŠ$Ú_M ¦½=—| ðߪ�a¬ ÖâüÁ¯Í;á%´ý)¶ÍÐΑÛí±ÛtÏv=Ïõ ÷<ÜùŒÇ�Ü‚±žDÒÜÎ]Ð]нE­Â\ÝpÝٽݙÖÝÃYàm&â�R÷TÞs ÚtRáCFÚ„ÓÞ=ðÞñ ßó=\õÍÞ�7Îù}9û�ý�ÿ}Ìÿ(à2×3]×5}× ¾à Ü×Óò×dDy‹áË]$îÜÌÒ½á�ݸŽ�!þ¡º´uèaë1åbCÞ­aÞ,\.žÍéUÚOj]ܳ)5nãˆ(9Žº<î6°]³²Íß§¨°þM‘·ÿ]äÑ¢ÛHNÓÂ|Ó9ýÁ;寭æWåh!áàÒâq¾åIÝåÔýåȋݓ-æv&âÉqæ-’æƒ46lŽn>aY®Þ0Ò7içÛƒçy>ƒ|®¤“ìçø èú­[³]è€{è��è¾èÞèJþè¿�ÓÁ­ÓPÞÓ¥ñகéW>áœîâžþnJÝÊîá¥Þ‡ÜMæ—ªÞ!¬9¯±N^³îѵnßRw]w'y~ ¼N'}¾ãÁ¾�Þ2dQìqhèBŽèÞF.ÓŽÞØ�>í’^í’qÑc�ß’—Ý“Îó–ýnÈ'Ù…ÀN“Ñ ÅÙ�á¶)ÆX¯‘ ´h¯ÿÁ#�x×m=¸Ë‚©½Kd6Ú oÅ ›Gh�€A; �u‰TóÔZ³ì?`–.:³qàÔgïæR`*QO³�€áÛÊ—H‘¢²T[ã�”Zwañbƒñv¢ñßñ/ùñïòx0ò0Zò3yòœò¾ÅO,ß./0?Š2/4OŒ¾}óY™óºóÖó?¿ A¯ACo Eôiö)I¿¡KÏðÑâô­.L'õKn©Tß,VŸXïZ/Ì]ß_ßNaßc¯dËùöƒöjõ7Ïñ«ãñ6 ÷r§Ômò(/òy¿O{�}�߇��ƒOólø‰øÈ§øÃÅø”ôÒ*ôLÿAôAKù rù™šùì -œ:F„ ¯úkÕQ£Ÿ+¥ï§ß©ßØ«ßúÞðúìû½$XÐàA„ v`ØpÛCˆ~ X±ÝEŒû4n$ÐÑc�!E‚$VÒä”)U¢¤öÎ¥Ko1½áÁÁ&*œÅí72ÚK ïhÖ´YtÂQ¤”. ÓÔ)¨Q+VdWÕ*¬Y%n›Jq©<°;ÅŠkTÖìÙ²ÕÔ®•)sÖ[¸åäÎ5û²›=¼xûíÍÐWÌ_À=žjÊÜYÅâ`lRf^{{­þ l¶ˆÜ4gMÓ9ͦM:dž#®$PÈx­vÓZÛkØ[=§1Œ±ÝÿXqŒq¤eso?«„ ^\áqäÉ6t¸Ub×¶/näè±ãHìyLž\Ù½%ж4‹âD%Z\O‘?ƒºZÔ(Ò£K™:mUjW«W³bÝ ýkXÜа‘µzk ±·æ¢«,»Rû­¯ ²‘pÂþ*2 1ÅvÒͱ˜ “¬*Ê~° 3ˆ4ã†3Ï@3o§ÒL#µÔV ¤57`‹M¢Ùj[17ÆxSK¦ß‚®8â”3òH…˜cȹ纒®ê4²îºìDÚ®¤î¼ *<¢" Ï<ôBRo½öÜ‹¾øä+€¾úìºüªÚ�¿&§úOÜÈð¬lËgQP®º\ºËC¾úšÿ�Â:?¸® yÄ�Co�¬²‚.Ël3¬fSñ"ÜZ<í¥Ôì‘‘F_“Í3AK7«òCv„“€È"‘Ôu׆nŒè`ƒ­(bŸÜ¨´) ÀîOo®$&Ë•¾{‰Ëñrrõ<ŸÖcO<3ÁòOÜÆw\7ßÄ/N2ÒÕê!Ú­´M¾PœÒìæ^|û¬º@-§ÐwÍëAEͦBŠ}+Ò Kzl`à@Ä” MKä OC»–ÅÒFu©TeLU›`ƒÍÑÛpƒ•@ƒŒBãv•ÙÈ^U•¨d`‡-VºcIKv=f�gh¢µO&n½´ö6ž²Õ¶L÷äw¬qÇÅÿά³Ž“�tÉXw›v x4©Åª-|óí“_ýX`½�Ð`„= Ò}kÌá!¾TÄLI|ÈD;û”i³;~qÚ?C^mdœ�89åW{dÙOo\Îæ\göâkŒ±¡‚pˆ(lQ=¼Ûº')JYJb€£˜à¶A¸ó.}¡RÜÑœè8(¶KЬBYý,w?ßÐÊ*YÜâçºÀ0Šg¥3#=¢F™°±�Ç%XA÷]°Zå©�s‡Ç<~+O"ìcðþxBÿ��HÞ!—C´9o‘iä‚Ñ Hî�nÚ«$÷ô6)¾UÊo›,âà.–1%–2v2yb*WÙ™V©¯Š—“U,ó7Ëýu®–»º 6`c"q@¢][f”ö1�ëÑвi´$=i?L{ÚÔ®V¦4ý“Ma+[�Ö6K·íCnå³[£’¦ÀÀ½SIàT¨P¼bA.c”›]µjµ«^ÍX"Vê"κ.Æ®À~³]"v7Utå@×î:Þ¼š÷ièÿU/`ÙÛ^÷ÂW%ò}}í‹ßüi¿Úè/xŒYThV.ýmÓІŠvÁ ~ðJ# Ó GãµVÙl5ÜûG·Ó)joE\fÈ÷ÄÃM1W¼“ãàÅ>Þ‹ŒŸ[ãèÞxº…åNv¬èk·­A&ˆwý[äðÉ-RòýÚd<Ù½â�rJ¨lå89–ÓY6Ò–»üßSgÀ#6ó^Ð|5�–Í×<­Þü Öº¶Â°ý†wzg•ä¹+B±ŸÃÁë@—X¸Û ®qY\޳ZÆÌu4W¡«鎕ÒeýF¸—ûãMOl žöò‘aXšR?óÔMVu”;‚X�(öcŒ�õÿ}gMëäØš²^ÎõFv h¬žù×Á&­GÛÌÒvnD­¥p[,ŒÓ:gÚ)‘¶�ö ¥>—÷H%q7LŒââªXÔßv÷¸SnÛx8^wuÛ}]q3z­ñæä¼‡üÝÿÚ{}ø _…Âd~³wÕ­FÉ«^ß‚cáÈñ´‰ºÖ5ò�Ç¢ÉÂvÄ}ýë¤]í ŽÅ°ÿ˜ŒcÈ¥p渜—Mçʉ|ä³ô,1«üÏ,O�‰_Nè˜zæˆ7ÐßÝhçšÒè–´º¹y8±\zÑšÖ:äÊ_Ê~=]O‚!vL=T÷{,ɸHè›!¹5³ÀÖ�Óu͈ž aÏl”Èÿq¼¸•2¿Æ†ÚÕ!5x+pGmÆçŽì8;ëã± ¹nô¥á¾ÿéïK üÊ“ Ão»Û27O¢7ãÈç<Ò;Ÿôå+-ÍgZ­@–·@>ÏåЋžôëÃŽ€Ð‹‡À›‹á#>ãK;äë 哿36çS-º«*éc6gcŒë«­ìk‹íSŠî¼ïË‹ð4n+4¥ó“?rK¿sã†t˱Ìû9 :Î;8σ«É‚(ÝÛ¿oê?´ø¿”‹œ’ÖS²R‰=#d@ ¾‘+/;Þ¡d¹Â8¾ÀÀ ÜÀ @6lÃÿåʸľº+AØ2½ HÁžZA™€Ž|Áp8°ß˜A˜ó6Æ«9¡Ã¹üÁžÓ1!Ä4"œ?¢3ˆûë¯%”ŽÒ ¡(,‡î À)3À«ƒ½ª�µÔB.L/ü/0 ;1œ2Ì3DCãSÃ6tC„Ãæ“»9L¶™²Ã›ÂC ÐfûòâØðCÞDAÜ BDPQÝR-)S5'ÖäH×ÄR-}Uu¬œÕݬÕÞ¼U 5U�HÓwXÓ_ýR�ÑXѺLÖ¼LQìäKÿvðS@…Ñïœ@ë Qæ²Ql­=mýSFuTH•T€%×JµTfm‹”JWM]W¶jWŸdÀx%œÍY5Êâ,ÎR)•ãª|ýäRá$¯I ¯d�ÂUáü™ PØ6ËdñÊR!HD¨Kd¥Î݈ÌlÖ­!¾þ)Œ¤Ž~„¤ß =McUϦ`;b‚ϕݎ;W‚Ù�Ù3 ùÔ&½ÙœÅÙ�-Êž%ËŸM� ¥�¡õœ¢UУͫ¤Íƒ¥ý“¦-ص„Z �ZùxÚ)±ÚÔÀZ­½S®ÍS¯½’ð Û_ÛT*Ûê°¥TÛlUˆ¶íÖ·]°¸WJU g©Û?ñßý]ÿ¼Õ[¾m ¿ÝOÀ ÜÁu‡Â¥†Ã…ŒÄ]Ü™i\Ú|܉ÜÉm‹Ê5ÓËU ÌõÕ©5ʪuž«%ÈÐ�ΨÎÒ�O°�±¥,²]FŽõˆ×…]ä˜]G-©Û�Ôr- Þm‹ß^˜Þá-Þz,ßÀÅY‹Îå-}h`~Þ%ÚT‰Û„U°DÚ” ¯\EÈÞßäÜ4 èxö¯Ô[еS/”XêøZyâI«h_ˆzß°#¯³Í òDTµ­ßssÛ‘²]ªLfQÊÄý_ß ^™^7 à,Ã>`‹š-XàÔpàZèUŽT´ ®àÛ\K ®ºkßHkßÅh¶f58åèa�ë˜ë]©kÿ÷¸k¼Öë–~iú-ÀìƒlÕ…¢pö×êãéz^ìüjÊ L¢>Šwֈɦl¥¶ì§Âç§ÒgÐàg�ðç™h<íÒ.‰ÓNmÑyˆ°kÀhD* ØÎÙöÚ–R7µm·Æm¸¶Š�êÏIæ’n•Ž“½väÞ:åvßTjîÄÅÞ^UÇ®îî¼î Èî}ØîÊ.çËÎìÍîìÏ>o«hhÒÖjƒv„¦…–ˆøN„ÖŽhûî8´ÎµvŽÚnØ·ŽÅgì‡]ÑMGéAXr&?î_¨ŸáÏiqFlrŽn 'ðtÎp� ȶ(ïnÿî¦ï§ïÿ¨.ï©í—ø?õvqÓ†ñ®–ñ¯¦ñø¾ñú6k�mŸíµæo`mk‡µØ!¯¥d>òÐLr6`ò&/î'¯%c5‘È) *áŽ0f¼H\'××q #�ê%ÒØîž¶R/uðf…Á ᡪmŠ’Ã^f"|A!èн’öâL°¨‰Ôs»{áŠÞŠÂÆ£¼©[^.¦DôȯCGt×tMF_òMô™‰t͘tJOK'L·MwôÆÎÒN£O? 3 õÉõR'õSOuÁXußiu‡W§‰XOÈY·‹{±õ®Àu3Ñu^Ï+‰î¸�‰aŸòX ö¢4ö7N›¼HvDgvÿ#wög'’h„i§ö]±vnÀvJßönÿö†,V5OO%PQ¯çug÷2Guw‡÷ª‘÷1©w<¸wî9÷%¢õ}?¡[½\÷â€o‘�ÿõ‚Ï�ƒgn’Rxw`xëdˆ?r‰W[e¯x‹�öŒ×x$áx�¯ôí}zñEÜ Íz™)yÍ8y(Jù•/ç–·†v�ùµduy ›ÇùžÙy}ï~Ÿ w€�’^Ÿè£·Š¤›’bz§7á°·‡¨MÈjö#·úâ¸x²×zåàzœÉvmÿzÅÇe™ù WޏŠ+³ç´›”×—RQöûT—ùq¡yº?!X'YÏ+“Èû½¯ˆÿ¾/Š¿§ŽÀ'x½0x‰ö‹(ö—:öqküМzÚ«zÉÊwË—Ì/Íy8þü±§þ]}¸*ýÓo—Ôï“ÕßÀÖywïØÙw‰º·}|Ç}�©uŸïw ÿw¡|�ˆF�¢ôfÐÂ~ì.Üæð¡�ˆcQlgÑÆo pìØí#H„öÎ�L`ò$€”*W²lé2e€˜2Ož`ó&N›ƒvò”)ó%РB‡º Ҥܖ2 ãôi¦¨Ý•«j•Ö¬"EöëꕆÏEƒb+kvÚ´ÚÖ²}QbD‹rÛi¬ûíÞ¼[’ì{†m[‡¬÷(lxêÔpŠÿçÍûîq¼È† ϵîr…Ì772èÙۇТÁ�.-ï4jqªW[µ:à5ì<²gÙMd Üøvó~úðàv5,m¯=¯æ–';ö9ôèÒ§Sz4)R¦M}‡‰šijëªYµîõúÕyufϦE x­[‡pãV~·ñ3ä~I¾×öp0+“†F‹1†ßcïD�€=TÖÎeàdVg}f�h£•Fj©­¦ZxåÀÛl²ÕB¹Â[oÜ'ÜpÆ„œrÌ¡—Ž9긣P×a§ÝRÜu'F!އ�æõ–O8®WV{î½ß6óð }øå·×~M)aèÿŽ�Ši™à‚ >á„vva†¡mÈa‡ò|bx#¾V¢‰Ñ؆›n,â#ä‹ÀÙ'ãqåuµœ9Í5É#¤‘J*��J)¤wà…w$5IšÇäOÐÉÍ“ØD¹ATZ‰åpZê·_ª`(&�e†s&d’ ¸&fšUx!hqÎ F�vÞI ²Éê9Ÿyœø + Jh¡‡Êè)£Ž†:)·Ýz›R¥Ù]Ê]¦Enz¤§ç=vâj‡¼ñž«[«Ö×*~¯úE/€ Ži+® ê:¯úʰq~0l±88üp²ÊêÙì³·¥(‹Ô¾h­qØÚ¸î·!‹Œãþmc)7¨Œ)‘ÿØUX¡¸•9n¸¡î¶@µ›Í¨ñÊ%½E�F=¸X]®r ë—ÛôK+b#˜+ƒ»VÆæÁ›%,ìœ ?ìpÄÈ.K±Ÿ3«(è .V㵊ö“í�#Ë=÷X l³Ê*sÀòwÂ,žÌÐîå 4àÓP;÷ì3 *L%ÑEÓ7Ò)½U—A;äo­eœ šWGx™›ËÚÊp�_ƒöØ|VŒÚÃh¢77ݹëÎ’Ýx»«7߉ý]NV3‹D¸á]�ЏPŠÉxã>_äFWVù}�éÛ—æÛpµçS'øNès�Nz…¦ÛZ¦êíã61­—øú^±«½1Û» ÿ7È»ûŸ{¸x6.ß”‹*çOº”‡;—8ï]Œs\œT5VÙår"É\Óò=áès�)Ÿ\ÎŽÒéi}ìsß×à'?Ú”Mp[±Ÿo … ŽÇvÚbÞÿr8·Ž*xæj §¸¤¶¤�L�3T€%2ÑJyb,ìc«jP±ŠÈɳH%´™¢‹^üW™Æ'FÐ H„$‘ „†­ŠU$ÛŸöR�9ÒQ‚pÙóX»ý},g:ü£·xø<ÆÐHG–’†Ø?¶kq>K¢h˜ØÄù@‘"R,“©xÅ,bq‹‚òâ;g 1ޱA"´�úÒŽ5B¬�™Œ,cI¿­Ð±ÿŽñ±RóXÉXØ�ˆ€ü%�é@Ÿò€YA¤’–'–æ5r��”^œ$¹D'Vò’Êd56ÉIO²”]ã(I9>Sž•%Tå*Yù>Wº1–²l¡ÅhYËzØQ"¹Äã.{¹H`òsRý9"¼„ô }tBñŒ§j’0´¡IySx£22P” ‘{¢4 ¤E £•!jÆ!ÒŽt9"aÈRªÒQ=D4÷Ü„}š5FÏ&£©¸)NEªÓq˜ §>]–›e›�«Ac8*RÉ�0µTT¢*U†0¤K7é'VCöÏ¥ÄK •!è> Ê„ºM¡8i¨C‘Ñ¥H”ÿµ(Ñ0*Í� È£-THGJR˜!(UiJYê—Þ3¦|š©Aj*Mœæt§<õiO�Z!¡µ¨BjR•´T¦¶ä©Ü‘êT©Ê«Ú$«¦åÖV¹ÑUî ´ ™9èAÊj’œ­ }¨C"º›‰Vô¢É(]'c׎‚ô4:Ý+_ûúWÀ v„Í¥aK„Xo(V’Œ½©c YÉr†²¶±ìd0{T¥.„©?èl|  Z6ˆv´û¹êiãË£Ô®Ö7­ ëkÇÛ­xŬ7±-p{7¶îÖ­½�ëoçÊŽ·¸ò8î^ûj�å®H- ÍK£;›éV—‰×MEv!Y=UFCíÿx #Þ1�—æŠzAÛ^Ò @¾6Î}ÊÚ¯º¶°õFBg»PÛ X·øà-E}‹b×0Ã�€ƒ!LR S8°,† ;™Š‘¦…±éuC,bînÆ» i¯QÅÛâ …¶ëe¯hi ßÓY:9Æ‚WçV±€¬üíŠmà"øÈN2‚—\§&æÉQÖ딕»ÀZY;þ@†·|Ø.'öË‹ ³cEl2 ÄÌAóeÕ¬Ùòr¶Í9ys{å\Ú:Óú9nîS<*°‚¹cLd_þKdµæ¶ÐH†kžX¬;‰ƒÁO¶ë²UÓ‘ ”¶[|x“GÃØ§.͘ÿK„q“[Ô¤ˆ‰‡Ú^óšwʼndw«ƒ"kœð„'´­5¾mm[\;E×á5A}-F`“DØh%47ÚúV%GûCˆZЂžÜði£«Ú¢½67·]˜nkäÛJä‡ÉMîŒö¡ä&/±qN¼nxÓÞ.?¯«ç-€zïäÞù¾¹Pn}åm亣»¸ÀÇGð3<­ÙXk ¼ðD7|5‡x<$^§ÕP�§*Ƴ½�÷€ãßðøg@~]‘�›ä&/9Ê‹£rѺ¼å/g÷Pd®šÛçvo‰Î-í�žGàç¼z‚†~“R!\áN6Eš®š§C\ê¢:G¨½kS:ãxä6ÇÁî™ÿD@d'‚ÙÏŽ‡Ñ“¾ÅíÝ,»ÝþöxEî3§{Nî.û•ä�)á»ß{½×_+)Ø6!<±œtC/ñŠ~ü�ñáN<òŸüÅ+¯u|pÝëš7ç;ϊχÞä¤/ýªO�zóª~õq—;ÍQ÷Ùß½öK¹}¿}þo ï~à½/øïŸTx¥^ÙSO¾Œ@]Ô1ßÿ‰CÕ‘ôa�ô¹…¶]ÞÆeŸ “yhßö‘]÷•Ü÷�žé‰_ÛåÄê±™¼¡ìáûÍÞµu ²ªÌd´Œ•Ãbðžyx Ö 7ñ†Â8Z¡0raÓ) EÌ‚ÎXYÅÃä… %GWô…äÿDè�Þ|že—„‰DÝN€na{9€~a{ÙŒºAX,S ža|¡`°Å¨° a¸ U,üŒQâÁ îF6ØÞIfÒÆIaVÅâEz:a¼‡žV¡=\ᬭDúuázaŽ!úvâ©!‰V…† fàâCÚ• ñà^ù a, !”: Æ“öC"âÄ"2"ÙM¡cAb$bÑœ©D%ŠÖ%b¢hiâ&î“'Nãÿ€âZ´!´`ßüÐ)FL*~_ƒ M+ÞÕ‹À"IÉâøÐ¢-b9â3â’Dž•mõG#ŽÿÎ#V¡$ÖK¤m5£ÐV–!5ä'¦à5Šb6¾á6¾`7&Ë7’ž³yÔ8v³™cG c‚¨£ â"!ê¢!ò""Êã�¡•=£##$îcKøc채@r¢AÎdîX£6`£6"F*ÆŠQNdGUd\$Æ¢Î" ÖbGîC.âÀ.þ™/’$=š¤0Š1î”1²d?Ž`2¦DLJ#M†¥ÜØ$N2¤Nš"O¢¢Of PF€Â(ž8´OG$r$ÈÜ¥ÞˆF !;º#$²Däèµåh"߇˜& æV¨æäehìå-2åG:eHBå/&äfÙí¦x%¦oJ@cÀcv%'!§}r‹rjÇ(ö@)rf8ôäøüdhÚÕtzHuªÎ\>F]>Æ]n'kv§k~gS>%WÔ¦` Z=f�C¦xµW{º'p*£pòãJЧÞ'ŠBJ~2Å~ö§stâA[z‡wÀ¥ub§Hh'w~€wö¥lþeyb(U•p(fyh{¾g|ÿ§WJ¦L¦(”FÇŠ.E‹6äNþ§Z([¨GÑhTØ(‚ž¦‚¦&ƒ®&´æ:¦_Ò&`^hme(‘Ƈ‘"’ú¦’ŽhK˜h”î)޽4(T¸ F´€&H *¢ ÀíFrüãDª¤&…Þì’9¦f*r´×dErÍØ~t*Ÿ–j�ýé]jCªê¬�l j¢ÖÉ¢6*<*$Jê¤"E¥VÒ¥f*¦nªh‘êt¸ž°šª±žª�ªŽIû¸jÀê¡**ÀѪ­V!®F*¥ªŒ¥ž�¯þêÕ1D±F±>é±–«%ë²H³N Ÿ@k H+¯- rU«„]ÿ[¶rÀ¶ŽN·:r¤_¤¸ž¹¬�¡«SÐT¬ëˆ4˲Ë„Lˆ¼F$B£½êª¶VÒ\,Æv ¨f€¿B À ,ÈfÁɪºÂ’H‰,l�4lfäFˆäê-ì†ìbÎ~ÔnJÝn{x®î‚.ïê¬ï/öjUBjGƒ6è˜ØGve—y“)Œ‘1"£0Ê=¬/û&ÒÆÒ„Id¯üÞg(jGj1:ä¯þî/ÿêïøz“ùž/Tzû¶¯’¼/üίWfý2Åý.EÿF0ÿþ/(°'„’ðúº/¨Âo,0Ód/ÅsƒŸ0:P°µ×W¨yhð=p0'…0 ‹åsC £°S ù²p ÷"k° gQ ±AÞpëÿpÿò°7ùp ' 11Sf+ñþ21(‰U# ñƒj�ñL^1ç/•l,s±dú.Ç{’±³ŸŸqƒê‹_7ã›CÏ1 ã\cñsRŸ@&’¿ñ²#ÓÚ +q!gÑ![â%*23rˆ>2'Cò{ŒÊgq|¨q%SU"+É"§o#w2+ç4ÂZ)34¶2-ÿ.mò*ײ._í-çq.ï20 ¬‰Žn03Èóõ³2 ³“ú1/34ó)2Ë\4W³±Nó¼Y³6ï)6ËÚ63Šv³œ�39§8ÿr9§3û�ó&«³;¿3<dz<ÏŸ3=׳=ß3>ç³>ï3?÷³?ÿ3@´@4A´A4B'´B/4C7´C?4DG´DO4EW´E_4Fg´Fo4Gw´G4H‡´H�4I—´IŸ4J§´J¯4K·´K¿4LÇ´LÏ4M×´Mß4Nç´Nï4O÷´Oÿ4PµP5QµQ5R'µR/5S7õ<v¨¡¢³Ss2T'…T£ U—k@!ù#, ±ÿ(°…Á*\Ȱ¡Ã‡#JœH±bBƒ-,jÜȱ£Ç� CŠI²äÆŒ&Sª\©%Ë—0cÊœI³&D—6sÚÄ©³§ÏŸ@ƒ’ä)´(H¢F“*]Ê”%Ò¦P>�JµªÕ¨S¯6ͪµ«×¯1¹‚*v¬Ù³h)bLkt-Û·pãÊ�K·®Ý»xóêÝË·¯_°"L˜…áÃ;+^œX„ãÇ�c˜L9€å˘-Þ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°A.|Ø0ãÛ;"ëA¹ræß±ƒ N¼¸ñãÈ“+/={pmÛ¸ïŽÜ{òoà˳kßν»÷ïÊ›#ÿxÎ"ºôÈ=Ò«_ŸþzfððãËŸO¿~pñäÍ+¾Â¿?ûÿ=Œ!à€ØÙgà�&¨`xÍå§ßýùàzøÞ‚f¨á†.à¡xî@ƈ$FÈß„V8F�¶èâ‹0*çá*Ôhãmä¨#‰%šˆ¢z*®xaŒDiä‘£Íhã�Œé¸#�d˜xÅ�éÉ"’Xf©e‹J.©ŽNre”>Riå�[¦©æšóu¹$˜NŽ)%•ªèÀ�x^Éæž|ö ››L.¦˜PÎi¦�xÞ©§ŸŒ6ê(AÕõ¦Ã¤”aé¥dªiœvjħ º ê¨o”jj]¤šê 'üàêÿ'Þ£´ÖJe^ª@i¥—Zªé¦�r:ê°Äšzªª«¶új¬ÆÍjë³Ðn‡«—»NÚ«¯¿z¬°Ävkl©¨"Ëê«°ÊÚ\´è¦kÜ´KV«C¶ðzüôvëí·áª:î²æÎ¦î¿»Æ®�î«ÇÁÓ[¯½Ã~ûF¾É’ËlqÎlñÅ£ \cÁÙ"œ°Â00Ü0¾Èv±¯«W1Æ,· éd¹RzÄÌ{¬È!kÁÎ<›àóÏ›¬,ÊýæòÑ.k¬ë¤3Q³Ç8wËsÏ?ûôÉå6{.Ò\[¬´Ì4wlsÔ:OmAÕV—ŒuÊíÜõÛÑ~ÍtØ¿Ú|3ÈR›�¶ Wÿ�µjäå*¸—pþ¨Ü:4ýôÇ ç=õÞ}K RàƒWžk¤†gŽ$⊋ 5Þe?ŽväËNþœå¨Ûˆ¹æ¬»8㌷a!ûìÔn{¸çŽFôî;ÀÁðÄ£`üñÈ/ÀòÌo&^ÐGâm[Øgÿ×öÜwÔÙëÆ>»ì¶ßž;î»äûïÁO|ñÉÇÚóÑC?=cÕW{}öØwïÿÿùøÄ7¾òÕî|èKßúz×>÷½ïñ“ŸlšS?ûÝO1ùÛÕþøÀz!|ÝmÂ@Âðék�VÈ � (Yâ—€Úp~͹ b ÀÃÒé?üëßÿ‡Ø½ÂŽ1%4¡SÈÂ.P†2¤¡ kš\…hL=ôá×Ä ñ‹ a f—DÚŽgLl¢\Å’IqŠUôÒ¡”En‘‹A£÷"Æ)†Œe<ãÎÒØDßáá�mDÖoØ¥ÝæZCÀbËìñ’téã—È$ Ò„t"‰‡Dªj‘Tl$ÌäÈHJ2‹”œP fIËÖÙ’>à[À¹Äô©q�½#¥)S…ÊxÆ‘­¼Ö+µKöв–·Œ&xr¹KOörw¿4$"‡YÌc®òMÉìÕ2íØLg>3H§:¥ÉN ‰¼,_(W¨ÍRsøÌçSÉÿd.Æ•tœd9×sNtª3�íL¨q¨ OkÊÓ—j¬ç0»�O}îÓ›°b8/5N( ” ç<(BJÒà¸I1 H© 0�–N }0½’@ÓØtÓaHÀSò¬Ž =d¤´…¢T ¢©R“ ²Q™á©PEê§x@ÕªâéUƒ@SI·Zš“&&¥ X©K_SSÍ´¦7^ ÖÊÖ�öô9?HP£¢µ¨R5ÂRiÚTQA5ªR­ªUï„U­rõ° ñêÀ*V—ÂT¦óRêMqz¶¶•?<%�O«³™¹6&2v½k^÷ÊÔ¾þõ©y,U¯êª¬b±° �bËRÇÿ–µTgMÂdÕjÙ¸U³pål`<›Кè®x•*iûê‚ÓšÐ�®jyÀÚ¸ö2±Í®&QªÒÚ¶ô±f�,ZmÊ[Ëþv³½ÙŒƒ&)Ù gË%VæKßúÎ7ºÒUmu¯«íúW® mÇ ^ÜŠW·i­loÏÜôf½Š”{Dzv˾®~¡;Ýýö¿°�mw |Û7äv· 6¯‰ÐKõ>N:šðç–B³Y ÃöÝ0ˆ7ØDñ÷µ ͈"â°z—¬�…�dÜ[ßš(PŽò¼@å*C816Ñ{+œ>㸾:æñjå€c7È„r‘ûÝŸ˜ÿÉ ~r”¡<å*SùÊ;Èr„¶¬0ÒzùË÷ݰ˜©Kf3÷×–”³\v×|䛸À(n²”æLgöØùÎ/nR{µLá>ïõÏ€óðzŒ'C³­k¹Ltår¹UF“8ÉK&oŠ/!J‡ Îv&�»•W>çV© þ²¨/@ê;™:s©>êX]RWÛÖ㥬¤å<\�Oú ŠÓ‹OVãÃã¸ñ<.•¯Z#Ÿ ž 8»”ƒ\K-gÍËYYo œæpèwþÝ[�ïœç>/8ÂG¤ð…3Ýè ƒ¸Ò'~w§ßê�: ¨nõ€e�6µ¹ÍJovžÿ§ðY ûjÆβŸ½vûN»Í׎ó¶ëœçˆ» æNJ1žÍ.U‚êWô&&} °�}ßцqÀ žð*7üáÇSòÄœ¾ñÿOAE$É«†ò�Š9ðó�ùš‹¾l·¬ÛWOýê“Þô§zõ•Ðz¾>ö°Ÿ}ÿÕj¿ñ¢vüã¹ØîyŸxÆüôÂ?'ñcdüÔ ß�î_>ÚÕ}¶NûÖtt7)¿§}Õ×}+ô}à'~?C~Qg~S‡~_§~»‡gïçxæôL4°�!‡$õ‡÷·I–7sͧyÏg_9pX}¹£cR€ ·}¨ ({Lç\x8x÷>øäF�‡g�§HKHx$â‘:§q¹ò{2woû·yôõK8³‚Ôׂéñ‚Ùƒ˜wj~dhƒE‡ƒOW~[p~U÷aB˜uDÈxFRÈ�‡æ�Íᄦ…^"…úW‚jw…j”…Z¨z\Ø^ÈxH}3X†eÿxwhøwjȆóÇ(ò¦j5"ùç‡SˆoñW‡Jx‡rnµ‘:zH�Šªc9⇗÷™ˆó…… Sˆ†ˆ;.%¿g7Û‡að‹Àèˆd‰§•ƒ·'�KH+—¨lK2ÎøŒŠÇ‰�xoŸˆ„vxu BЇaŠÜh#ª¸Ššæ$®H‚°¸oHpŽèˆa´¨0¶¨‡˜ˆ‹Ç‹Õç‹Àø‹Â¸€7XŒiø€k�mèn¶²Œ¥è%Ï�›È‰s¨•„ɸ ÚhÝØ�ß˜Š¬ÈãH…%ˆŽéh_ëH/íøŽºxzòH}ôX�÷h† ‰6e{;ˆ{‰‡³!�‡1‘ Ö3�ÿ¡#¶z¿×-t'' ’K4™+ºqre””a€“�á. ÷”<—”vƒqT96¶7�•Z¹•Y Œ=Ä“§‡,Ä•dy•” —j¹–€q?¹–kY‰0B?õC4i“Õòº¡“µ–Œç“”C >Eé%G©nJYFLéN •Ž)•6S•w•hS–\é•<ä—‹'–+d™[y–e”–p™m‰bï3šY —/B—Ñc—‰—»¢—‘Á— ™+˜ï#˜ B”i”‘�”‰YB‹)�é˜O ™#™“E™Uã™Z‰™P`›À™àœY šI$špYš vš£©š.šÐÿãšß›”B'´ zÌõ“dæB¹›„Ù›†‰ìœ%$zæ9)Æ •ÛGZÊySÌù3d zЩžÄB�dÉ* zØYB:,Ü)kï³ ¬ž-"ž@žª¨ 9!éÉsëù@íùž›ߘ+còöIB¢—.ú¢Åé˜ÝÒŸ{õŸ6 >3 #:˜¯S˜K’¢õ¹¢-ú¢.£P9£ÕçŸ6Š£& £Ç£Tê£*Ô™AJ¡µ+$ô £¡”5¡š„¡Hƒá<Í¡NZ“‘Ñ¡rBøf*ݲ7ƒÿv¥ñ1#›q49&\º+_ ¦ûÌE£Ke£V©7h3] WGÑyo¹Ó-¿” J“tøV²ªªHJlT%¤|*ŠLêÏQ�Ψ�T¤ÆI'ˆzoŠJ,Œ:jc–($:MFvŠP”J"*ê¥q¦. z?Ù©eZ£6ÚdñCªÿû[5ˬò¡°"­ ë°dP­{­ØJ±ïc±«‡±7ÕNû´‹<‹oæ ¡"«ZêZ²¡é®³z®µª² ʲöá²,³‘¬];¬TR¬p¬Ã’¬¶Jh<û¨ÏZy@+NB;´ìacyŽ›­<·­}å©Jµ7O µ½®ªUªuT® {®Y+X[û�&ûµG*¯·º²n8мZh j›�ûY³;i¬‹¬«¬t‹'ë>ûHAë°ÿá·¸9€´Ä£´ªGZˆ›¸ µÇ3µ÷VµW{§“+¶ J“— ¯`«¹< ¤�‹Kàã›�V`eªC/wGZÛ×qÿWâ«)¶3*ó":>S^U•ì›=&J“ªHÌö¹3ÕIC7Z{…3ü 2?y¢w ‚ÛG–F•?Œ<àFÉ#¤VðÀŒ}�-FpŽ»#*S£•¤„%ó�–Ž;0ìáRŒÃBµ×d¨ ëÄ%Õ;Ÿ×‹½  ½ ǽLç½Õ¾>'¾@¾µc¾0€¾& ¾Tž)à¾ñ ¿ñûóëõK-÷{-ù«\ûÛ¿TlcÀ7ÀQÀ\yÀ—À¿¸ÀŠÔÀ ÁL€+EÁŒÌ3|HŒ, ,ÂëAÂC/&üt( ~*²%ÈóĽÅHEZT\ÅfsÅXlZÜ\¼•^ ÄBÌDœ=º�ÄßhÎ�šX½4ëÌsCÿ×-¤ 2Tϧ<Ϫü)\}l_ì3 ÌÀÈó몋§Ë¼ìËÌr,Ì™v¬x|70Ñ+)ѰGÑ�΃\¨ãºÑcÕÑÖ|Ã�¼Ã�ÜÑüÓÄàŒÒâ¼Ò,�Š.í!èì³b5í¦�39m_ò<Ïõ Ô],Ô_LÔalÔǃÔÿŒÆÐklm¼3oŒq¬*s¼ÐVÝÐX­ÕÇÕKàÕ, Ö6’ÑT[GÛgÖ3ec8ÒÙ¼ÍÝ|6?sÒ)�=t]×w½y}·Ÿ<Ó××Ã’B¡ÓSƒÊXœWÛW†ÄC_CmE�,ä‚2Rý�­)ÝÔýÔÕ ÿ=Õ!LÌ`ÌxÊ¢MÑ ‰ Îì3kµ´Ú}åÑ‘åÚi=Ò%ýÖ¶=בQÈÒ¸RKÜë-czð=ÜéSÜ‚½Ó„-U¢ÇÜÃã܉ Ý‹-ÝÓíØÖ ÙLMÐN Õš]ÝÑ*Þä�Ì~¬Ìé”Þàí�@EPà"ãgfóÚ'ÒkMÒmmÒq}ÛA@È0ÜßðßœàÎs,.*¤…àõ5Ø©œW N†Í=_Ïݪ2ݰRݪxÝ™’ݾݞ*› ÞU�W­ÇÇÌÇÉ|êdâ‚âk ¹ç3äöââSã6 ãÚÌÖÜìÖÞ\Û7®ß/Œ½<þ{qÖ�äçæEÆÿÍ3ÈÀJw~‚ØDú\2RnáUŽá’=Д]Ж}И�ЗÁÙ`îÙb^ÞçMâ€æð)jNº§ânnÓŸöâõ=ã÷�ç”ÌV–\ĸ½ß;þçŒWQøÔÄ‚þ„Žo†¾WFN_H^p ×è>÷è‘ÎB“NáCå©hå€å›¾áÝÝáßýÎÐãíÐY=æ]æg®«·R­î <ëÕ×ѳçµ^ç4~ç6®ëáÌë9îë~ì‹'ì+@ì§Ç~oɾTË>_ÍnÏÎàŽÎä>‹jTíQ^áØþÚÎí-PÙpÙ™ÍåNÕ nî mÞê^âì>x6(C÷“ðÿµWæwUqŠçR'‹µpzO+z¿—ð|½p ‡­9 )v°ô䡯ø»p?9OÕÉ•n¼ €ad {tøæ»êÄMÈO?²ÌBK­–Ø*Áȸ,«@,LPA2ŒsËÁs8ÿp1;Èc�•�à aˆÄÓD쌰8‘´»VTÍÅaCÆ#0bÕ«²m´uK-Z}$¡r r¸!!¢(CŒâÊn¹%›kÒÉ'£œô�*¯Ü(ÉíZÒ‰Ë.ôÖ(²u”ÌÌDS½*×dÓÍ$àìpN�ÆÒÔ¿< .?í*PPBÉ8î¸*UÔBG!BÒI+½SMI,«ª‹`= TÔF%•†cu�˜HUY¥ÍÕÖQ5Z3°õ7r]`Wâ(֢̆U²ØcÍlÙ˰Ãr¹-»üáZœ…Ê�mÉôöÛpÝb³M75�]±nXÏ ôä^ºþœ×Â"ª¶ÿú^·òMTÐ~!xJ�;Ä4D na‹f˜Å‡#žØ×‰V5¢Uª^Õ 7YQèøc\u]HÈâ&:ù-ag^yI3]† fËd~6Ëš«ÍyòƒvîÙ¼ŸÑ Zª¡- ×èsÑUWDv›vå>£–/A­¾ë‹´~�ë ½¶pÙ°ï»`N¦*á»S5µ‡!nRb(¦ˆnìF1Öw㸿y °ãŽ|œØbòåIcŽÉY›h–¶;ï(§Ürò¸Í<ÍëÄ�o¹�4¥¤Gç¬t§LýM A®«ìb×$$P�‚rŠSüõ5 mh` â`ê‚6(Œ4ÃCAñÜ–ÿ<¸†yÎÃ[ôV3½Ÿ�¬W©ªˆ‘Tö‘bAÁ{èß”Äg¥jé|ÔJŸúrƾ1ùìIßJÃæ.Ò¹ûÙ�~ùSé˜Ö¿wÉEu€j h‘*)p�j`Sx»€IPl+[ïÎö»´¯4ôàñÞÆÂ‰Œ0cjܘôò#ê±@8% a ”ÃÎp/5ÌÐ É7hépÓ’A#é›[ùP<@LŠÑCD#Z‰ôSâr˜¸4ügOþƒ¥Æ:ªYñŠYÔ"ØÅ/"wbÔ9c6 jPE #^ÛÜB8F@Ž8:@OxÇH¦°z| föÙ=A€�2d·äÈGÿBR’@ÙÙÎ0ðMprK8ÂñLÌyNrá@�ëLÑF2’ÄSž€j%ÚIE ]@Ÿ¹ÔJ"5uÎsf/38‘¹L Ï Ê9G`(j‘Jµs,½A ,zQ‡(`/„é�WŠŽe$' iÇ N¤y¥Ñl\Z%„nA¦<úBMm”ä4¥*À®78<­p@( <#€šó8ë\gX:òTÓa4DU­ºÍŸt3[à '™êe(©¤“©8àÑ;E"Ïy¨ž‚Â'‚ÊÏ øSDW$\fN¯µ@ mè·ꂈ¦ˆGŨCXJ‘Žž.� éHKJ«“~sÿ§+Õ X?º•˜Ît7�BrÚ��öô§ª ªTÐ¥W¼*™tÁXqàT¨F5oSÅ*Q´Š®~“[_-RXÝäÚ²š­ñ¤g+Ù*À½�ìg–4E×�´>xí jïÂ×#8T©ÝP;KØdô°Iì(¥²•�ÞÀ±'0)APªR‰�w"Ç9Qf·À#ÎâT§)­òHë–ÓêÓ¨„ k] [¨Jµ—4¨íPn›[ ì–P–µˆX™Üw÷ÅÕâqQéÖ}.w+rå tzW°äUÀ{mC³ë×í¶»‚Ý xÃkØÊ¦¼ôÕJz×ÛÞ¼W”5…™+ûâW›@ÿùlh}êß¹xNÖM‹gªdà±"ø© î`‹¬3­BX 2²…׉axPfå�‡ï"(åÂà£$ÞŒ‰í:ÝWwÅxÁ®vû0•—滄oŽëÑÅúX$$e/dÝ+Yøê@¾à1’õ)ÓûnvÉ?i2ŸÜÇÿšvÊ{¾‹•¯?·8; ží‚¿”çvÌ Âž[̬N4ŸUÍb³› ”ÏËy±t>‹�ã‚⚨8¡,†‚‹ý hÊx·Æà-t‘uŒè#+šŒ²�‰läú^Z³«É/“÷ËÓOÃ1ʢΕm`êS»'ÕY^õ–[Ýe¿:«Ú*™ºÈ�z±–\<â‘ÿÍ4¼f³¾’oNÌ9+u¢DÒµ�ÑBÅ·B݃’:-1\B* ¹<5Žª6G+�Þ±`šÑŒæìNwj&ŠèAæ'×J’ScÓrsúÜýõº/‚4�D_ñ–·TT�%`šGÅÓ÷¾yÖoóü;àj²µ›D¾ƒ7×mæbSî‡oâY’xŠ(nq­`ÜÝW�Ç…ZÊ«“ÇÖF,Í{•¯ü-w¹ `>™ëÁî6GÎ7íÙ�§›0>·Ð ô¬] �:úã’>¨é"·¤N(�[ýê©É:Z·®ð¯‡�2c_NÙKsv!\<Ï_6Ÿ‹Õq}~üq'OÉuÿl÷‰æ}å|wùß#øÁ‹;Ó…¯iÎZO�–ñ.p<ä¥"ùÉ—¨ò6¹üò3ïåÍ óþîâÔQíÛùŒžô]²©MOßõ…ÿìæ|x}"~Å{¨â±Oûì×~û¶Ë½·“¢à½Æð½ºs‹ >™Ò»½ƒ¤¾ó»'‰¹™SÀú <Ãó ý‚>t“¾Òú9 ³¾"ºNSºÝ`ºð¿¨+?У:©¸õC›i¿šz?qŠÔ£?±³?²Ã¿”ý“½dÓ³Ú».L·#¥Ý9¹Ó(C#/àK¹Ô;â{¹ ¼ <¯ T>ÕÈ@<Ò9ä9uûÀÆ Á�:,@I¯ÿ§BA¶!•ð?~cÏsAa-T¿´A<”?Õ« Ö ×ýC» P;�³¶SBdB¸sÂÞ›;“³@Ñ`À-pÀ+L)ãC>LÄ,/¼¹æ;¼ƒè´„23¤>4Ì 5Œ·,7ì8ü¾|[­‘‰ÀŒÊ(Á@(„Š.Fbt@d¤€ HflFxFh<iœÆ=š»½À¶ø‹©§vÒ”—`‹z‘±”Ôš„ ýS°ÔAÕÅÿÐÒ7ÒD­ÊEEÍF}ÔHm‰I Ë ×'WM›9×ÜMNãìRu¤flF %)0ÕÀcUydÎ|M }]/F«Õ ²\ÝÎ]—ïÜ RXaØ Eó|ØÌ�€QV5¥àèc?'†pUÏœÎ! �¸‹‹2E^ä¥P_ir‰s¢ÖŒË�¼|Æ%ÖY0IF�€Gw䑘Åâ=c0KžÃÉqâHC)žâ*¶bPÆ&-.f/v0¦Çш2¦QNã•Xc—hã7Žc ˜ã:¾ãe%¦Â ?þc@d ä¡1ä�@d‹ZdFV G~‰HþÚºº}¢ä‘t€K\œád ðäOÎKweR6eÊAå!ƒbXetle`|ålÂdõ™e¨åæ¸å‹ižñ‹]^Ž^–566‚7†c�c.GÿdßËŠ@iæ>d€fÀ�f6¡f:N‹DÆfChä~ä–èæŒ[p¾qIKî‰XtVçuÉv>ãw†çœ‘g㣈J‰.+¾€˜5àÐ7h(h1>¤vŠÙ„Ö�…nè‡&æ‰.5;N <Æ\=Îh�æhÏdo.ä¹8d’¾f“FéyTé `iÒ�d<¨drö‰ÚºéÝÈi‘tWŸÖ7 ÎBÀê�*ê£6`¥.Û.‚/n‰0®›‚&ã‘ê3öå!æ–f7Æj#i­®è<^æ»Ðhë±þ貞泮æ´N“>imNin6'Iç¹ç€ÈmÝÞmÞîmÿßæíZý]R®é¾Æ™¿FÏìÌ lãDêÃÖV³ýgŶeÆÆåÇÞˆ¨6Ω®ê`vèaŽh9ÞìcæêdVÐN Ñ&íÒœÓéÔæì’Æf¶Ö‹ØîƒÙ†éÚ–éºöÜþmÿþoà^Sá6Kâ.î&†V,DnÂPî¸`î¼tîW[êéèêè\€ì¦k’¤l˞̆h6Éj£±Ï>¥»@õ^ïã  øÈ?¼‰lÞ�m†dÙöf|T±˜î‚™æ ïqn¾n&6ðSFpOl¡Þ¢våæ6ìGlZžð¦®ð§6èÈÖîÉVè_fèî¾jð.fñ¦hò¶èÅzž¯.ÿTYoßàøpñ»€qEžo·†k—ÆñüÖñýþßsÿòšr~&r:îIcp¸pp‘„ð/“ðÅž€Æ&è1Æî+×phäp.¿lïÎì/ñwÛjèj.T£ó¶�4Wó±–ŸB^‰Ÿñ•®ñ–þf;§kïàs[pð†,pAG¡gI{’z2t ˆYtVôctêvtëŽt�hÞ˜…0K·êïñ0ïì1/ñÕ9q1õ`-³. „ã�V‡m·oŸÊY·íž¸uw?oF@7ç^Ÿœ_§g3v%(cçdd¯-e§pf·ðë~ö¹ŒöÜšö.¯v‰¾öÏv¯õÿRWspGmq_ur�ó×nëú¾ïßq=w[�wfœ÷â­w{'`Ï÷V"ö~‡ÇǪ€Ÿò�¯òš€vã”v-¯ìK÷ðLñ†§=Î~øO/oQ7ñ´˜øõ®x÷¾øgu�—qsut�õ׳�Ïs‘yrr”Gáè›bµÛ¸à‘iœÆßÝâÏÊ©¦t”cñ—0¨{»·»Na3ÎâèZ–* d½‹e!r¹Ï€3+®”܉¯XGá\ù'q©—j�è¢)D¦“{ͧœ±䲟âèTûµ?ƒ¶—å·ï€¸'�¹‡»¿ûPÔŠ¼7«½äjýºÿ{°ü´ÐÿÂwÃ' ÄFŧ%Æï ǯKÈGÉŸ�*©üݰÁ/ÀüÎÚ|êǙΧÏGÇÐß�Ñ'}¾uû·OýÆX} ±ý0ÀûÑ{Hâûb1ܯ Ý·Þï}¬ø}Àþ8~K)þÆn)hP„2„ãð¡’ˆ5P¬ˆâ"Æ/7RàÑ#€�"G’,iò$Ê”*W²lé’%‹˜29Ь9á&N:wV¬xã'Ð.B‡&(jôeÈJ—îhêT¦ÌR§QaUÅ�0Z·FèêuçN bÇò(köÚ´F�N�ºu«D‰æÒ5a÷®�¼zsðí›ä/àÀéÒõêÕâÄÿ3†áø1dÇw'S8РAŒ2|«5nÄž5_:´ãÇHW³níúõK¨1kÚÄy¬NÑ€5ÝemÑÕK™:m*›E[©U¯fõl¸+ncÇ2fœV-ðä<‡éãý{tÊ&ôîíË·úô‚“nOüø •D®C¼xË1o!�"€r�êæŸo] öl :ø „'GM¶Ý†›n¼ý” p 7\Å'›vËYÕÜ[ÏEÝtbU·Øuhu¨wß�‡›xäåeÞyé¡·ž{îÅ'höE†_eú°äù €žh h4ÐF .R„]zùeKÇ9Uÿ›mŒíÔš>i˜àmÕÒRW]%â Øyg‰r‘WϱØâ‹ÄxÂŒÉÕhcá%É@yæùø£`A¶7$|ó ’“éÇ“MöG”8eº5°X–¾m©˜­ºÚª˜M‘‰“™:¡Ù‚š¼±éfpp*%§UtÞy'g ™ˆŸZ©øçt�Zh[‡Ú¨¨¦5Ú×£=)é{”ZYአ¹åêhæ�: j¨£Ni¼ñžzAª¦­ú*¾ù:ë³ÞT« ·æÚ›imžñ&Kq+ì° kÀKœlËâÖ¢ÎÆ­[ž!š(Ž‹^Û£�Ûr;¥8| ™¸ã–Kÿî¹›ò÷©f¡án�ñÆ‹ ª©±ª/ÐA‡)Û˜Z°Àixî÷šð¯ ‹Ø°ÃÅJ<1B}Æ,u/>›�¡#Jí]�œC¶&s›ò|ºµîË0ë(3O¶+%©:Ã˳½> ý7à&ñëïH§©ôš¾ŒðJ ËÉð°_1Ń…±Æ×q,•´7‚•Ÿµ;ò˜­¥›~ò\lƒæöÛqCp.©!Ìl7”8¨·|Ÿæwà½>¸Ñe.væá»%^0¯úÚ°*@N¬Õ“WîçÅ€z½1ØÑŠ=mÈÕ2*º£�š~:êªÇÅzË®ÃNêììÖŽ÷»zë.Ô½¾Ûß»LNa±ÿ?CNðÆ £„· $ôÏx7’0°�t#H† R01‰9�rð0ÿÕçm`Bè�°„8¡SŽ Âz%^Ñq“ô¢¢s�¯t�Z’{ÄsÃ,-„>ăYÌ2†!qP ’}–š 0±‰/x"ýƒ@�0è~VZþš²?,ôÏB bÀ P�"i EA Rp‚D y´A uðm !iJhB6e…,ìŠ qÃ%Éð94¬ásH™.Í?A, ‹£#&Q‰i¢¡øD)’f#U¼"(ñ•Ål±‹¶ùâcز°“f øÀ5Š ÿ�n|cÍ3GÛÔ±ewÄÃõ(€b …~%’ûZ�¿âóزiž²�Éìä>»ÒÑÆÉ´]PíkoÄ_ö´˜Ijo—Y gîTšQ€êT·ÙÍ68÷ŒçÜÉø~�Ý}v÷ps-o ºÞrEÌc¾”©$dÌèÃ"£o&•+>ÿ9 ‚.ô~²±�i8:Ò'=éú`n1ì=o�Òݪ:™Î@|h8 C`Æ@…±“€fÃz„ öµSRFá:Ü0(–žzÍ3X ]®w_Ï\*5—¸Wp®s…À\:úÐÕHË"=éJGÓ­w�§ƒ6ꈙºª~õÿ±d=„[ï:pôÉ@±“}ì8=êÓ¾vµ·Ý(Jœ;Ý7~÷6å}ï¶pßðwP>çÃÞráåFÄ�èd|ãÓðxÈG¦é“_/Ô¥Nõ[m^,�ÇÃç;$ú�¾ô¨O½`VÏzo"Ñõ>ƒ=Ke?ûÚß¾ýrÍýîŸ#øßó\øz!> Œ_K[&_ù��|³8ôUžôeõIç „Ö ×iI„B”žé}ߨÞêµ^Q(QTÑ�Æ¡š’�û… LÁBØÜüáTSßëñÑÉ?!_ãEvÍó-Aô]Þô¡IõYÀõe_è=àèE R` F‚``|`TéÑ4ÿ¡>a*¡N!(‘ ˜ ï¡`µÞðµ ˆ¼ ÿ%Ÿ 6ŸäQ^FYž`žæ! õ) ç1 è­ÅöuÙáz!ù¹]úÌ þáH!¢ïX!^ ZÔÙ< �âÆ Š«Ý bä Õ±!º!öÁáš=ÍÅ’„bR Há¡itˆö¡"¾!¾bÐ"àuÅ úV"vyd#6âEGtxÆL"â ê &ö :à�¢(Nà÷•¢) *ò¡*’+>¡+¢6¾Š,ò-f¡-V›"‚O_ì"/ú"nc‹ãàb�&ú !…¢Œÿâ3nS4J#p¤b^£fã6¤—t£ü�c’Ýâ,–9RP  #XxÐ̰wt…; <2À Eþà2Öc3BB£iЀIžä4¦F5Z#@bË$L>ˆAF-&¤8ââ"Ë?=$DRÛÛL$œU$ª!F& F¾!GÆ!ãÀ3Þ£3¢IÅI¢d?Rc5¶¤KöZLn¥L*Í•à,ÞBîÜ 1¤NÚOö¤DòE:ÇPZâ"cR*ã'‚¤SŠ$)ê£oL¥I¦äG¬ä*¶¤@r%a¶FÌÉÄe‹W<„ÚÌE øOÿ}ÌBFÊŠlÜmQ·éÌò]&ª±ßJtÿÈì��Ä]GÎca¦f fL$æ£,¦C4f�@fòI&$FFe¾ˆg®YfîÏfÆKg’ÆÆ�&RŒfiš¦j&g½±& ¸¦�À&Ȧ{ÐfãÙ&XÔGnVÇn¶XobÁoÂKpjÆp‚`k'i˜¦(§z®&Ì!æþ(fW0f¤”¥ôß|Læcd'cl'‹uçwAxŽÛšçK(Ѭ æz&((1§s¦tJç¤xË|€׈…~¢Šp¢Úl(‡þ'ާ¸†�ö‚*¨‰úƒ¾çkÆglÎçɘτFD…ZÀ…ÒK†®‡vèÄé̇~&y²ÆˆúX‰ž(‘Ž{b|F€|ÿê Œ„ƨŒVÏt¤Ì{qZ åè†z(ÝEUƒ) i‘†)Ði’.)`4)ŒÆ¨:N«U©Ãé–n€Š `}q)lxé~�©˜ö©«�éŠ*i‹2)} ”JÄšŽE›Š X) ÅéœÆˆØé� S—úÌ�¾¤Ÿnê«ês²htºèÚ<)”&ª$™›f›0Åé8e�¥âékèé ð)§Þê¾´æþ€¯ö*tâ«° ©ªéÛ#ª2ª£ «ŽÓ«*X¬Zjžb*‰j*®^ëƒi¯ú*¨«°+±ê¡ê[ kŒ¥jT5+&=+¥J€¬Š(µ ©µb+½BÿȶòêÃdзëeÊ]ìЦ¸�]ÄYÑÛJ�Ü´ë,,ÃÖ«Ã⽂@¾òȾ@¿ú« ¬~,£bDÁÆÕJäÚÃŽ,,FìÄšGÅ^¬¿j¬epì«‘ÆÇÞZÈîÉÖì6ž,´”Êf Ë„˦ÌÚȪ„ÈÚ¬ÑbœfPcÀÎ"IÏ Ä>v�ÄìjíÑ^­û%-�,mÓâÇÓ2@ÔN­ÐÊ,ÑÒ,Öž­íi­y,í¹`lÆÞÐü¡_mJX-ÚÞ­¯Å©ì-ß²­ŽŒàn6Å-‡T¥V²„Ýâ­â˜ÞòíÞú-y®äÆÀà’FÔÎ-ÙÖ­Ù..çÞVã:ÿ.äêÅä î#Å-_ÒæVíæv.ëÂÔçömc�ËènåjF‚œnê"Eâ¶.ïZÑë>nìþíìPíÖ‹Tòeîèêö.óÂÔG´ê ƒr*´¨Ñ£H=MÊ4áÒ¦P£J útjÒªV³jÝ+WŸ^¿ŠK!ŲBÏ¢]˶­Û·pãÊ�K·®Ý»xóêµ) ¯_s€�Lx‚áÃ+>¸±�Ç�µHžl'�eË2kÞ̹³çÏ C‹Mº´éÓ¨S«^ͺµë×°c¯öû70`Â…V¼¸1cÈ‘'K®|9�ìãÈ“+_μ¹óçÐUÓîkû6îºwóŽàû7p‡ÿ7½¼ùóèÓ«_}º€êæ®cϾ�{÷ïàÿ̾¿ÿÿ(àqîÁ'_vÔ×Ýø…§Å~˜ (á„Vh!tVw }Û-Ø ~ã](âˆ$–Xâ (Ú¡âŠàâ‹"ãŒ~ç „ä™¨ãŽ<öøŠ+¬Èbx/˜݌4v7Ï’LÞ¢�PF)唣)¤Š-Y@ŒH² “M‚X•d–iæŽV^™e‘¬´éf—€t#çœ`.Ï�xâxæž|ö `šB®ù¢›ov9'�uâ™ç“~6êè£Ë:¤pZ@h›p*g�ó(z§ž�†*ꨥ�—@eÈ¡ªõõàj°ÂÿÉi5´Öj+­Òäªk¼öšZÀ;ȰÄ d>È&«,²Æ¢ì³Ð’*í´±™Šêª¬nçj°Ö!k�·V3À¸äêºk¯¼þ -±Å6»ì»ù4»´ô@í½ø¢fmª«¶új¬]Îz+¹åš+ ºé¢F/»ÃÊ ï²òÖm¾WìÙ¾ØúË-ÀHrÚÈÇ <®Á#¬î³ âðÃÉF,q°Ç3Æýjû¯·× rÈ"“Œp' ˰¼lmôÑHÍÎÒLÓ+óÓùÒ¬ªÆÝ~ æÎ‹<É'|ÚÂC7›ôØH3ÝôÄP§MªÔÙòÖmÕ9_�µÖ\“ëµi`³KöÞc›ÿ½ô€N¬Ú„?Êv}oÃúÌâŒcíx#tÜ5Ð CëÀå˜ó­¹Ò~.ø°…‡ÞçáÛ%^ã�?¾säæþ4°˜g¾¹æ~³ã9àƒ‹®{™Qôîûµ«†!ü𦣾¸ê«‹,ÎòÌ»ŽZÐGûå³ÓÞùí¹ï®}”¾ÿίªÃŸ¸ñÏ Ï3ÁÌ7o²hòF/ýôÕó]ûígd¿ýý;vß;ðà‡FñÆ3_Ö”—>q8/4ís_¦ç€øím~Øþ&H¢¾(â‚VÈ`"6ø":xðƒpb\Fh‚šPkåH¡ ÕÁÂfã…0ãLÊäE?Aá†8ä€w¸ ò°;¢ÿéG�éPðˆ² 5ÈA}„]! MXBª0…-t! �Õ™6«†ÙÁa}È�’qABâíŠH$º‘=JTD­°ÁDtð‰táâF˜*VQdWÄbÕñÂlÄp3^4u#Æ’±ŒÝy$Óø"ñ�˜Q�Ïà£M`Å+’�[´— æÈÛÙ°‘’Œä�HIK¶1“¸Ä�.(G&Úщx¥(ýÈ�b³ ÈLæ» yHͤL>õy¥céj6†’•\ã%sÉÍålÒ—ž„"’¤ØGb³˜ÉT沘ÉÅU² šÛ‘æ}hFzÒ2�¶ôK7÷™ÿœoZ¡Rüƒ@gT„‚òq˜&À�BωÎtVá]NËLʈOÞ è‘�ä”76ÊÑIâS›·ä§H_ãO€zP  ¨AZ΄.”¡}è²" €‰«¢Š¹(F}¨QŽúÔ§ïªPÓ@Ô¢²QŸ#M*kJª¥€TF-K[ªP0”1…(Úl:œ&F§;ÕaOúS¡µ¨D=j_”ÊÖÔ0µHNM)TWzPVõªY�éV‡¥À x5aÝá9Kر’•£f *ZӺͶ:V4oõ$JU*U–Úõ¥çÌ«²hJ¬¾þ5°:$laëtز&v±iP«ËÚÐD˜t˜ì\+[×ÿÞ¦Õ곜ÉW~´¢¬aK›Øw Vµ#ͱ”+A\Ò‹—¨*ƒ¶å*ÎQØ ‡vq 2*2€¸h$j“F¿ºµÔ½Y· ÁÞö×qSÕ5æK_]áâ¾½cWr×Å0悛Ͻ`t§K]ëf» Ðn8¸K0ï‚W¼‹%ïíÌ=ô¦×tíuobáËR­�Ò¾ø�‚~Eê_ÿZÐE�·e`+ XÁ &—ƒÃ+Æñ"­¼Íê«…©‹á Cã½X‹owýb\ä×~Ý,1Gì\ XÅémñ‹·;ä~—Æ8´ñÑpl,A¹è‘¦£/}§Êáƒz˜È¹º¯‘EŒä£¬ÿ¿Kn³¬ˆGù†×Í.•lÂ+C­ â2�¼\0'NÌó%s�;\eùÈÍݧ’ßÌäLÒÙÎÆó�õ¼àFû¹Æ‹ ô„›EhC¿ ÑÔPô΄Ìg*>šÍ‘nr½RF¿”¹H)–î�¡�çïYÆ}~0¨Ý�úȧÔd 3¢U �f³Ø®Nsˆ+-k XûÚô«5Ãn�¢\¯¸ºšv1§c<®ÿ¹¨ 2öu�íÃb¸ûݨfv³¿AïzŸ9ÚÒP3¤ÿ›d`]ÛÙöœ­s,\?Y×™æõ¦}ÝéV›àÓYu±·sl"ié‘ï†÷²Y ²fãÞönt _MmKûûßÿ¸çÈíx{×½†±§…�ÃK±"Ý_·Å‹„ñŒ#Þÿ˜ÇANï{;ZÚk.9&ƒ…ò”«p ìëœ�eð:C9á1ÿu¹ƒ�åÚ缩8¥.NFŸÿ|ãíø¼‰Èr|éû–ôÉÿýt¨OOêH,x·þíHyÜ3ï:¾>ñ°ë|ìô«”é Áúªj dŒƒ“Ùƒ{N¡¶R�„œÂE°qŒCÁ F…ð‡O|á_»¬Û…òMU¸ËǹaÍBíæ·Óù¢}>J¥ÄèÇ“ýD©¯õQ}ÿâX_׋ ö‹“½ÏioûÅVJð�?œFÙûß¿ø¨ƒþ÷üp$ùŒ’6ÎGiíb,Òœž‡" WzÛWÝÇJß§@á§%«×z õz{]2{ÁÕ~hõ~ñóçGõ×ø·üw|ÿ· ÌG8(4ìr%v€Z¹—€Â±€+Ѐ¡÷€—�ì"B8„ÓÇâ÷6äg~ƒ~Ï.(Z XT"8‚äCäâ{W•^= ‚ú×-ø‚jƒÀ’24hƒ�„ƒ“¡ƒ<ÈU ´9Ù7„Dˆ€Ûq„Ý’„x~¸8áB2Ž…D5…ñW…&x…ã�…éÅ…bà…=“+Êç‚ÿ5bdx%f(Fh(jˆ}¥×†šó†p(E¨•2¤X‡Hnã„{h0}X'·ç"�1‚ð'ˆTT†H]ˆ¨ˆ£+�†8Ú6ƒ”¸X¹gsÕw4׿#´v;œ(?~“2ŸŠrh„ZBŠs`Šåw‡Kˆ5«h.Ôj&…°ø²(´xB„x‹Û‚ˆÓÐŽ Æ:ºB—ÑL–ŒÌ8=eHŒ�dŒ ˆ4ÉØ#˸rðc=µc6ÑЉ1Š¥+vˆŠà8ݨ+ߎ8ŽPŽçøGã‚… ¥…ìèŽÈ·ˆæ"�–A�ãôÃ@ùˆVÅx)Çh4ÿÈ#8Íø@i�Ÿÿˆ�@‡ yЏ3™+y_âX$isY—æx—µ¨šçä‘­Ù—¯ù—#I•%i•Qÿâ)ó.}E?IƒMd°žìY�‰ÇäÇ)Å…'C¸ƒâ}(�¨…M ÒŸÝá?aPõ1O P J{Å¥+Z³ ãÒýç{º”ç¤%d€R(E~SÅGýGÚ¡½•²*;U¥�äÂ8Ee�5%äÉ0æ©@è‰4êÉžëéž/²CñY'óy'õ9 ø¹ú¹XüéŸD  ºj Š ‰¥  ª5z|Ê‘Z$j¡€¡#¥Ç·^ú¥ú!ª*#Z¢‰¢D¥¢!E%-Ê./ê>1z43J£6úe:”£`²£ñУ÷)�ùù‰ûIIDZ¤þs¤¼‘¤Jʤfå¤OÿJ0Q |S*¡ÆD¡Xš¥¬ÇG\ |_ ¦¼¢Z"¢:D¢%ª5hšjŠTdÒ¦Äò¦Ñ§F3§í9‡dŸ¬ç1XCŸBhŸò£AŠVC:¨ b¤†šˆz Á• ¹Ò¨"ó¨ ©WE©Xª¥y�© ¶©^¦0¦rP¦£*2¥zªkU&ª:,I£“xD°Z£²úžä7JŽƒ« «òL×Q�šFÀÚŸÂ:¬ÅZ Ž#yÊê¨ÌÛP°‹ˆÐj¡ÒJ­Úe­ €­ÚÊ­Jx¢‹“¢+*%ã:媙‰q®éJî ª´Zîz«<š«>Ê0u¯B”¯ÁZ¨Ãý ÿŠfÒÿ°ä2°k°‹°VZ© »¬]j­û©dªfJ.|ô­;žöè9›œÛá±”D£êJ� ²íêGïz²ñšD}ÑYг²B*¨.ëûj¨ˆJ_5{�8 ¡ý‡r;·<Û³\˜°Oùl ª]ˆÐ·[´E"²¢ª„K[±iÚ´P‚’·µ“Qç:�¹V ²ëªµ¬W²;¯ò GaÛ[~U¯Û�Z†` B{¥åS1+³Ž¤CʶX“” ¡§4·t[·>û"WúyËh}‹Û©bj´ÛŠ´Ý:…û »¦,ú´�ø’á¸x¹’kµuZhwz¹\k²{вÿábÿû¹¸a¯‹5ºØUºÁuº•ºk;_m‹Žoë{³K»èP·Ûp».’»»kfBë»~K´Â›­Ä+±&:.L˼;’!¶áªEc®ÓK½C0¹×‹£ÚKE]Û½_û½�;ÑóW b¾ ð„„¥¾Å)ººкîûºx»ò;Hô[¿¶{·?+Pû‹©ýû»Áž¸G˃[ÀpÀ¨Ú#  ÌüD<œâ)ñP)L²Û›¹^»¹îñ.M'/KµÁ º¼ñÁæ+ƒEÂÞÀ)¸‡Â*L ï«‘.<óK»ö‹¿ ¿í¨· `: À<<¼>\¼@œ´Þj¸¦Š¸%rÄ€‘ÄKÿüAMüÄž"ÅÙKÅ̽|ªY¼,[Ü,],áëÁÝÂd|fŒÆZÒ¾lÌÂnûÆq\» áÅñ°XìiL*•S+÷ÍðÑtÄÉ@˜Ót)C/°ÍÜì;ìY)|ÎâÜÄÅ.eÆGá.ѰÎìœ{àðÎ𬳑Š~D_sRõ ,Ûü\Hø€¾¡Ee ]o¾G0Sµ$ý°Ðý /$ðÐÝ8”F©£D_…ÍÛf"½|p¿¼Á,ÌoCÌ>–η’ÌhµÌÅÔÌ~I.Ð,ÍÕAÍdiÍ—ÿ£Ñì¢ÍܼÍÞ¼žà,ÎáLÎ%}+ç Ô¦j 3U˜ 2G�Ô�¤ÔK=°óÌÖÔpÏù|ÚœQÕWÍÚàÚ] Û_-Û%Ö MÖe}ÖP�ÖD7¿M nýŒÃM"r-Á }×Ê]A) SuÌÐMÒ]Ô=./}ØÕá ‚M ÄÝ�ý,�½à-Þã Á™�Ùéý1ë ž Ï™�ã:î <ÞãñýÔóEßS}ß©� «�Õ­½Õ½Ûã’д=Ö·�ÛŽà §àòÝàf×ÞÑÎ!­Üžá'½áþáâðAâÙaâÓƒâÂÓ9Ýâ“MÙMã‹V[“¼35~ãï¬ã;Þã<®B*Ú%DÚ¦�,¨ÿmÕª�ÕŒ¡ÕiÀÕ^ Öþäå®ÛhÍÛýíÛWÜ®táÖ;áÉ]áaÎRžÒѽÒÓÝÒ ^ØÑ ½ZPâØDIä9pÎÍ“ëâ•M½v¾j–UÅê½Þ|~žã€èË3èò-äö½ø½èú­�îß’ÎGÞшÛ$�{TnÐ 6ÚÀí ·N,PÑ¢N§¤.>oC>§~P©þ׫Ø­>دnݱŽ4j®µnë׃ëÞ�Ó»>çã ãwÎG2.ì4¾ÞÜÐðUÇž Éî å°ì¾Gè&`èõ�èD®èFÎèGPÕþ L޼³]ÛÛŽÛÞ®é î…>îå>,çÿÎé«^Náín<ïŽÎc®êÎêîêgë÷ ë´ÞïAtë�“ëÛ<ðEBÙ|Pç?B ŸçÃ~Ôÿð ñÿãâ>ßQ½ñù�èù�ä¼1ò%ïä(ÿ‰Ü¾òAÔÛ°íòóÿnîMS“;¹�´{·âî¡i.bn+~MT€-Ø$âF¿æHŸôÿ8?õ“;Gs„”_ù?yÞA·3‘§ð�'Yßðì]ßÔÍöCíE~ä�¾hÿßãRãÙ�¹çö÷$/÷íéfó9ƒ`��÷yO£{ß%áâ÷Ði0�ÿÜ>_æÚuøDŸøü¾ø ô€óø”ù’o•oùŸÿ‰ùåÞà°ùVÿ1žÿù¡ïç£Ú¥_ÚbOöÒnöÔ¾ä®?°OéÚþ‰³ßHi©¸Ô¨y#ÈÎàÁ3 -<ÐÐáCˆ%N¤8ÀEŒU4n$ÓÑãÇŽDŽTÒd5”)Ÿ­d™2¥4˜1ó̤ée¼49szä׳ÜÏpAcÆLyÏ(¤Iµ,e:ÁéÓQ¥N�zaB¬A´nåÓÕ+H2VÄŽESÖì´i­eK“&8¸qÎ-gÂî]¶lMšäÖ×oOÀü2 &ìÉðáq‰ã¸kW µn‘ëÕËW9FŒ4gãŒßÐG"Œ&mÊô7Ô‰ÓˆÖÚõ¼yýd÷“PÛ6ÿܹuãžjZ±â áî>&èͪA¬ UdÞܹDåÊ9vìQÝ:Ø9Ùµëáž×ûjðáÅ£è2Þy�aÔ‹cÿÇ{n¾£�Ǿuë^½²âßoI�)¦Žcg£� P°I#í#œfÂñ`äB ƒ3ÍT:ô5¿ �­âŒºÇýòkG¢ãŧrq®àVƒ©¸ÙJ`Ç0» µÒ³Ï@í©2 ñøà£ÉµÙfsp4«,@¿®†ÐrKxº¬�-×p” +Ë|4óL4ÓTÍ蚎 üªÃN»ì¸Óƒ­ óÔ³¼”ÎÃ)'õÂ`O÷œ¤i¾úî‹ÿK>úóï?$P ÔHAªœ2‚%¤p< 3 jC?\rĵJ4 Es4sµ·qF§dD�Æ l”FÌ~täÑL ±R"C;Ò©$—lò½'[‹R¶M­d�Ñ-¹ôr<0[ã•ÌÊÖôö[p1js�7ãìaN:íÄSOvÃãó&ô]¯½rš”�úÞ±su”¿ÿ‰4ÀI)=ÎÒ*0ÕtÊN!œpš C½PCÓJípIÁ#‘ Y}U³Xg¥#FÜf*×´n$(Ç3xìÑÇ`‡-ÖÈ�T2Äeã› Êg£•–Új‡èž/× så1*3\¦›ÆlÜrãDw»îÖjÿ÷ê´Þ­ÆÏôæ%´^CgBT_Eñó÷߀mª&ß|+µTánøáˆ%¦Ø”M1FµUODñcX[éÅ‘k-ùÖ“ÃÑuÛ–…9È!=3¶fdo1çf£�móy|¶èj‡.º‘£½aùŒ¥�V\¨5òÈܩ묺¬±Öšky¥×ÞCñM”ßE±ü—•´mb›>¯P~y¸ Ø´á?èÕîQMËûT�SåxÕ¿?ypZ'°õ\OyW¤{m|G`!'VršmVvÙÌ9‡Íó*A·–hl�Ö6}n]fu\Sëªð:©�„N²»“Õj×®ÛÅ+ �T¡˜Õ»|í«_ÂCÛÔvÿ¼w$oyÊkÞóæö)ñHŒw»^ˆ~ƒ–�y£cÝ{Õ÷8@8’AÁdå¨Ñùç²ö +rEÍ”,‡± æá5öÃß´°4¡]K<ÙŠãPW™èP‹X@¡ë$BŒS@μC»²Kk:éšî¾Æ;±ùŽlÀ3–Ôö˜Ç|ðx‘éÆAF¨zÊ ~J­ÜüàèÏÍlªú!ëèJwº¬j•¡\í”W{V‰Ž5—«A«YÛ�V�¦d˜l«1ß Ò¸âa™®q�3ñx×|å•{íë_ DWº‚lM "œnO±€k¬%�ŠIjÒ¨ñ¤='·ÔË5U‰OµŸhƒÕÒö�tÿ³¬Òº¥Ú­Ê²«´üª-#5ÑuÑ£¶Å­ZOZ�Ývô�M¦\HÜÖ7�ÑÄë4õZMi]ó¥0 �t§+XÂÚ4cˆÕž ËÉ]tz²à¥ìwÔz&ŸúLïgÙË9÷V ¾³5-}Q{_üª)–±\f Á Ö‡= >wÿ OÎ5¨á†0î r•sšÝè†.? OLò°B„YÌn™IíÖ2¶wœCÍ sБŨä÷4Æ1Ï„F�9“ ö`JOÙáGgÂG>f@Ð ô�ïL$‰88Ãy&Y¥œ3u‘3*ŠUhÉËFJ,k)NqÔüéstš d΃ ÑŠÖ¡Àd2õ€t�™6ä.YZnND’'´d»4yYOfO”¥œ‰*[yYXÎ2n¶\Ž.ÃäËÿó˜ÉlæF ùÓl& ­áÌ9›´Îи³ qã >³ÓÏytd�BÀÐ�ñL¢¯ ¢EÏ�ŽFQ«}$élPšE––¦S£iòpZÔ V³ÿ¨½AjSŸÚ—©–ƪííêoÁz²¶’µm�kèºI¼‡¯¥l*_4Å6ö–“-�eï¥Ùa&5´¥½æ¸µÙÍ×–³ ´mgÎØ0z&M¸#;îrwãÜé^w6ý"E…ÑóŽÌ£éLzEûÍ¥w™éPmz '¸Á.1…/<Õ:ÄÁ%qŠWÉâIƸÆá£¢¾x|Ê LOˆ]ìcŸ<å& O˱vf9¦æ‚”ù‘ižm:ãÏ”ŒÀí”>óÏåz¡×}t:$]8ò~ ½ÍñpŒà[ßÛà·•üý�q|Äá:¨ûN愇 'û Ì~vXgÙÈ3¿xœsÿ žœÁ]øÜø5°é^÷»g9ïàñ2}öz·¸<ðÓŽyµy? Œ/ý1Ûî6ãwÞsÈ‹[òä¦ü -ohÌk^ûñ<è/"ú©“¾êý¾ú¿³ð­w:¾øz¨dÚ› ÷»=¨2Ý›µë;¼Œ¾e>¸+>�s‡ºã‡äÛ�åÓ”s¾ÿ€>š�>¶¡>³>û5ßkŒ›ã¶œó>ž£œ ˆ¼ßš<@«ðð»Õ˜‹ÿ)жÀë+L¡µœ¹‹”0©¢‰‘ žC"õ*>²AL7¢ãŒþ w‹€ÃÀ˜š3)Va!ÂÑ+=°-#Ä�ð¨¹ýk y­؊q¡B4á ,É2è�)$ØB9ëVlE/ü¾YœÅ $Cx wz 4„ v!µtCTA39T�ßHŒ:´‹”° ËÈC=ä> ?„#@Œ A´B<¿CDÄÌ Ä(Æš ºGD‘H”º¾¨´ù+€J4«K¼�L”³M$³tˆGyôÄO ‚PÅ*Ô F1ņAEUlŒVtEXƒÅXœEƒ¬E’»E\Ôº]”†^$³_ä²`ŒÃ  L)Æÿq8FHFeÌfÔCѳh ›iì†j¼Æ̆lDDÒèÆßøÆr GsÇ ,Gª;‚*IG‹ZGFhÇÆxG·�Çyü¿z´Ç6ÁÇ| ‚}Ü�S„©¼‹€dÅW„Eƒ<Ⱥ³EÄÅÉÒEúˆ vA«ˆD¶‰d›a4ŒÔHŽTÆ�ÜÃgÉ$*É“¼Æ;[ÉDtIÅ€I@“IšœÄsÔI^âIŸÄ‹%t(LÃÊxD+ƒ,Ê{DJŒ EýàÇNñG‰©¹¨ì„©üª¤Å«LȬ\È3ìJ^Ô°9`Ìa¬È¸ÈbDK”èH�\·ftÆ�tË·‚ËA”KCämÜFE4 ŒÄKÿσÄ4�?›”?œd¿Ü%ÀMLÃ:�¢„ÑL4ÂBRï08 —aù‘°T 0ŒÚ§%á8‚¾ÿÅβÑÝ0R-Ñ 8QïHÑ•@É- –ÅR¥Q5}&]–,ûQv RïRû(R:åÒ¼P›%%4'}RþˆR…¤ÒȰÒzÄR|@Ĉ€-]’3òRó 01 25S_BÓá83YS7]“�SDQ:µÓpÀÓ¼ÐÓgàS-òS Õ@TÅ(ÔCÅ£Dm’E=�Fý‰$u "� :Je KE&ÍTk€RϔҠðÔnÕOU–„‚S ‘Tµ/—0uÀ1µY� Z[õ\ÍÕâ„5^íÕ9ýÕf4Ñ™@Q=5VBVlPVªTOhV´ÌÿF µh…�i5 µÖGµ‰lý€míÖµøVs×L%×ó\’)-¨*Mš3¸R,%Ç£ƒw‘xí´yý–z¾{-•|…‹}E ‰X­’¸ÞôU#Í„̓3† qµLÁ=6Š‹ÅX2›Í�EÏsõ?ñ“�Õ›ìÉ ‰$”ÕTVàÔÏDWuÝŠªU�Dƒ:°Í3ZµUÛYoéYáûY ZpÀÀ)Z£}%¤ÕF¥Q¦½Ó„õ¨½Æ-šÚ¹5€«Ý²¬ÝZ®¥ ¯Ý Fý­ ‡3Ûó(ÛÃR ïHÛrZÛ&UÙ,Ø–�¯hxYõ‰Ùz¬Ü©Ù»õ,øÈ[½­ÿ¾]¿…;ÀíÁ%Ü�1ÜÃ]‰‹¥¤Å °ÚVÌ!³§m“¨mšX¢Ü¹•Š ¹ÀB½‹ÍåÜfüÚÏŒÝÇ Ýx�Q³%±F( Õ•É©%ÃEL�Ä8#נݬ¸Ý¹Eºx¼-Y”øÝz¸ÞoYSá›Ná+ºÂ…µåͯez^(@²Þƒ#š¸ÌÈ%ÄüÒÞªå^ÓðÞŠ•3RóáÎÕ�Ï ÝgE_õ=]àjP]Åb•Ê•_Ãh¤úõŽûýT˜%îaÜ…‚ œÿmßþ]ö†;†;N^nàÕš¸‚` f;õªà¨¼àtË`q­\6ÖZ&³&áñõ\j]ÿ­LaÒ]aì:[÷M[™œa’›_Ô»á¼ÈátÝáæaÜ�€þõ_Þ}o-b½=â5IbYbiâWQ^(~µX›bÅ…Þ7›àq³`ë•\æí" ¶Ú¨è^3\�š á2öƒÎ�^cÀ£¦ŠõE]"~á÷ G:.6;V ûm üMˆ>öãý!d(äj`DVÀYSFö GvHŽdÜ“b:¡âK¶b ž MŽŽdö–ìíâí ååïµ S.ãTÆ�UÆE6[7‘½‰ãH’á¹¥aO°áqØåÙÕáÚýeðâ@d¦jcFfNfše&Èfî‹gÖŒh–fožäj®äÿ¾ækËä,Þd îäødùâ0.e2>åtv×4FáV~婈åžežãz®ã¦ß|Æa^æg¬ðçÊ�mâ”0è�Fè�afÄLàu[à!ƒhoEhj§n¨ŽêÞ¬ª®j[ƒð€­Þj¦Âeʲ@ ”ÐÕØê­Žê¨¾e°š¡™ÞõІ}Ù‹ÀȽÙÈk½Þ”°V�, �Ðà8RS›(lÆžÞìë0°ë³ÝdžÍnæèæí"¥&@¦vꦋ©®jª&Ïþìð0k­vÓ¯Þ Åë<)kÑFk¨Vk1bë.qk׈kû˜k±¨ëb¼kØÐ뽞ÿÅþkÀ>‚3l›0ìÃn˜ÄîkÆf_ÇÞ…­lè^¨ËÆlÍÖFÎîìÏöìÐmÒ^ °îkÔ®Õ6kÖn×N؆Ùn ÚÆÛ¶Üv$öÅkÞö¾îkàìá&3Â6î@lmTìå–åæ~îè>ðšn§®nD¼î:ÈníÎjîÆÎÒÖ�ÓÖJ²m8(ïóNïõ†kÚ~ïøÎZY¦o޾ﰆ¢bXqßo·èoãpDðÜnìÇîHÏqÕQðÌ‰Íæl'€í6ëïëð�ñ>kÖîpØþðöñoiïmQlgñß??îNIî°žòGZ‹Çq?sÿÖqj°bpí¨j–òðèá­.ríÈ2 j±ÆðÔ–s­æð˜®hô~rõší/€±°1g‹*Ïk”,×r./nÿ–q‹@It2¿qeDsN/ 5#6Ï7_ 8hÒ9§pïÞ�:‰<ÇEøPrЊ­–¸[Î ¿â™ˆrC LÏ‹ú¶oßîëGoñÁìòÂnîéM+€�KoÍ÷�e¶ØêÔêtk¿ˆé^s‘6§ê7‡ð8GõÑÆN”̲Vç€@™ÍX˜õ ¨uX»uÜ ·¦ †{o+ØÖ½a †ktõ(ö-ÌF|&e‡fwvõî#X÷1Ï j²k�xÿW'/õÕÐp7-wÓîku�vv×p[ÿóÜ w]σ{—}?[~O5€/†ýx<*ø?ó@Qx†?£‡ ˆ—xÌîñ�øñªÆø´Ðxr¿FèQì�Ç%yX+Ê,‹ô&µ”·’mÅÈ3ê÷)ž˜ŸyÄ«yÇŽ�eRl�ù†Ÿv­®öŸG󉝸¹xp—p"ǯqY¼Ï{”\z�oF†>¨2©ß ª‡m«Oµ@ÊúbÜúTÛ¶móú Ñò€ŸPRûǰù²ïë³wú–V{8`û¶×ñ·ßö¿n£G ¤W­»Ï{¼ßû†az¿G{Àm‰|Ý(|¶>ü¡H|ÿ:Õzï`8ǯ3ȯÉ—y�·|�Àü2ûàÞyïèùÐ}å µ@Z&TÌ“B*J§—s;7ø~ð—É(òÇB°JrèŠ.ØÌ‡k¬Ü@ºê&\˜ú$‰eµ�*‚;ˆh&Äað`¸„ 1l(í!½ˆØ&R4`ñ"™Œ3qìï#Èr"¹‘`ò$Ê”*W²léò%̘2gÒD9èf¢œ: ðì9ç'P$B‡(jô¨Ð J—Öpóé  R§:¨jÕÖ¬Q¶r…âõkO� -Ëàl¾´jóhÛöâÅž=§Ñ­[v޲¸öò•ËÓàÀwïV+lxâÄçÿ3Žæø1Á‚ ŽMØÐ!D‰'µ¨qcGŽ CŽ,Ùô4êÔªWÓ|ªs§_ A‡ l4éR¥M¡ÞœJÕjÕ¬Z¹ný –§ØÊ¶œe°V­Û·�ý¨k·lÞ£|ûú ,xyQÇ#fÜø±ãÈ'S®|™áCiémæÜùsÆÐ¢GÃYŽ$7¬ 8 �ºäÚk‰P'ÛO´Õ¶n¹íÆ›oRW•jH\qÆAVN•…³\sÏ¥]�@�utÝ•�QÛíE�w€�žxÕ�Wžyç —žzìá â{ŒÄ7_}بˆúeÂ_¥h •UZYÓSˆh¹%uL:ˆx2…ÿ%…^耆iªéá‡ÈåTœq’x–Œ¸°ÝyêI]}úÙâ40¥ž ÔQçä�ì8O�>þH¨�5zR䑚mÖ¦™2é$”þx%¨¡ŠjR–[jÙ%~_†é ndBUagª9«l‚˜HœrÚÖ\�wº¥çž~ùùg‹‚@¨¡~!zã¢�þ(P�ìIJifôÕ—©¦øqÊŸ§$ió­6£Š;®€¦j)º=1)»DAÈj¾ZáõÚK+¾ÇÉ•+œdÙÖ+ŠÀæÉ Á= Û' ÆúX²8 ÄËÚÅ ©´5º³1Çó!9ÑIØbº É%o;€‚.¹-»<ÿ“¹ˆ +†ºø±+ˆ»¶}Ùjkeúfï½øÎªoOüÖáï`ã)0Á¬|pÂe-ìXÃGlÛÄS|q´“IÊqÇ[‹MÈ"—\rÊ$¥³6Ûis³òËq˽RÌ3×üÙÍ9&&Ï3ñ½@O ôÐ^Qg4Òw)ý+ÓótpQ5u4Uë18«§õÖ\KæµÆ`»#öØec{6Én³ÝvÚs»þºIu§ËÓºí>¨3¹õ-“pXÍ*øà„§I4Oˆ'´Üâm ¼@ÓO+¹Q”[æšGÆy#ž¤÷Ý-:陞)êÛ¨¾z:nþ~ܲÓL»Í¶ƒù®îñ¾$þù÷nÿÎï‚ ?¼áüb¼ýKF¾R^ãœö8¨KjêaX²¬–9¬mŽs„ú3Ø=ï…lá™IDÖ�ò�ouêc Çå¾»i$o·Û[ît“üé¯wýÚÿ4D¼ y X�G,ë(ì�T‹àå®6˜¬ií‚Äà¹÷=ŠM|!4êJȺ”¥°‹¢rË–¬`ã@nf„‹Hið%+( ñ÷·ýÎ8€¸#óxdž9OŒV¨ËA½Ô£ 8dTB0’O}b$øÁ�±²b{9&3©IL:©žü$æ0'¢q�²”â8%*Ñ¡ÊUºM‹kkÊÊb ®åy±ÿ–V£–ÄHƃ™qh„ƒÂƽ¸EqÀm¸&é±™€àã#àG@¤’#¤!©È‰@Ò‘€¤$)Y–Aâb“æ]‚KDèò+eô` •l{)‹‹åZC–åÓl; ëRéb«ºžéuq*XÔÂuµ­-¨1ïÞñÖÖ¼�A¯z—ÊÛ¦þ£'‘ïfè ¹û0¿•]®ÿ³˜6ô¥#ºií�clËC!§ª•+k½aðNx¶_!¯…ƒaÇ®··FépTQ’$Û7²%>²r-›â³¹²Å~ñte¬åÒØÆÛTw‰ áèÀ*¼ p_õ¬!WuÁ»%,‡+úÞàždÉT±“­©_þNm+FŸ‹Sã-úu]~«NãÊÓ�ŠÙ°*s�HÛÚªùGlá¬glzXª!¾s“‘ åÃò9–$üóê  AºÕ/;ô°´«hî2ú§Xyt…ÌŒæ¦Uú¼9Êð›Ù;jýÎy±ÄbŸH¼éý¢ØÔ*N‹UMV»ºÚâÒ ²M‡msÛO:�d)›ÿZ”øÄ£ÜæfºÓ�†u³r�„¤Ñ !ïy?£Þö”Âàv….¢.ÊAü pµ$'/›œ4VRR[¸38Ä#qZZ»â°Ã¶¶¹½moçܤ÷Èmîr§[Ýì^·»ßÍ�xÏ[Þ›L¾÷½î~Oãßx1ˆÀýðÆ‚¼¶ ×�ˆ$ž ‹ÝÚ'�Æ7Þ§o32ܶùÈKŽî“£ü`*_9¿Zîò®$ærá÷Oü�Õ€ |ç,�8Â=¤ðʽèn/ôÑ“NŽ'Âãã9ÔÏ-uª§!åï65/ø—w�?úþúÌÃ^ó±ã¼ì(ây6Òn'±¸ío¿|ŒãžtÿºÛï9É÷Nu¿Ã›_‚<× âõž€}bǯQÈ®óÇŸ]èÿyh*/qÌ󾺚×8ç›þñ§ôRgßIÏHÀŸž„W½áežšÛ\öf_‰ío¯výè>â½ÿ~h—×´n[]øw¿ÑcÌ-÷ä—ÿï¦oþóq°zžðýõOxãg˜Ým”GŸå�Ÿæ“ø ù K硟c¨_Òñy]ݳ4Ÿó¥”Ïá±ÕÙß‹äßõAÄ�•Úàî ÚR²ÂZ•ù�œQ¤_¹­Õ= ÊE üQ J»i vp í¹Dÿ�`÷A\ a�` z8x¸`<ÀÿàÉÉà»ÑàéÅß "ÞÉéàQX_z Á� 7¡Á¡®�*® Fjy‘W1¼!J!êEK‰Cbà.ìáä\Ö^Äy!ݢܔáܵŸ.Ê]ÖÆá�H ¡ÔáÒ_êáýÝ\:Þþ½ÄžÕ ")ºL’¨›H’*òC¢ (¼",6“³üHÅ,ÇAt–žÈ’Š„/ö"J‘0#Z±†Q\)ãëœbg¤â*²â�¸",¾¢,öȳԢmÜ¢Kåb,íb/òâ/#0#2Žcµ)#\0ã*¶bŽD£4êÑ,¢‡56Γ6® 7vÿã7‚£8’#?Z[’Õö…Æ]äA¤>Ë;>F¤§QDŸ‘LE’Ã>f¤LÆØ?r¤W,ËQ€dH6BR#-RŒ-„C.DbCKnÃKÆäL.åhÕ¤MJ�Qèdˆ$ÿ¦N¢eINæ@ÜE &Q®äD¦÷u&lzf}ˆe@’¥A¦àIæ_®eY¤f[j%k%\–ÌfƦqv‘Ðáƒr.ç¡�rÜH‘ˆˆˆD‘:çq^'Ñ%çr*gs††ˆ$JtJçXP'v–'øiçvvgG|'t¾‡xŽg™§|bz2§²8§ÍÝExŽ…Ûã|þçå}&É8ÉqŒ~ºgeôçe(ƒº�€n�v��–Å~*„‚ºeƒfhÅ=h„z‡è¸C ‹](pj¨‰‡êG�nLR爦�ž¨ŒXŠ†ÆŠ‚(K¹(ú�è`Ψ�R׃–Ï�¶h½hÊÄè�&)Mÿ)ê iŽéŽÂè‚*)•Γž�“Æ“Žš�”bh•~iZ‰�z¡,!)˜ž©Œ�)¢)›¾�šžU›Æ)æy¡œÖ©�Þ)žæ©žî)Ÿö©Ÿþ) ª *¡ª¡*¢&ª¢.*£6ª£>*¤Fª¤N*¥Vª¥^*¦fª¦n*§vª§~*¨†ª¨Ž*©–ª©ž*ª¦ªª®*«¶ª«¾*¬Æª¬Î*­Öª­Þ*®æª®î*¯öª¯þ*°«°+±«±+²&«².+³6«³>+´FêßL+o¬€µ^«PAE´Î'µvë \+¶ÆÑßl«|z+µ‚«µfëS�«yšë´¢ë ¨ëM°kyºsëßÀë䫾Ž+½^§½V+ºêë¾òF¿ú«¹žÉñ l¾þ�[,lþ�žÂJ]Ä2l[8lgB¬ÂNlÉU,o4,Æ&¦Æ ,Ǧ[ÄF,ȆìLšˆ´¬ËFlÉ¢ÛÉ*lʪlF²¬Ë¶,Ì^HÂά¾Ö¬!ù,"*œüÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢E„�2þÚȱ’ÇE ň„B²€É“·Rª\™Ò˜Ë—¸bÊ”E³æ†›8/6”ij§ªŸ@u J´¨Ñ£H“*…˜ÇŽCŽ,yÒ$Ë[½²j} SfÌš6qÞ\*°§O ?ɪ]˶­Û·d›>Ýè±ÈE"Å�„RÕ*K­[¹óú¬,±cÉšå‰6-ÜÇ�#Kž¬Tîܺwóîí[à*ଂ6|±ÚÅ’«¢Ìºµë×®-?Å,U/Õªž?‡&À»7iÄN/V »¸ñãȇʆj·öæ¾¹ïîÍû·iÅÃ'ßν»wËéFÿ]´÷y�bèCî5©½{ê¼gÉŸŸ©~N‡A ÎÝÿ 5ñï( \áýByåñezŨ÷™{ïÁ7}ö%ÖPM¸ŸÚ èᇠ*§Ñeã%¨àyé ¶„íÁGÀ„òÕ—É}þ”áˆüqÄ!Z!öèã� x ‰'1è `,Nâ"Œ³ÈH#CÞ˜ãluyäË•XVé�\v9 �%&XdŠ\­Èâ’0:i!”6J9¥xUb™¥–tziç�¯�Ù‚å�Ù Šž)aš‡_›¾ g]r^Ig�xF*i[@ñb©-˜b)œ’Ñǧ Z"ꨘ”j*#¨¦êȪ¬2‰Ê«°rÿ ë¬Ýè‰�2Ú(‘œõu×]+lÄ;é±ÈNT饙^¹i§ †:ª¨¦žš*ª¬¶ #¬°klA¶î—k•œñÚëI¿‚$ì°Þ�ì»ð*´,/˜Ú¢©�zm‚YRm©×b›­#®r‹J»î‚ë&•ãVR®˜ç¢›îºÁ"ïÅ0o½÷æ»/¿\ùûoÀŒœbòÉsk±Â‰âZW¾œ>ÜgÄçR,ÀÊç|ìÆÍúò,§÷û/&$ŸŒò¶ã´ñ˜Œ£&ëÈÉE”ó“{ å(;Ãά(3`ÌŒ§3çYÄzâó¢GÑ'?·yËnær—õ¥“ø´§�’aÅ\`Uޤf¾³�5E#1Ÿ0bô¦CѨ6wÈMoꜽ”ÏHIZÒ|¡|˜²‚R—ú4I0Cs)Dá)Ñ™ÖôqöÄ©V%¢ÓIrÔŸ¸è7N‚Ž´¨F] Rm±T¦ÂÌ©dzITSùR8ÆÔªò±éV÷‘®Öò«ÿ (/ÅiG´v*�km«R› ×Ð̵�uâ])zÕW^T5¶ú_5ö“fÓ«<í¨OAZV‘žÕ°d@,RkÆ:Õ±ÿ’êµ"ZUÊÿæ«Åì�4ËW¿ê°alH…:TÔ¦6x‰U¬kŸÊ•ÇÂ1²Í¬í<+›Õ1¢¦„k-á)8Æßm$Šyùªú\AÞòÎÔzÑüØÖË^5î0Š&º l«5=ë1izȯ~åH!ÍhM4¼n³[ÀíÊ�†ÞýxÿºÆ>Œ·¼ä=oÙÒ»/ö¶×½ðM�|¡ú¯úênBøÕo~ù#ÿþ×Pd°÷ì=72Á þmƒ a �ÂѲðzÝ›ƒ —gÃÍíðÀì £‹˜ÄM2ñ“¼ì"U»ì‚ §àF…7´N„ÉSô²R½:æñÓâË’ùšÊÜ+òÀD<â"öWÿM(¶n“ŒÔ§…áÎx\aleƒŠÆåíò„Y¹eWèøb†™WbæR¡ùhZ›€dŸØ‘*¶_�a†ç��ÅF‰�3›H€rdpŒ:x¢‡8‡th¦È¨�G¸ŠJØŠòñŠKõ„Q8…釈Vø#%T{¬Åt{¡Ž$á@¿è5ñòX‰——!%DsÌè†ç¢ŒûÈ)¡ñŒë“$ÓH�ða=xÈcܧ%!/#³òŠm·CƒxE°×_Ù)ç(‚Ý“ŽŠŠYî¸Ex�ó(Œnq�M‘�Áö�P35þ’ù�[–$9�Ùÿf4 é^ ™ Ù"ñ‘²"‘$ÁCiE™k‰'i%䑟Xì#yE%IòøôH*™,Ùi.71)•0C“f“,R�9y2;©F=‰¨”9!©%K5‘9p”@””…·”?²st|�•û&“…)’ì#HW) Y¹•“QBt’@úh˜1“žx˜{у/Qhh !1Å$ki2G0š¤©�ÛÇ�q©$AI—Ci—J…—zù |)#~ù%T™3ˆ%„)r”¹Œ R•V´˜�‰’JQ{‘<“I–ÍØ�—É›ˆ¹>fY^�™z'š³`=¤Yš™š½Á$uY%wÿY”)‹Ér„G›Ø" †›q2˜Ê’ë(Ÿí˜˜$I„&©•ęƩ%’Ù’½)–Íé›Ï©>ÑI^ÓÙªš§��£iš±€šO!ß)”@”P`”扔è{ê¹BŒ–"˜r‰Uñ1¾Çcî…·Ul–*Ö³:†`+4Z£�Lj�xœñ1´ð£@ª�/±ô1OøsW�“{ƒ –æJ´$cy™ê#Hñ4\³@ ”0\:TBN�¢F)Q "Q«b4JWjjsȉÞC¢Xb¢'�¢„¡¢jÄ¢.*b0Z62j£~š!8î×u<Ú> ¤?*¤.A¤úÿc¤±Ø¢.‘¤Jz¥„פ–vTŸÅ`Sz UºE”TYº¥]ú¥¦J¦Hb¦Ž€¦I§¦ôX�°!¢¼§W"§&A§^a§<„§Íõ¢¨£�3£ú§� ƒ*I…z¢û‚¨‰ª€Eº/G©7©”ʤs©j•©Rª�zEŸ #ZÚ¥^ `Ê)bz ¨ÊwªÊª›àªl*²J«¾`«€«2¡«;Ä«rå«%çÁ:¬Äº9ª‹È =º¬Ìª¨ÆÀ¨çã¨é ©Æ ©Ö*S•j0æÄQ±ßjEá:!ã:ªæZªèzªeOgz2iº¦ûÙ¦ø˜ZÂö)ª¯üÿê˜à¯ÀjÂ*°5Z¬q¬˜¢8·ª°ˆº´O“±*±sg=‰dMš±’°±MÛ±@ô±ó²\Jªù’®ëš“Ю*Ûª,ë‚È1¯1Û3+5««7k 9«§¿ °<ë³6 ´!´¶@´÷º/Ǹ‚‹´T¥´lÆ´åé´µÓ(µ‹Pfaµ‰‹µ¯ µòÁµå*çJ`{²Ï”²&³²¯š²z¦{º2‹ŒçB³uj³‹³:k·=‹·7¢·‘`l‡‚‚;¸Ÿ‘´Ï4iÖó„*ñ´eµ‹ bGµ’»©ßJŠXй^kªå¶ìA¶¡k¶£›¶nÚ=§‹ºlÿ«º ™ÔZoúšq;·úµ§FÓ§´k+¶«6-ó¹Û…»+½¸Ì¼Î$¼eC¼)‘ <ÀŒK‡Ž«¼aǼÜʱécEÐ[Z—+ª];²_k²©Š²«Z¶ïz¶c˜'Ýk)ßkº©»œã �\1w盾±Û¾û¾µK°ABeõË¡Á¬´°¿…¼l6¼�ªLÀÇ۸ɻ¼�ÛÍë­ D ªÒKÁÔ;¥Ö;¶ì®ðÚ²)™‰I¥X!|œWÅÐBÐ)s÷ü¢¯+·+|2îÛt‚@Á¿,ÃÆ®ÙV&¢A5̬8 Så¿FÀ·@Æ©`=…¶¤ó+D¼.˜ºO;ÿå¼Iü K,®œ¹Ò\½žëL { ¢¯ma†YÜV[ÜÅpÆ*ÆÈfœ§ë[·,|·ÒÆ(”@Áò+Çâ©y bÇ‚aÃyüy&ÀǬtWÈ‚\“,rÀ‡,,‰¼Q“ÛÈ� ²‘<½%kÉü¹œ½\´ìžÌVZ¢ìT¤œ>¡1ÆdœÊ½J·ÿÚʳ °ü+²<Ë×á;7â�¯™ËúsLjÚËóf¸"f=x—tÃLÆÅ|–Ç<Ä \Ä»ÀWëÌÒ8Qªä*ÍœkÁì:ÅìªÛ ªÑ0á·xÒ"}JYă,Os„͘ÔlG–Ò&Ó ­0RmÿX™ÅS{᪶âÑ•ð1WQh…V�3•´(€,À&²y9 €Q*í1„EÁ”€T]�óRã™®Ó‚ îq‡×§ÁQ„†â«¦2wìЛ°J)�ÁÓ~+H$Í“fÀ0­t+} -} /m42MÓ�b¯2£Óõ¬%OãÓ,Ô[æ"2½Ø­0SðØ� ÙE= G� Imq;ÄÔd� OíÕy(ÕT�V]?#êY­¡[í âÙ`Ý(bM›­¾«¼Îh­Ö�ÔÖýÖp}E¡1×@hD*Ý“y½×'Ó×vTÓ/yÓ9­¦;MØ0cØ+�Ø¦ØŒÝØÙØ=Ù•}Ù@—Ù1ÿÑÔœ= PýÙ¡:ÕU]WmÚ÷¬Õ£ÂÕ�m�_�Íaíܰ�¦2igж ì6•À¹ÛÌäÛ Üšœtw=ÜÈ×3mGayÓ8M‚ýÊô½7 r ®`cÅ]ÝŽ�Ý’ÕF� ¡ÚÜ�—šmßá=Þ[«¥¡=ÚªÐ=X½Þ¨ÝÞªÝÕ§ß¾ >6Ÿùâ@±�߬\Ûˆ±ÖlÑßôI•ö¹Û@àlF×|àüãÒ žá#ÕàÊ áÌ=Ø}ôÜè…†á1­á×Íá�­Ý âˆ@'J]â½àÔâíÙ)nÞ¢�Þ¤=«êmäYž©½Ú5þ­-'.Éã&.Ûù•ßx·ß�AäQÿ™™GŽäJ.bLÜÜi;¢åm¦àS ¾ÜUÐÜY~9|#]NQÖSÝÖ=Ob>æNÙeâhŽÙKýÝ›ýÞðMÞZ ç,îâu~çSšç4>ë}Ž%Î>=¾Â@.B¾zâVQÉ ÿý üœ>}n×=)é–@égé ŽéU^œ®ì{ ân–½áå§@êâžî°`ENæf~æsLâ°nâ²^Ôµ¾ârÞâ¥Ýn0Žç2®ç×¢Á<ÆŒH¼>îΞ­t†ÞɾX!É싞äüí“ÕäÕí~î žDÁnðŸQ:¬õâ­¥å}�îäÎæŽîê¾î@Ôî©.ÀïÿŽ¡<¤ælŽâ }Þ‘Þünçã¢âÞmðØ<ð2Yðêsð³�ðI—•Yyì•�#ÌîÎ ñë#HÏNñµeñ܉à•.åÛ®œ�è€!òŠEò…ý)(êäUî¢^6,¯îìžÝ1¿ê¡MóÞ� à]ï~ï:?<Úþô3.ë?žtF¯œHŸ>J?è x}JçôòõIÑð%¿ìèÑìY¿ä¿]×.ÜO®×Qþå—.öœBöë¡&2òužö'?îlï n?O£^Ý-ïòÎÞÏînæxÿêzëC?ëoŽï;?ç$¯ë,ýï½N良ã‹� �?ÖùM/ù”�–oz_ñ¹ÿßËZÿ©�¡xúÄMúa¿,$ì©«ö­oòkoÒm¯òo¯àŒ}ûV4t»ÏêñP ä ˆË`/„½0aš4‰ÑCF�$΢HÉ""ŒlܨÊ#/�•DZ!)� Á[·,­´äÊUÆ!ž¢¹ÉæÉ“uB!Ó3å-dA…&\ˆiÀQ¤2J|dsÓ¨Q5r¤ZÕêU¬X!mýÕÕ«ÈJ$­ô$KFg1´B…¾bÛ6Ï[¸qß"EjÂî]¼‘"Ñ<å4ÖßX)Y²¼t‰®^¾§Zµ"Ò˜ÈN�µ$OV4áeÌ�¡ˆ VlÙž}DÃ"mÌôi—®¬ÖÛzobÅ‹e“¦ ËíÿÛ»L)RL• ãoD`=—4Yð Q†!ê®x1cU�ª@òn¥8J•,]ÂT.“¯Sœ5“ýYr£t(�(ÑiT©YåÏç=úôé¾ôï/ÐßÿÏŸÚj«0/a6OqdA\°5¾d“M´>&°°¼^K 0À[é4ÔRs©¨¢„0ñÄÞzû‹,±40%M[mF˜âk·ÝèÐqGœRºl!ïjm7TЬâÈû@²eÉEš$#¼ò‚j &!õÚ-Å9æ`Ë©®š,1Â,JJ/)¥œrj²É<´ä8ãÑ%×ôÂË.öŠÔ•#«à’>@³²ï#üxÙ�?ÿú{ÿñÙ*°°LÌAJ��& £ÐBG1¬Aÿr3FcætåNØK1•{j²EI¥q5i‘¢y<©L31 Ò®!)Ò³Ï$yYÒ–&y²Ç”Öb‹J`­ä­·,¹ìÒª/E SŒ1™½…(õÂ�•6%s3N9ç¬3TóÜ“Ï#ÿ t^ª•®ÐCõKTÑ}åQ•’tÒJ¼46 7•ìÂK25ÔQc4µ]¥Vm•ŒWwŠ5Æqk=åÖYrÕ‘Ù}õÔ„`gIB�eÒI2�’òÙ†ªŒäJjµ”×Ë�´3fpÃ¥kÜrk9ÝcL]—b™Þ…×Ï-é•{ 5ÿ4ß} XÔ_€#XÁ‚<8ÓV®…a‡a 5–ˆAD•iˆ,Ž…Eâ4~QÖY=Yd:HFîW”¥UÙH–ïuY˜½uöh¿yÚTªÝÛž+Ù¶Û]y=Sèˆ.÷ht•®îsò©éóÊ+«5ËšT®ùkšÂ1šÖ6íOaì7Ç}ûNUS¼8c�~'q¡Ž%âËè£çÛï^Oyå*Š=6Ùe3—™)kŽöñY°Ô9j¬²µügoƒæ¼óY‹v“R—¾dÓãE?u@Wïªuȼ.F±+Ðìhg»áîº §þu²À!èwÁ›ÕððR<ÍÍUuKf–‡ÿ‰æ=âyу޶t…�’YOpØÓÞË”³Å5.eæ³VVÔw9 ™é}Gñ›æç ú�î~·ÊÔ®Å?ùøï܉AD@01YãýÔªÝuªa½;¼8A Ï‚xª˜ñ4X�üDyË›ÑnD†é„9à•B0�ªë.{-Û^â¼Cñ9g‘;߯&öyÏ}œëa›p‹Ñâ‹áÆÁˆqŒdÕÉ’Æ:öŠDm¤Èá8½b"ç˜äc!]Ø=ì|/|“°Ù %‡I¬Ts]¤ÐÆÅM¹|“&â”$9õdNtVE3¥©:ש™¢½“; | BÏÙS•ø<[+¹èÏß…rµ A/vP]&ÔŽ õeC�ùP‘QÏŽ%R2-ºLŒÒ±YΔ¡àhˆºCúÌšíÓáOªžnªô,]È€“‘KÆ”*4­é&o ™œÆH©<½•OÿT •CYÔ§+‘Š¥2uÿxN5hOú-^R•¿LL0!ŠB‰Þ)�OS&÷`HVhšUšhµŠH¯¹9“Î ¥q‘+]Sd×»ÂT¯áëLmÊIœ–K§0!,Ž ‹X:(0Œ\iòØËD¶‚´¤,./»FÍrv„$ü¬X�)Zd’ö«¦m&øhÆÑñy´�ôq-[±éVÙÂ5¥@„�m{ƒ[àè–[á/$ŽÕGeõ$kæ1¥¤¸'8ÁYbðÖfG8_¾SûC›¶½w¡ÔÇ…Êqmx|àìMÖüƒÝ¥,+fq·²âä8½¢í‚Hœ ä¸ ½K²ÄäæBÐ.Ê16päy @Éœÿ!IxrP(G™Rì1pq…õ.YdYËk3l¼üåÝjÅÅÿ½¨€÷Eà9UG|I°Uœ¥G®°Nüƒa¶høNî%�@<+;îÆ&îŠY#8·ØÅ0þ±ŒqQ²;âÆEÞ1_{ܤ÷'Èû¼ ‘s|ä $yÉLvr”¥ì *;ÈÊWÞ“–·*ÆP.ö/™¹gæD¡YDjæl›«òf‡JÎsÎW�rgÒdx!�æ³fgôgú`)"t M':´f´r0ÒÛ1Ò“Ö1�Eâcny•Emì�7¦Ó­éuó/;�7 Ž~x ‡Ç‹g|8ɶêÁíéð“€~—~•¦ÿ÷Ödpe ¬jyÒÄ×T±|G´^ñ®]Ù {ŸŸmv¡}Ð%ÏlŠÛŽr•³¼åÆ�4\ÿDnTš¦—^D¦ �swæÈ<—7å�xœ0¾ñ’|üª�æü£—þòTÉü±pÙyµ|¾A Sðë¢}{m$ǸÆ9nÁ¢AgoÚKLûËŒëä-νÜÃt’ny9LÀ»¡9¾³9¿Ã¹À3ªÁS¾O+¼ž›·>�>é[<ÇËÈ3'ì›7íÛ¾�è¾%ù¾3ó¼9�¼ò³ºóúz9=®»8;»°d ;Öë¸åA% ¡úËûK…jûý»=þƒ;ÝÛ=$@½ ¾š»9u#*Áë4„·P“šÉ›ÀÄ«@S¸@ !¿òÓÀ ¬<ô@î32Á\#A1Áò»ºiZAû 3ÿ<6»�;$¼Á>ÈA›™½µÃŒ$mÛ¶Eó?o£»1)Bß³1™Ã±½¾¾+¾¿;¾l·LŒåƒÀæ;:*:+ÄBÙÐBã ìÀ0A[Ø–mÁ%ì*ŠuÁ¯ß8A5D«ô+¶7ôº8\½@Ó9Úq2<ÌÃØ«?>,²³=ò5Pã6BĉC´;KDI[DtD„DdB-Z‹Bz™Â#¡À ôÄŸ+D8AQÄ>RÜ-SDÅ0QÅÌbÅ:qEŒ€Å\ÃúÐ:Zl¿œÃ´ TâE<ÔÃ[DÿF×;´b4Æ @F‹+DCDÄ·ø=hlÄ™">ãÛ4l|BÿæÛÆÃÛD'ëDêËq$ÇKêB/¤Ç¥KGudÇ’!‘V¼•�LÃy”E{<”Ô»EÌÅäû¼A€4�ì‚t6ƒÜ „LÈA\Èð(‡ô&EÌ;FDÂTBÀ³F}ºHK|@mŒ@%ãHÅûÆ�”�— Å‘ìÂsL{Q¢jr^ñ—q9°4¿Lâ¯c鶬©#˜ƒ õ`„–ħ Ë©t æ9 �¥\ç¡ ÆÅ©©¤iˆtÊ0˜L’ý( ï™ ô@ Á™…@œ·03'`6Ò4qœ<0Œ©³ôŸ´„•µl”¶ ½S½RÜŠ¹$ĺĬfœ ºÐËw¼•¾ÄÍÿ¿Ì§ÀÜÁX Lf7¸0LBÌÅ[ÌżœÆ�Ç ¤ÈL‘É ƒÊ‹Ë$‹Ì”ŒÍ<ŠÎüL% Ms:O“LMõ\ÍÕiM»ÑM¶œ·DAY“Ë%ñËD±ËÄËÞÜËÝÎ…\BÀ„ Ádäì½·`N¾HLèé”ĬΠ»ÎÞÈÎí‰îì‰ï¬…ð€ñÔ6ÐÜ-ôÑsROdϯP+µ„OØ”OÙ¤Mt´ÍûÎüÔMåäͤðOŠÐE>~ZÄãt4ÍuNShPÍ´^”PkJì¤L+°L_ÀÌŒÒL…âLòñL-Ïí#Q�2Q0DÑ®pÏëBˆø¤‘ùjÝÙ„íY©¢[¡íÖ»•Ø¥ØפhÚ§\â”Z=5ÜE\�‰W^mÜǽׯ}FÿÉœÜJÈÐî‘ÛÌ¥ˆÍÅÄ´½ÙÏÝT�ýž}C¹5݇%Z½²OTe]Uå[rõ[�=”t�ZÂ�Z>MN8ÅÝ?ÕÝAå]”õÝÈ[á%^EÂ\õXÎ8ÏmÞ�«šB©'‹d8�¢`rJ0K•5{QÈÈrI�»€‹”Ù qä¯ý Ãɘ˜œä‹µñ–ø T '' ¬'jö Fx·"SÇHì�¿ÓÍ„Õ_8«ñßÓ `Ó`¥(`;à0Kà£\` l`—xà·ˆ`Š˜à#^\»à9ÑÅ ^ ¾> )aâ˜'LauÌšf�º]±ža4Ž©ÿ‰&»a^&¢"1àý6¾!f¶ îÌ$¾+ fbÎËc ®D –b¦âåù`I aá V FáSa1~$Ð{Ø3NcNN�5‹6.¯7Æ„8Æ=¡c¶ã Æã(š=6�>ÎÒ?Ž@®\²`àZ(d'Œb™bK¨â1rd6��H–‰IþâJã}ã)cæÒNŽf©ùd±øß±ÂacÐa™àá=ðá@±%âþ:ZW.b>>b?ž%Ž;[nbÉÐå!»¢^Nä_^dZ˜,6�-–ä.ödæK^fLvaM†fi>hú æPþ£ åRî*T@åygÿÿçZâV&âS9ç<@buä%nçAÎè\~â ÎD.€¶ç1ÂçGaáâ òâ«,2€VæDafGpæMFhŸ¦üXLkRyhV“èù(–égUçÀÅe'‘n‚GD 52ôx6�‡™çDf réa¬Pš š8æÄØ�"Ç¬Ñ 5± ž6蟎kŽød°êŸ(ê–ãˆîá@Qj�@KÅTHDI”r–j¹ j«�¬Éê­Œ¬ñêáëÉ®˜xˆ�ñš¡ˆ´¾«µ†Œ¶Þ„·öf¹–kº »†‘1êÈCjùðk^lál}Ù—ÂN�©vI�îÆ–gÿÇÞÈ~É– ÊîŽË¦éÌž…ÍŽÎÞ‰ÏíÑŽî´ŽzÛ¦`ŠSæk@qmØ&¾d™°uZ„Åž“nZ§¡µÅ ßÌêì–ˆ¬Á¥¬¥ªï±¶lIÑýÞoAëGqd붆né.ð�XÌê¾›Áî÷Þînîë–YjÖTÌñïu*oÃŽ ô~õVLö¦÷~ïø�ù~û>qãÎïýÖïþÖìÿpàp5ù7Y`±ž6ð¸Fp&³îÓ`ðìvpÑ”ÿë Ž Ï—ñÆpÛ–‹ ß“Ž�Ïî/‹/·o²N�gqØðo€ñ÷춦q‡kÿGèèð ãWïâ% ¾`0úè-I087DÅjó�zó†6¯g1â‹;:ìUá“ÀAé¦-ÿŽ›H<ÚN5‚Þ ²YLÏt¿¾.6‰‹°¢Ls¹^ó®hsË­!M™9Ï’:ï-<§E=ßóèóþøó�r%BçC_SD'E FÇïÄH' Iïgö€†»ôLÇôMÔüµ7ûtu'õ_0uŒ’ªóUuš óù°óW§Iœ®6ZǾu.Êõ]?Õ^Ï�_g‰`?aØ v ‹tõ˜ô}ËdKÏ”fwöãô£s³i¶a³öÇvmתÃõöSwùwÿ2‹]Y¯xt¿fuÿÑ«l÷cy÷x_‰yG{w2|§ }÷ç³¾fov�vù(G%+K„�f…/³m·Ñ†—óogõpwõ‰j‹ßs[?/\§‰BŸ·CWÇD 7 ùzô{'�µ9ùF·•÷÷oùã˜/IÖšùƒ®ùƒ»y´@‹œ'ŸUŸà ‰ÿ/Šújú@Ï�ì6z]Gz^Wz_gz1ìªï ¨'y©ªöäîw ù÷UÐú�Ÿ�®—y°Oc±ßöºeàÓ« ïôyéÑK?ëécÖ].³ÆøJ0Ñnö}´œVˆ?¾à‚«ˆŒ†½ÐHã#í»¯eVóÎñµ„¹�R”tÿî×oQ–yj&2ªæÙ„€5 Ýò¦§ÀJ¨z©Ã³¶×:¾µâ` ùÊ×°ó¥o}‚qßû¿Å5®~&¸ßHò·¿’Yî"²x! xŠB¯&¤ ¨ÃêÆ�t3Nö$ø«î½®NŸ7¨¢z„íƒFäǸޙ…"QáäøW9ÿa†1IIh¨¥Ö‡Ï# ©"Lsóý$Ä‚UNW¸#�h…$‹ƒòà$œø(^DŠ%ÄšýÚ‡¿(­°p<ˆ_(C1vŽŒh4c–*¹ÆMnÒ‡�LH%Hǃá1�G䣱üˆ@ ’�º»Za¬,Oÿ‹1Ûe")‹IŠê†ðe9)L5zò_' åöFiÇR^A�¨„‚*±ÂJ'ºRq»›"ýyBE¦�‘Y×-sI^îÁ—À<£&‡©NþÆ,’yF0#Í&"š¸'>Á3BjõAž É*Е¡¢ 5B*¸ƒàÅ}h+¡$<¢È$m¥BÒ|¹Î�rÔ7ûzç�.âÏÌГ0öÄç=õE~öÓŸh@ jЂ&T¡Kcè] QjJTº±h0ÚÑ¡57í, H'OΧžAiJ÷²Oj�ô¥0•éLkŠÐ…¤¡:uEDM"2Ü•4B-*ZÓ”£ò"©”ÿiSMúT¨ª´�,­*³`ÓtÍ”¦Zåj¼ªÓ°–d¬IÁÒJÔªØÅ*å£ }+SKj‚“¢´®ÉÞH©W ¤¯¨È`ñ‚üx¶ ¦=­a‘‚X•0¶µŒe«[—*ϸNv®••*F0ëOÍêµ³}íM»z—ÑV¤´§5mj�²Ú™¸¶¹hýÍo’ G¸J¶0›Oút+OÞàc!1(" ܆Q†¸›0îq´\ç²w¨Ð]ŠtÿE]®`k³QË.³2ëA�z$ào”{ó¢÷´ê­KÚ«àu¾Wñ½Þ|R_½ÞWCÚÅ wû;‹ÿ"b¼Ç*/q lÚçd6 >qÿ'ß›08‚ç«®˜0L+Œœ /$Ãñ-*ÂÛáüE Ä£qH¬“£¸È¶R/Rëõ1ûÐΆ´AÿBËÝPÛÚæ^0¶)³mu»Ù¹æL¸g1nÝ”ûÜön.§9­î½„ ßþnw¢ßýl'Í;7õ¾7›o@ï[/þþ7À‡˜x» ÇÍÁ®q¢.| —ËÃûq‰›„âÁ¾¸ª­´ñ•µãùOÈCP1t[5&g5Ê­r–ó|£.�ÌC>sÕöÆá®xÎ�’ñž3=�?'PÐ>tÄ�ÊÐFº7y³ô¦s]��×Á¶Š±“ݼ™8;ÚÓ®v´K::]»½¿¾ª°Ã‰ìe'îÚó®v¸ó=árGÝÃ`÷±›]ï†ï;â7.“À~…7|&¶žøÉkzñtoüã /yÿÊsÌ–;æñùÈï¼ó¦çó”VúÑ®ý˧}˜S/û)¹ö¶?ñìs�Î<—þö¾o®îƒ/€Úÿ¾øŒ¾î‰oüå£ù¹W>ó£/ýéS¿úÖ¿>ö³¯ýís¿ûÞÿ>øÃ/þñ“¿üæ??úÓ¯þõ³¿ýî?üã/ÿùÓ¿þö¿?þó¯ÿýó¿ÿþÿ?    & . 6 > F N V ^ f n v ~ † Ž –  ž ¦  ® ºßo´ öñ$�ˆO¼ ZŸ Ò ¾,Å â ��‰Ø`Ÿ æ ¦…¡ïáÏ!Z$¡ò]ƒMÇ­‡ZaÂà žˆ‹¸l^šÛRᎡ-d¡úZŠ~aµ…át�áš¡¦¡!¬!›º>ʼnX–AØá¾ZV¡>˜[øab fÚ òËâT ¢".âž5âB"ŠÈe4ž¥Qâ½Yâ#‚TâÖEpb¥y¢½�b!Šbv ¢)V*šŸQ ‰Pa[%+¾…+^'Æ¢¦Í¢$�Èu,.æâ!’âA¼¢/þâ, ãuã;�bx`„2*X@!ù,*ŸüÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Åˆ 2jÌÀQ†Ç Ljœ@²¤�“(¨\9§¥K#0c˜ £æš›8�8éÀ³Ã@ƒ t�Ñ£H�öì™t‚§P/J�JµªÕ«X³ju¨qcÇ�!G–$‰2åJ•._Æ„9“@M\âÊÕ¹ô'Ñ»B›6]ʳ)Ô¨[ L¸°áÁ]3rÌàQÈ"ÇŒ%[ÖÀY´iç¬eK³¦Ü¹;{ÚÅ‹WoR¾üþEp¸µë×°cNœ`qãÇ‘'O¨lùrf͛۾ý—®è…¤I›FŠZõ_ÙУKŸ.�¶m°�ÅŽå}YÁïàà ÿ÷LÜ8ÏÑɇ.?Ú<éjÖÔãËŸOÿ¢õ¯ŽÃJžÜ½û÷ðà�Wy¡�‡\zD­§_ÎV߃F8ŸzÅXcEY—ááá‡B„("€v6àgæùt ‚y)ØRïI(ãŒ4F¡b˜¡†cpxÖ‡ Š"‰H)¢TL6)Ç“P’!唼¡&•XÆXã–\vyÑ�9êÈc�—ñ¤‡BI¢‘ÖµbPM: å“SRY™•X^©¥—|öé§A`*†_ccvgæ™i A$›(¨"A7ÞHÁ¤”ÆÉäœtÖIotêižWΠꨖjj—�Ö6èŽZÙ™x$ÿº¨‰G&YP¤RZ©¥˜Ê¡é¦•yú)¨£ŽÊ±Ȟªì²ñ¥z†…–ù*¢iÎêy�º )®ºNji½þÊ©°€*B±¢"›,³ì¶kØ�?Äûì ô¦`¯øæ;ľüNáï¿,p¬ÁÁ«¡ðÂM4ì0N8ÑFÃÄK`ñÅùækÃÆàñÇwü±Çt”l²¹èΰ§»,·l¼òâGï ö¦�1¾üöû¯¿\0Á'¼°Â;Œ+މQ\ñÅ߬EÈ�ì1Ô6H]€É'‹îÊ.wí5C0ÿ0o½÷Þœó¾;óÜ3?´C]tGK¬4 L7}3ÕVóÿ-5Ö%£¼õj_nøAa�M³½u4îøÙC¤=”WÞvoÃ÷{u'æÀç ëö«ß#“þ1àt^,ׇ·Þuâ2“�‚ã�Ÿ-yå–·�yÜjpŽ+m ‡>ÙèP÷]ü߀«>*ë®7ß.ìÊ0sÍ´7ùí¸3pùÖyWÁ.º¦¦O}üȨ+/*óη*ô�MÏxõü–pÀÙkO0ügŽšï‘^øÆW§òàL ÕÒ§µb©à�rŸßG¡x‰-v‹›ýöe?µA ãtBBGñ€7Ê›ÂçN r$ˆ¡ ¨@äaM}3x  "8Áö ~‘ŸÿiW?’ÜïƒÙ !ÿJ˜¢zW*d¡ ¥CÆ�†\`ò8*òЇ`Ü¥'»êÕ¡ˆ8"÷·D&þŠâ‡§©*Z‹Gxƒ÷˜¹Ì¥Ì‹O £ ¹4F!š�jL"GèF¾ �Br ÞÉ`Çbq�|ìcÐæÖ@Âg� ”P!˸Á!tp [cDÈDvà‘ˆ¤ðÆò«J^ñ’˜|ƒ&797O†ò—’Ô¤,†!3_V�––é�]à™yˆ&ÂD(BˆÝÄ\Mqƒ6·Ù˜šé†;—‘‚8ǹ6$jèL§ ÖÉN ¸³ð¬•y€IÏ åj˜(æ1ñ•ÿ̳œ„™Íô×3/͸‘"îHµÙi²†óMéÜñ[œ !o·»K.o@Ÿ<Ø)W9¾ ï$¼ÜßÿÎ_æ�@ö²›åæŸv«½ókŸ-ÛËÜv·S-tŠsüµ§Ò“¾ôZ7]ÝOHÔ0rª ·$ôFÉÈVŽ;ÔÙ.è÷¿Å ö·•Ýì�vÚsÎvŒòüí×6Ä/ ñºWïã¾›Ó"ÀúÖ› °�ýºJåñç€<ê…ïµÉ9€r,~ [ äQ=ùÊíòd?;ÎùªsÏ»=gp÷€Ü�ŽjºÇ¥a$d:ê#ÅÂÕ·žõ¯�=ÿìgÿ§Úqð#ÿ³n’ßÿñû®¾ òg|„! Êß<óÛÒõÏC?ôq7zòg}«ÖÙçwÛw#Ýw3ß~ "~ãw,§b~�t{!—~U·~WWoYwo,gl.'ô—=c‡|ù—3’Cm3ÑÏÇ/Ñ7}¤'Ÿ�}:¡}“%KŸã}ß~âG~~B�ðB8„:äIPÁBê7ìg*|˜o!X}#ˆ;%xyg's)¸v+¨o}Ð…^Øs¢÷s1X}3h€5ˆ€%Õ-(•7 ˜1 <({8#y71Up‡xhE14„DX„*€ˆH˜�J¸�öfhOÈuQˆjSX9Uÿˆy6's‰¢‚Ðu^ø… çssWz×g†N`ƒ$¥†8è:èz�>L©§4x˜‡zȇB臈€8ˆ‡§ófˆˆˆ-wl؈”óˆÉ—y ‰iB‰–x‰}†(†X†ˆn.CßCؘ�jø�¡¨#sÝñG*@t­A�¸bA¤†v°ŽìØ+Vó+q�ò9oø†“'ø˜�¨³mÛvNEu9Ù6œ6wP�‰FüXj—R u33Nyu­Wh1�G€ŸñO°C¶×2æ@ÖØÙ¨�ÝÂ� á�€Ž—!Žäx6éØ-ìØŽ˜òŽš"�óÿx6õØ€÷˜�ø¸� é��DYIy�D ¹ É�-à�ô‘Ú%‘¬G‘Y9Aw$É‘_Ä./Y!!y�#Ûh’(‰5*y, Š„–€Žñ¢Ž3iî(5ðˆ“q@�;Ùz=é“@É�B™NE�G™”‰� ù” )•'@•Tf•€•©j\Е�ç.p9–d9’“g’/�–&³–+Ñ–hXp)—?PЬg56Y'oh5}é—>)>ù“€C$i•V… �GÙŠÉ�Œ Rö�â‘0‘„V‘•©j˜Ù‘,³™œ™eŸ‰–“ñ�Žèò@-i©)—¬ÿ®‰—š›Ró†Ýa›ùÈž€™›$²›ÿØ›9�À¹”Дà OÅ9•ÇY•Éy•Ë™•”³•Äñœ_™nAQ�!Y�×É�…u¤©¦)�.9G£šãYž#ó+è92êyî)#Š›X£›òI˜ôù3¿yÁ¹mûÙýù˜ÿ™:™Úœ\¹‘™Ù.ÒÙNó+“G5�Ó”&0¡jêpÙ†ùò¡ê¡ (›¬ç)ëY› ÖD‚¢):+ú3NÓºÑ�!R0Tp¦rAœæeœR€œÊ¹Ì©•)Z�‰¡¸2zº§Aª)C 5E*¡“†¤Ijœä�n9D1ŠÿÊ¡#¥ßG¥`¥"Š¥F¶¥Ò¥èÔ›¦—1¦¥&"fЦq¡¦ÂŦn* pJ  ` ɣЩ™x){ʧ7#¤ÿF¤ §–ƒ0…j¨½4މ*‹Ê†áÓ¨Ž ©­'©”z“—¥˜š©šÊ©æå©gªK ªs¦T�¦ü¹¦þÙ¦ú¦qZ suúIÑ9­x‡µª§}Z'2 Ç«i@¨Iz¨Âzšo9ŒÊ€Sꨀ¬ÓzͺÏz©Ñzšê¥mã±�z3b:d*£Ú­¥ú­§®©Š£«ª£ « º%p©†íZï:ñ:%óÊ1õ:š½ ¿ª¯ßÿYmö¯n°#c>û³ë1Û)ëùoк° ;Ÿ?ÓJ+±ÕJ±Ÿj±¡Z¦ÛJª\`ª5ƒªãªªåÚªçz™$k§}r²Ý’²+Û²Rò²³%s¤¾Z¨6;¬�‘³ÆüÃûÄýÛ"‡ŒÈ± H|1JÜzLÜÄ‘�“\ÉlÅكŢŜ|† ½³Á ÊbLÆfŒÊh¬Êj<¾‰¨ÂÛ½NÇ„DË�ÛkvLžKC¬gÃòÛË¿ÜÃù;È…ì¿Ç|ÄŠ<ÀŒ\ÀR"��ÜÑ �Óü6˜$%ŒÉEÁǶÅTÐÉß¼Áa,Ê LÊ"lÊîLB©¾éŒÂ”ÃÎçË€"ϺQÏVóxÿ¤Ïó;SÒ”÷+úûü+ÄC,ЇLлv`ÍÌzÁûÀ¨?EùÐAÑd0Ñ×ÌQŠ&Ý*´R�aF¨Sh¥¼À"Õ$%ýü2%MÈÆJàÆî ÏõËl1I8õ|›‚@Ó Äzù3Ég-Ñ ¹Ó=-?-ĈÕ}‡ÌP¡†ß{`µS"�YºÔ Å™ÕR�;MYÕàqÕq‘ÕI±ÕÆÔÕÕóÕ„Ö5ÖLÂØ•Ñ×d�ÖëìÊíÌÂ,ý p]ÐILˆtmÇvýo¸×QÌÚ: È<ݺ ÔPØIqØï¡Ø:¢Údu¿ÙÀ8Ù LÍurÙ•“ÙcÕ‰†Õ[ÿ¬ÕyÃÕ áÕ€Ö!-ÖnÕ$Î�¬íÚ¸£Ò§ìÖôQÛ»¶È·8u}›¼Ý€¾½ÀÀý×ÂØq1ز‹X¼‡°·ÜÝ²ØæÕØ*Ý &ÙPLÙocÉKà!�£ÝÀÝIàÝ ÞL#Þ/@ÞXcÞeŨ]ë}í­u¯½Ö¯üγýÖ@×0×!z»�½�=|½/9 àÀLÜÃLÈÆmà•�à@ .ÇÂܲâ6çØš"Ý�HÝeÝAþÇž�š}œÍž� �¢M;¤½¦íN)å-î�ï Û+}³òAßÞ|Û÷]9¾;ž=Ž;?ŽÓ~ ÁC.Ì>MÌ@�äeÿ¡äLÎNV5ãà áì%áMMáAcá~6Îáέ þÅeî8gžæ°æ ¾Ú@.%îÝÊ0Û°,ç¯� †W3c2yxd×x”¥‰B0Õý6IC ¹©Œƒj“ŒË4Ìz�c.´ˆ  PËD.`á¥Fºó6C5T‰ÌPÙd�f}6h½rOx¹mý@72(".gƒ%±mÉ•;ð¼5Qv&#.•Áú¾ïM8P•9"ê"·ýš³n/µþo·~›¹Þ`CÅëWîëwì\Ž?Ä®ÆÅÈÞ·ß·ì ÒìQðìÐ.íÔ¾àñ3™“íe–&ܕ߾áž3ãÿî„å~®²­é=úÚ Áî9ãîLYjñN9cydwïšÂûÎï*çïÏðü#ðÈBðŠšŸ ¿l ï“ Ï^_½4¿ž@ü¸K0ì €0¿À¢ èñyò"P$_ÍÂyyPôA£òµí>Üí/ŸÆ2¯êä.§ªvó9oY�áó½÷îB�\ò^…H_'J¿ô|ÐïNõL õÇBõÄjõºg^Yi[Ÿ�xÄ÷ìñî”9c�@eöŸöÅÎhÇÞöBûögÃìÍ>÷ÌT÷×½˜E¢÷3TMé÷ù øLrè<ø­]øæzø°Œó¢î<ÿŒ�uàøK0ôLÿ-ù%ƒïeaù—ßô™ÿ6ÿÆŸ¾àé¯yš9¶ŽE‰‚ú*¯ú”,ñ¿fûH 4 tQÐÂA„.dØpaˆ‡L¤(ÂâÅ15¾àØ‘"E!E’!Y2ÏI”ò¨ÐràK GdÎ\RÓ¦œ9¹ìäÙÂçÏ2Ae íèñã�’[”âaÊÀiAžQ�LUQUÀÕ †Eѵ£œ£ÄN k³ÁY§ ZV€9É[:qK–[×¼ysæ4Ñ×o[ LóœÊÂ0‹‰,fÜØñcÈ‘%Pٲ̙‹rLÑÙóÑ! D�ž9s/N¿©U¯n‰Ðà;wJÛÜRÂÿí´/ ºp}Ðáï†%½ˆQcÆÍ/@‹9— Ê”pÙ¶´L›7OGÝù¨P¢›A']Úô© î;§:©ªâª€¬[etEñ5ìØ²5Ï6H»ð[$â¢Ã92F-/½N[ 0Á˜ ̉ÃSl2 +¬Ð²Ë2Ã,9Ï>;Ê@Ñ®;â4!V3QµÖz c›-»%ÒÊ­-„Œ°8 "Њ³è8äÄ;й�„ Ž-뮃q‰œ”�2½Ÿ¢°R¾ð^°bKŠêRêË-˜Â#-¨Ò[ï½÷âÛŠ>û>"ëÍ Ì:k-ÿÚP@ATA¼H\p ŸÌ„ð0 52 +ÓÿpÃÍ:ì 4=EôóDJS­ÖôŠ#°Ü„3Ný椳֗îŒkn»Õ“O>&Mí¥@¹+ŒÐCÓ54Ñ•€CGAc^z%U�Ò-}m apqÓì>ˆÆƒl4‚ÔRMEUÕâXuuHX�;2�Y©ìVsU‚JŸ¬ŒK~år"/‰“LôubYfåcÚ£¦¥v‰ý®ÅÖ-¸¶í–[SïâSÜ¿õIÐÕ5ºÂ/’VÚÝäˆä@^zç½`jª�Æÿ75}1õWSì:õôÓP ¶QOAÊ6»gª©†cm¶ÁpûmVEm ºë&qb: È4Œ³Ó˜ã<Yä`IÖdó(ÓÜ©XV“«g_ˆ–"™ålÀæÿr¦cgžMM{j«M whÆ‹>útÈ”^zѦ‰„:êÏ/ýj²æ7Ó›` &Ûì²Ñþœí¶ßv;îëæ®›î»e�õ¾�Ì')7Þµã^å#\Xˆ 3ñÅ¥j|ÙÇç‹|ò‰*¯öòk3Pç�…O;ôÑ[ ]Ôó_Lõ¤™ÞÌé×Ñ+v³»ší4ЯÉÄk_“QØz76/xžñà`¼ãInGYóNƒÿ·¼E/wÚBõ'8_qXÜóÞÉŽ¥2Ç5 rõ�™´àd9ÌÙIsœ›ƒüªv¯q Í~¥ÃŸþ&ò$Q‰îrT ¤ðDÐP$ S¤¢˜Äd3%e‘àb½ÈE›õÆf cd“ºÝ@�€ÙÍn²ðF8ö¬s¤cì‚“ê‰Ê ; ªb—@0j$ä @sÆšÔmF B#éHDÒYôAÁ!,9‘¼éI€IO<ÙP&@”£Ä %M‰§Å@•«\%_úR¿Ÿ¨A–³4˜Áö³-*é‹ QƒôÈF¶§=F¬•˜D&:ê‰RˆâD¨XE+⋹Üå.ÃØ›2ÿš1.h¤!ÙØFÀ1ަ¢#)˜<Šm�;�?HA¶E ó¤ç!·™Hº-˜�Œ$ &IK“!Ñ$Œ8ÉO6”%)%pJJ¦’•¬t¥è„ËYʲ–6š¦wÙK_2aŸÄL—1�™Ì-³™Cxæ£)Íkår‹Õôâ5]“M2"r i\c[ÀNqfAŽåìÃ9ےήS8íÜÑá™ÀгžGÑ©"A5�}BR’3è%E“Éüdç QIèB*ÊRB´+�¨*+ KŸdT£íh?zš�Š˜$=”I—¸¨&ª´™-MƒLëªKšvѦÁ©ªÚÍžÂäÿ§Aª©viT'e{vÙ¡S³êÔS…ãTxFu´¥=mj³ÊZ®ºÖ« ëÌl2Vž”õ¶ Í-Dw;ÑÞj€5Á%°Lﺗ¼&FÁ @nr—uÌå27¥Î�"a£›·áz±º×#vï¹SÈÞà›mô®e¿ˆÙ— Õw 2oDÐO˜Œ–´Tý°UÆHÕÂ×|”|íW ÖûÒ¡¶e(nªVTi•_ÿj%j^9�¸&.^Cºà 582–ISù†ÒÄ•.óI»pÅ´ˆª Ó !pì›M ©Fïød7¹M�!�Ø.¢˜w+6�üüçˆä„j!Ð’•ÒäPÊSÎe@úXǺӠÄ2ƒµ¼åÊtY†[s3Å #2çÒf¬Bs4mÊféeçÍ7ˆs æ ;ßÏ\Ô3Lô¨§?"‚ž¡ihS"z"Š6£süèIJZ”¶¤¥‰¬�̺Èü=²ZK­J&»ÕÉøZ5«µèjKÆZÖ³®õÿ­q]ƒ¬×QüµîdTæ–{Gi^ËšßØæš,»ÙÏŽ@´ï<íj¿äÚ Ê¶Ÿ�“Aï¤Ð€<ôzÇ­�E˨Ñ:N÷¤ESéiÙäÝð–÷Y jSÞ»­1¨h¥ú-Ý,ü‡µ¼ nðÇp+^–ÁÂAÓp� â�¸p^z˳X< _‚ÆãÌq�Oû!ÈÈû\ò“ !å\XyZ.ÕDüÜ2?·?±Du³ûîÆ4¼¹Ðs##Bçí¾�~ôµ°JéL€Ó± õ¨çzê»þr¼|ýʧE¦P×#òu°‹�ìf÷Ú£­v¶kÀí£)¹â>÷ºß}ªC ·ÃÓÿ2stÏ0ð7owÎøÃ#žÞŠg<€Ÿ/ÈGH“gºåŒyÇH�Yœ¯ºçú½‹>—¤‹é!‚ú[ª>Ùn~óÆ Bç׃<¼€i;yI÷m£¼Û*ÿ6ËÃírÞÓ;ßs àó;HC�áSœ»¡ãˆä›5Ÿ:Jj>Šz>‰>é;ê8ëS0-c AÌ Ì«k¦—£ê©žõX�eZ&�yA\&;Á!h¼½è—~! �Ù%è À #qÒ“—ZA)i4G:%IcŽS‰ËÉ¢ÝØ§M+5,tÏ‘ˆï!¤ÝÐAY�Ã�7Æxw9¥ä¨½¶»ÿX6ÐjÁ©x:¬Cþù–Á> A Axé�•¢ˆì $T9t‚ŒÁ”ÁhDGtˆDIl+À°É!˜˜— B×B3'™9B$ܧ (Å2`B9pBŽ(T’)¦*–SÚÂ-éBˆøB5Ú •)"Ç@ÃEQÃÍ`ÉrC8|ªCÔÃãÃ>üC ÄAt�B<ÄDÄ’EdDGlDH”ÄH¤Ä¶°ÄÓÀÄ—ÐÄhâDi "„£PŒ¦B$ESÜÊ¢°Á¼“°K²L³<+�t€´\ËI<ÉnLÉo\I˜˜K+"ÇK�IPüJ1ÙËGºI¿ŒÇU„ÂÀtÅÿÁ„Å”ES¢E+°ÅÀÅÐEÆaJÇ|ÌÈ|�ÉŒ�ÊT£ËÄ̈¼ ¥9ÍÖaR# ™„È/±DôLϲ\–³ÌÂÔ$É’D5”Ä@Ê’Í“©ËYºË,ÈË,2!þ£?PÞì ÏÐIàIŸN*Ø45LS²ÂZìÇ[TŠ:[ÌçäEÈ`™é¬Î èP­µìÔN’z�îÉï‰ð$ƒñü”òÜ ±l‚ôTOÒdOÓDK‘TM“$:œ˜Ïè«Oû“º| ýäO%ñOºãKS¤�MEßLš9 ÁtÂtPJ‚Ðä”Ðå¤ÐÛ°Ð¥ÄÐÇ`™S1]Ã’ÛL ðÐŲQÿ#"ѤñÎÿq�‰(‰•‘å‚�Qô\O4iO,|Oæ(I�Ï֤ϠúQ íDÛ”I8“þÔ•#Ý;$ÐÎ0P ÎzTP ,Î||PUÎ/©Ð\ ÈdÈbZ1Ó`,ÓÍDÓÑYcÓí€Í ‰­Ó´¸Ó<ÕS>}? É…O¶Ô7!àQÈóQû¤Í}±Ë˜Ä˯|Të‰TGPXÒ¿Î'm€(�Rã¬ÒOÅÒPÝÒQUÊ�N ÓT]û35SWÝXí4Yå+7ý8- šSñœò<óÔH=E€_½Š`EÍa Ôø4Vd=:e•MfõÄÛlT¦�Vÿo“Ô$¥Ô°ÔßœGLýÉF ÊS²RPÕRàÒsõÒ^DÕum×wmUW�×…ª×åÎ75Ñ8O~UQeQ€uÑóôÕíÓuÏ„ A%T·ÄÀ xعŒØE…VŠÅ‹ýÏj�Ôk­T&ÝÉŽíÉ�ÕÔ�åT¡ôT+,Ù-Õæ$U2lÌteÙTuÙ—Áx•YP¢Ùüy�¿z®L‘ˆ¿ …?h�ôÀÃ=\u± @­¯7A5ð²( (Ä7¨\ϨÌÍ\™yª±©ÝÀ 0�™Ê«Æb™�'©›Î½–¼êDÎ�1„�ôˆ¶=”‚»ÝÝ3¼Š¼ýÃÿ¾ýÛ�\§È"ÂåŽÃEÜtQÜdÜ£ý18�Ü{²ÉEÂÊ}ƒËÍ\ÌÝ\²X]5;ˆÏÅ ÑÍ%ÒÅ)Ó�Ô…Õ�›i]SyÝ‰Ý ˜ÝÚµ]Þ½ßYýݽ Þ8Ü’[%Á=Þ¨H^ÃMÜÊX\,i\è}\c�ܳ^Ëí íÝ^îõÞŠß‚ÝñÕ¢òͦó…“ôÍŽõ½€ö )×íʉ€Ýî•]1¬_ÓÁ_¾[ßE&FéÌÎà_ÿÍ6.^%`ž ` 0à@`ùPàØšéõ¢;¢ÜN� ®î� ¶”ð5ž 6Þ�*] qˆ>­)®÷µ øù¥_î°Ý¦Œaÿ56¼¥a½µa¾ ¿íßáý_U àÁ@^b"Þ #–™$Î3êebì•à Žâ/Fˆ*~K#¡œ Váâ@‚¶. ø©1Žˆ2ná3¶ß5þ侚áÐŒý•cáåâe,v=N^>nÞ~Þ#ŽÞž^É%äìÕ^Df_Ã`Ð`ãó›Ó€ä-nˆI¦dºIäÞÀd–bÖAVYP®æÈhWR~�&â_Šø³¶’)G*Ü^Þ¡5È´tDÐh+›äÔ0Òë½Þ´|âÏd 1­2’-GÞѶ�)‡�•ê )¨}ñåÝ ?$`Иg˜ªÃ&k~èk†°lÞfÿSŽƒnö³oÎ¥pne!Ö>s>çHç‰ZgjS w~ç7ˆçCÆMzî {&#|®‰Üç\êç¸øçè £Ÿ2h„¶È©½¢–h誀h£v l®aŠæ€9¾hÈh-ÚègÜ-ç«È �é£Pçš`g¿8éwVi]fi<¨ç§ºg “éa¦i-²i:ÀéåÑiž'Ÿ’„&ëµ j8j¾€¤~ã¥nê‰ðæ‰çFç &g a¬i‘f%’^;“†T”Ni‘”g²6kxBkûRë½ ~nn&€–ëe¦kòûiz“4Óë¾>ê¿îˆÀö[§†ê,’ê¦êu±jhìÿs~ìUŠìÕkx¾ì•ê–v�—6ƒ˜†’µ†‰ÐfˆÑŽ¢Ò¶–�>í6ªëã¸kä^h×~mˆŽmÎpnlŒ.l�>lŽVl�¾jÌÈjàV%ážìi­l±ÖÜÌv鳆é´vîÏfë,rk¸®Óv�žNm»jÖ6¶¡†7‡ok¶ŒQªUGôŒÝ zÊäÖ,b‘¨ØÔ5°µÓX(q+�šyy’]ªŸÆÚ´ˆñ¨Æt�±™Ê]ÛV1Ú(#Ð r+õ¸þ€¼f«ìÓTq1@7ܧ„:\€ðO–pQ¢ðF´ðy¢ Ÿ ·NW¿Xñ£!q/qÿ‡P%gñ/ªM[Ÿq"ÿGiGo-RA$ r!‡P"wŠè;r”Nrgr°srO‚r)_c*O+?,Ÿ±Ð� Ï7(ípÚóM#s£1ó3Os+\siq!zó8Ÿs:oˆ¿–Ç '>_A?ò!�¶"?:BgC�D¿%EoFoô~ôHŸt-·t.Çô/'€0ÿÏ1ÏP?q,i"1ø1x�ssî€q?¥tˆ'‰K ÈsVÂȃ(ÄZ×�[·³\ï·]¿Þ^§—_ß�`vbÇ_c¿Y„•ôθpeƒ.Ït0ßthïti×Ó3Gójw”k§ˆl‡‘ÿm?õn‡óo7¥poˆq‡Í—0÷UBw P÷Zo÷:{÷U‹÷Ê�÷y©÷³¸wÃ�ò|×÷ʘp~¯ðÏò‰Ør�gv-zöH�vÔ™v†—kÇvm�6n� o�ñSªƒ‰X&q‡r÷xUy‘÷s’Ç A7ò8Cr�Tr–o—ǘ�yÞÝw|VO€W€K?5/ïyƒÿy„·�Qz ¡§…sxlש‰×€rQz‹gzSªt¨×x©çø�¸Þ·i+«GBÀˆ\¿ 0“¯”ƒÓL˰ß' .{³·[´ÿÓ+¿yJ×ù�ovŸqO— šW��í'šë¼yø‰¿GzŠü8?%ÿÃ_u†Øx: ÆwÇ�¦Y¯žÈ·åÉ®´h«f›è�þÌIT�ýH’·Îÿü³Ÿù*¯ùÑg{œ¯t·_v¸'xgŸ{Õ/”ÖWš×·þ½Ÿ}¿};KzžXúwŒúì ÷á01Äcð …„ •0l¨á!Ä'š¨h±ÆŒp$H°È�3F’t`ò䉔*#°lIâ%Ì2gb¨i€œ:wòìéó'РB‡-j´g€¤ –~iŠ2eЍZ¦©ªàª˜¬[¶nØ �°`Ààb– •´kÖ.(º4AÓ¸_ìЭ fÕ¼C¢òM‘õ¯:‚—†`ø0Ä�gÏÿ®áxŠÈ’¥P®\à2fš—hÄâ›Ð`F{x¡Â„ ~Ö0‘¢ÅŠ�5rdP:†ŽÜºI–Øš„^ˆa†~å¡ †8¢ %šØQi)æ¶"‹-&ðâ 2ÎH\�܈�r=J:)¥AI÷¦h*£d|QÆ�ˆ:©\&€‹9árÒI'¬±j:k¾™$K˜aF¯½êz¯z`€p¦6YTسU8{& *U&*\.h�Ù ‘ZBã…Õ¸áâAÚòÉçld© ƒíº›e‚@È;ïõÚ«¬´f@¿ýºšT¥ <0P—fºiŒ�Fõ)wÔ’:�± f€«¶ú/¾°ê›Á{<î¯ôêë¯Áæ5l±[�Ê$ Ê.ÆÿlÎV­´”QkífØjË­Þ®¸¸–›í¹#¦».»î¶ /}8ý4ÁQK=uŽÿ0+§‘y*¨—ªò±a¥z–Å6ý@ÆlìñǸ†<2¯o“!,±-EŒlËË6ûì™5Kqó`×â¡í¶Üú 4¸ã-Dѱ½®ÒKÛ—àÓPS}9æ™û¦W#,ƒÂ)0|•׃-±Ø«ÊªÙg¼6Ûc€\2ÜrÓ�ò+‡•¬Þ1ó] ß€ï'8á<ޏâ™Û8‰!�´ÒYž]¹Óš[½ÔVc�°Ö sÝð¨_ç6c›UvMg§ ;Û³ë 7¶Ÿ\7Kw³ìòY0ËLÿsJÓŠŠ³ft–-ãy q=H^ ´•!< «3ÏkTÚ¦G=ìQ°‚’ÒÞçB7ºP…ÏtãC]ùTG6Ö¥Ïuøb_Û„#·‘ɯ*(³Ûéð†?³èïw’ Þÿ—³ÁíÌpDžÐ”—­6ÐyHƒ`Æ$X9 2±‰ÍÁ`²†‚­u­ƒö a Ä„> œmc¶r@ìdç6Ú±�v·ƒáeØ;™I �7ìŸÍrH‚�‡Lˆ òx¼H�ÉP3òÀEð_Ô‹”©HŸ@QŠTvEóqa‹]Ô×Ãè¾]ÕÎŒóÃ�îÈ3C.Ô° m”ÀOà¿j †Ž„`á,�Gì±ÿ�Aôȇ¥Kˆ —¾´—½�ˆ/%Zn‘Æ4f#¹7EïU1’âÓ%-ù//ÚJ“c|_'±yÆúÅð~ktÖ)S¹Jý¸r °TÈ,k?š&C»–/ Ì3VĬÞ1ó™Èd‚®{¢û鬨M,j‘„\œ&&«»Y¡¡…_ ‡ðBn¦Ñ›/Û›)ݲrŽ©cñð˜G&�´¤á‚–dn“ËwƳ—ó¤'!“hÈ ê³¦ä§ÊAgzš"<ŸA;×9jú&Œ uhC½;5Àd.¤_®(Êof•…ãßäXÎsŠÔ%5)¸P•º“¥-}i=auODÚ´­™ÿé?7XºIþ´’Aªçh•É…Ò©IõS�*Q¨J•wõ]UÅÇŽnÕŽ±œåWIzR±’õ4ïäåYç™V¬Õ­žÕ‘½X Ú¡¨ ´f8-´²‡ÕVZnjPd™�žôÈǯVxnsû°‡e¡·¾¥µ"V›Œp p€C’…Ý’J©³œ¥˜‚ ÝéÞ¡ºÖ}í.Ë&ìÆö<ç9%x먹¡¼æ=ÛgÓkÌЊ–P„*­ Nk†$з¾ö¥ïjãÐÚ3}g+—�íZjëWž=7�¾ý-p9 \Ž75ÆE®r¡Õ… S¸ ¾ð¼æE(ë^÷µãíg�>Œ×lN:á•@ÿÚJ 0õ²¸‰ìe�{W_ùÞ·ÆIÈï~ Ôß-üÀF*� |àÞ&XÁ§.FŠ{\åFAžð…1œa l˜ÃwÀ%b¼ª8'N1OÐÛâ1SðÅ1æÍŒOkãûâ˜2ÐÚq�gûc‡ù¹CÎB‘Ì€+äÁLvò“£lá)SyEV¾²‡Ç«åñޏË=óNÄLæIgÎÌgIšç»æú¶Y oîoœiKÛÖy–wÎó‘œd/9Âgz2”Mè*sËŠ>Ó–…êhž@Z'’¦4°¥féKgzÓœf­›ù êwx snh©ó¸."'XÏ|NˆŸ]] XwAÐe˜µ¡­ÿlkE-ZQ�ó¿�±]»Ýö™‹mì#ÛÓÊþN¨Lœð»ßÑvÁ´³0®ˆÍFÉN. +,ë)ÓºÃnÊ2®Íet»JÝør7Æ­ïËÛØ�fœßi[ùôÛßÜ*0ÀÕÕÛ�Ÿ®à¬>x“_ koƒ›7‡.·%“ëα['½Î8У¶q÷v|Ó_PÈw9ò}—üÿ¾3Ë?èò>·á2ôÂ3Üðêâ\™:—¸®).‹Ç*èfz½D ãKÏ èk>úf’®KÛ*µéN?¹�‡õÃLÛU�ù¶gžu ¯Hfû‹8¹/£sG:ݼ^÷Ù#_©¡¿×´jž7Ü5#÷ÿaÑÝKvºÞqEðÎüÏWWx”kNÃÛ021Øy.öïäç’¿}Ž(/cËkÚãõù²•î׺7ôÞ»aún�l[=ðXO=à Ïú®ƒøëæžxã+þø‹ã¾û9j|áK¨U‘ß ÏƒP}}k„õ³ŸMx?üÇew…$$‡†?üÙ´@<ñ, þ=·É àK½Ô%Ñ ´¸Çüš÷5 öRø•ÛÍÀùµFúõûµß‚àßûÉ_ÓÑ_ýµÀýq þeÿq‹ÿ¥š Ž¤�2 Î æ@`FߊTàg\`dàú¹z`É�`ý� þ•àiœ`j¤à >ÿY ÒÀ fL : VáåØ`øá oè Dð âŸöÚŸ•q  áA(¡B0á­¡@ÆÈBaŽØžÞ¡õ`!|i!IpáCx¡†aüáŠÝ=OŠà’ à$¡‡ôßÿ½aÊÀF!÷á¡%æ!õD  ðáHø¡b bbÓbaþ-â6" >bâÁ! Ê¡ Ö!ä]¢-^á!9Íj¡¤‡º°Æ'Þ×,iàf áò›)¡•q›¡ðÌëI·Íá$Òb%Þ"6L.êbiqâ ø"Yc� ãn òÌ!&cH$Ü„5#Š·EcdL#5Ò!tØÿa6æc�l#ì"á­8€8 c£f !:† :‚;v�;£ É#,>Y=Úãsà£>f$tð£?Ê‹{ä@Ú9‚á‚Î¥F:" ¬$K6$´LÆ$DF™DžXERbÙi¤NîGJ Û�ä‡ü!AºûÕFm˜d,)DJ® K¶äéMØKÆ$LÎä…Õdxݤ5æäNn¥sô¤ L Pæ‰PŠdA®ŸQrR&dý=OS®¤Kž‰TNåŠÄãJ†MÖ#N W4 ¡Zù­Š'Ö˜tóT„ÏøŒ4rT"ž=Ñ^OJœØÆ`$_^&ùåŠf`æ}¦F ÿ€hŽ&Ÿ$¦·,&c–Ûc€Qœ� b&l:‘fòg–ŸgÚhfÄh’战æx &·©¦ZA¦P¸&Æ&rS£¡Ýf}å&Fì¦h–¦o†pšprqZŠqŽ]r~ç"-'sf˜sÒtV€tuþ¦X1fcž ¬fkvçv‚§}b�xާ¼”gœgz®§XˆÕD§c'kF}è}.(~Öˆ~ÎËóÌR~fgügožæS¦æ™XæO$¨‚2(ˆbN~êg³IèCðŒJ'ŸìXCr›dr(#%hˆÎèåŒèx–hAŠV¨ŠŽ‹f¨‹ ŒvÙkÒ¨‘NJ£¨�ÚÿŽº€ŽrKŠîæŠöW‹ÂÚ‹Öâ|Òç‘niÀ$©’²“˜‰jÀކ¦t*Õ�:…mÌ•^#‚j)—Æi�x©’†él�i™êæ™zIš^g°©�bé›v§œ*¥¼”&N`["va—€ è‡I¦¡N*°%*Û-j£¾Ö£ŠÕ‡Qª§¶›¥^¦fªƒl*Juꧦª»M`£`ׯ˜*´ ©ªÎªM¡4Šd¾*¬ˆ¬Òª¯“­®®Š®îjdôê¯&kRO k‹«€¦ ²*+µ> M턳¾ ¶ˆ´v«VV+¸.³òD¶.Ŷ¾…·zk¸®«"�+¶ÖH®êK›¦« ²ÿ«½^�»êD¹&À¹.½J뽬µ.¹Â+±Êk þ«› ,Ã6¬Ã>,ÄF¬ÄN,ÅV¬Å^,Æf¬Æn,Çv¬Ç~,Ȇ¬ÈŽ,É–¬Éž,ʦ¬Ê®,˶¬Ë¾,ÌÆ¬ÌÎ,ÍÖ¬ÍÞ,Îæ¬Îî,Ïö¬Ïþ,ЭÐ-Ñ­Ñ-Ò&­Ò.-Ó6­Ó>-ÔF­ÔN-ÕV­Õ^-Ö6ìZåkÖÚëÖ^k×zíLñ#[…m¸~-Áš-»¢m1©íÙŽ-?ºíÚÂí6Êíº²->ÙmµâmÙêmœž�d®•&ú-¥®¡˜—yÅ¥ h¢&¾Ⴈá¶â–—â2n:îãîå¿Æ+­xÛ¸´ßD~ý¥¼ÌDæj.½rî¬xîçF@ènæèÊDéråælç Úê²îj‰.�nìîä¿f sM@ÈÜnëÒæëv@ïúnÆœð2×ð®nñ’ļðnòfdÚ0¯}ïó~nôŽÄôÂnõZ/¬ô öö…öþÊí¶„.Iï”ÙDøfc¬�ox5ïnmïí®¯÷¶oM¼/6Æ/¿”/_œ¯®¤/Kàï šûò¯-ú/pT0fp0ï¯_";p @ðẻ…Œ ë/\0�ïÿÎoö:ï¯xð€ð°°o†%0Ð!ù,*¤üÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢E‹hÜh¥£G( CÒI’“É“¥R^Z™§¥Ë0cʄ٦¦M†rêij§¡Ÿ@= Jt”Ñ£=“*½È´©Ó§P£J�JUbÆ�‰†IräI”*Yºl9³ì›7êÜ©hP¢p…Eª´nÕ»xóêÝË·/€«Xµn…ÒÕëWN)K­¼4–¬Y™hkâ\ ®ÛŸq3[™k´®]¿ C‹Mz*`ŽC.|qXÆ�CŽ Á/y£_5h?ÎAZ¯âNÿÿBu½ÂP€Ü3! '¡Âú°pè‹¡¡4ÃãáPq:ìXºxØÃè… ˆ"ÅBø¡øÅ(a—ØÄ¾í] Þ瘢*Ö°‚WdݹèC0Š„D<“‘‡F5z�� ôÜ]HÇFž‡zgûÉ!&IˆJZr€®È¤&y˜ŠNz’jªÑ83 c…Šj¢H¥*Õ¶§¹ò•ey%#ʯ=ØÒ‘¸4$ 'IJZ²’˜Ôd&9éÉN‚r0ᙤ2aÊ9 R•©de�d)ËX¾’–ï²årÉMãìu½<Ä/�É=aSƒÅ4æ¾T“Ìe2Ӕτ¦4DMXÎD–ØD…6»ÉÿOÒ|Óxá'!‚)Lbó˜[iç2›ÏU­•õÌ‘5]™Ï}öó¢+úàÉ€¢L�° ©A?¹NdÇ�ï4VC£ùÐiF”B÷¼&Ò"gQŒÚT[õY@ÇùÑ�‚t¤ê„;OêÎ0õ¨+Å<óR˜ÊŸ3eZMoJUÓäÔ^(µdâzêS ¦¡!Q¨2�zÔÄ%š©\¢&ÖÊÖt¦B––ã"WÕºV埕Êj%·Ê=Ÿþ�é+HÄ:I²Õ¬âB«(ÔÊÖµº��l\y4W¦Ùõ²QÁ+¥ôJ¾âίEðª`¡@Ø”Š ±¤P,cûØÈBv²;ª,É0KÛ‰ÿi¸Í-–TÃÙÄ•´Xê„p‡«Ø¡þ¥ÍDmYVÛÖtºöµ.V]èZ[…HâºØ­K­ºyÛÜâv·ƒé­¸~ë×àW¸Š¤J›\Ä.…�u¬sŸ ÛOLײÕMv³«”ír³»ÞïVÄK òúÔ¼çMï ÙkJå΄¹ò-æsáPßûγAÚO²ˆD†Å¿RʰpF\¬hD(N±VÌ⻘ áÁRËd¾–¡vO�ȱv¬, âÇ@F­,hŠ"yœ‹È‚’—\$8ùÉÔÍï_ôÓ–BqØÃ?q”DLâ.ÂÄH±ŠY¼âw8ÆDšñcj,0!¿2ÿÇ�رzL$ y¢9R`’~¹+,™É3yò“µ\[.ûÄÊ0rñ‡·e*{™Ä`3ŠÉ\f3£Fj6 ›ûåfWÂYÎt†‘�Œç éÙ?|&ÄŸ•ÜdA#�д54OÌ cà(:ËŒ¦¢£-œHKZ5´¾4‡–HcðÍg²ü4�ïD$bÇÔ•‡Ú³%AgËÄÕ¯Îu¬)ƒÒ`Ûˆ€µŠdÍk¥€ùPÀ¶4p°dí÷NâØÉÖñ²_Ôl–šÑFu%©]m{ÚÕâ¾l�º­îßÜ:ÜÚ÷®Ëmn£{0Þþ »ý­icÏ'Þqž÷•ê}À{çû;Ó®d»a‚í€ÛuàîÿŒ¸ohí¾‰ÜWˆ¹Ìgó;üT/¸o&Þñc_ü•r5H°”¸‘#û•ßM%­Ào£?Y›&¿(²Â©L•÷†åq9ЏCš{ýë‡"Ê÷BëQ Bµ÷ùcdôy]\F¯ƒÜçžtÝìÛ’Nw2ÔnÓ©‚à/Ö­ õq}(_O¼ÌÃ>”±‡¤ì£F{ÏÕ¾v ·}ã0*zÚa2wºŸiÏÂûæðt[F½Ÿ~¼‹oæ–Ë‘@þYG¯xÆ Åñ ¡–¬Ì.ùðQ^6l¿üЉ¤ùÉǤór¯{Áo‘�¾ô{8= ƒ´ßë¦>å:¿zë³þúôľ†³§=ÿØÏ$vœoE÷à=Z�þ{?å¨ís~æá>zä×Aù¡½ñI®wÓó}ŠÔW}×·LV—ƒWxçñ}]'~^g{�{P€~êMì×~Át˜Ç!Åç{3aø7Ny‡{Eƒ$AfÞ…[ÜAJD†-#P…0ƒ¹õBþ´pƒÀ(e\¾áÎÁƒ#"Jç%\¨U�2Z ôJ¸„FfdþAÆâ~ .P…``!…“æ3G"0€ .}rmNÓg‚k�‚)¸‚œÑ‚Àñ‚18N3X5˜8¨ƒî„9àƒ…¡‡á!„Cè`¿‡„ž³„KXwP(*RH…Vˆ… ÿ¥…аb]øPð…aH cOf†„†ihb)¸l8nøp(02Hƒ¸eƒ£Anx¸Lzȇ]á‡Àˆç%ˆ”GˆbˆJˆˆQ8…¤`…W8 ‰’(s^È!`(†/ñoHÀ‰ä‰:¡†ÞEkªQŠ;—f¨(‡ªØ0vhJáu’PÀ!‹$A‹¿ÁÆÂœÒ~ŽX о¨ˆÀ(ŒïhŒ\ˆŒ”h‰ÌèdøŒ?q†Òxngb�ªaR§�ýRsX‡7ŽI!Ž$‚�=hŽt€Ž¾¡Ž¢ÂŽÁâŽÄèW¡(�Ÿ÷‰*‹Œ�ø‘>…�“È$üˆ‰Íø�Ш>Ò˜i$ÿy�aµn ™ Ù�¬˜+8(‘”H‘½a‘i”¢‘¡Â‘â‘*R!™‚óh’õ˜’GèW,©�.©Œ—˜‰ü�† �žx“’“:IZ< #Øö“t¸Šßx Ø’L¢”H‰‘½Á”sà”‹•YYÚ4•ÞU•sp’ö¨’Ú´•1—Œ²Œ0é�šX†?á&é$”æ凓f––;™�léjné�­˜r‰x47Ž!1„� X&„ZÍ¢—|¹~!˜‚‰[„i˜XI› •˜±…tÉ&/ –¤'™†@™Ãc™”–™g¹™œ©–žÉ!m9 —YšBA”u¹ªÉšäš‹"Jíÿ8›µiK·‰›#¹%Y˜WY…æ›'‰ù¸˜ûè•ýHÎÈ)<ÊIfÌé!h©“¶!Ó)Õé�×isɕۙšCè�ÞƒZà™ŽZ3ž~Yž{pž�›í9Œ Ÿa&ŸÁY‰öù˜ø)““é(‚ãw—ùŸb 9 ‹P 1q A:��¡�½�`Ä…V­)¡f¥^âÙ‘äÙ›æyžʈ¶¤˜WÀ˜‹à˜Ä¹‰):%HÜÑ¢�W�ÎÉ™2J£0a£q© ¦œ9à£è¤ß)¤‰C¤j¤Фª¤é©ë©›Mú¡Oú›"Ê ÂY¢Ujœûi+A"iòIf¢¤‡‡ÿÒL!ð¨�ª^»á¢YóA`:¡¡¡¨]¹6€!‘$(Õ2Š…Z&pª¨zlÂX…±Ðª®úª­ª@‘0«´ Zea…™ª)¶£þ�y™údÕR½²!«w”…dãU0‡®G‚�r¨’v™‹ª”�jJ�©ƒ4©Q©�u©™º©œê]žê¬S¶¯ªþ1ª£X¨Ú®îªª« «ò ²J«³j«3�«`¨«(Æ«ßá«`¬²!¬ˆÆ!ź‡Çúc¾¥¬ÌÊ}ä'Ð*fÒª5Œz&Žz­! ©ºA©¡b©Êú­9®âÚ_Ÿª¥—¡LèúêÚ/ìê®. ¯Â8¯°Z¯öН2ÿ¡¯€À¯Šà¯»°€ °�A°¥reµ†°]�¬ư3ج±”�¨—ùœÐéÕj,›±Ùº±ÛÚ±Ýú±`®"»㊀  ¢êN-³D.û²—¯2ëª $J68«³<«> ´f!´–hgf¬G«°É*˺´Û´’ò´’£k$Í´D[;K¸ "©™´öb„V¶Pp¶Ë”¶(´¶ïÚ¶1û¶­J5rëW·Z…¹ª°«³×«ò÷«N¬EÀ›û·FKH{© Kxÿ×hk�¨ŒK­kJ�›µ’»µ”Ûµ–ûµ!K•^º»Ö¹&ë(k¶éж£¶¤ÿ›ª¦k…¨›ºû²º>Õº˜º¯°+»Vp´K¢S°·;°¹{Ö[‘�+ K¸Á+} W¼‹û¥iU+*Kd…ñ£­VÀ­pÀ�·š©™š¹Íi½dp(¹5~‡*+›à¾&³ä[¾ª«5™RꛩS$î ¿ÿZ»ô‹1™•êq.æH Áù:‡ÿÛ}Ϫ¸bv¼äø* \… ¬µ ̵lq,Á€@ÁjÁ|&,Œ$ݺß;º Âã˪°Š~%,3' R) †+¬Á-¿^ù³N6üYÃwà ˿ô÷nfQ¸<ܬ·±)&Ä�IµÉk,GLIܼKÿü¼M¬ÇO,ÁRü¢TŒÁ¸¥ÁÙ ì½ýòÁá+Âbüªd|¾& †(œ¯®«Æ·t±Û¯³ûÂòk»2 ™s¥ $§�&ƒe¬«­d­ÞÌmI¾�³}l™â´k¡Û.½ýÞÀÝ~½c…-…Æ=Û‹­5í]IÎ�¨,&ÙãäÌÔýJ „ÙØýÚÍÝ1çÝÆÞ2>ãmÉæú¨]‘é�ë�á“Pà„ðÞ)ßó1߉»ª×a þK-Ø~Ùß>ð߇]¿‚-Œ.3&~à^ã–Äà«ZÝRÄsп­†óBá.ü¢ ½¤mz¦Ýá†ðáè-*¬½§gâ-3Û*^,þr܆}?ݰ-04•6ŽãŽÜB5ËÝÞ@NsB^ID.ŒFnH®äÎØä&ÆbÝíQÅ6 ÿŽÅå�(ç�°!>â1>^.Û`~˜bž'ô­/Nw~âj!³iã‹`SÜ:N·pÞ*¡Dà^ç3×éyn…{^}>¸KèX!èNèß-åá�èTNÞVŽåŽ®åêÍå®]à_^é�.cbeN€¼× ˆBkî‘ðÇ +V0bzÜàª=^0&ž8­"JAŽæ¿Äì²þJTSµÆ]‘f^gá¢rlÚ”èåª@ñ!á¡Ú¢æ]^à‡Ììò-#ˆ›"D±éÍ$PˆDœî˜íÛN0Ý>±@5{#3 ïäÎ*ænçènIê^…²Ôî…üî3ï&6ï¼n,ö~ïÑWåúîáÿÒït`,ÿ^]Õ“ò`¯³Z3rð(’ðfîb _ítíßv¢4ñŸlñ1£5ßßÿê_I9_Õ<ïó‘ôïÃPBôÒþbš½�)ê~ Mšaíª2&0qÿ÷cQõW/sX"P‘?ù’_ù"*Æ Ò‘³ 1‡%Ý>a.ÿòŠû.ú¿áï¡ÿróá}ú_…MXdtO æþA�÷ºôúàûEßa}ŸÇäðó�ûL¯û®Æû­zøý—œTÐ`„ I-ìÑ�ÏCˆW$N\TÑ¢Aƒ4n䨑ÈG� EöSÒä”HT`Ù2ËK˜ˆdδRÓæDŠ+ªä‰¤eK8A…î!Z4¤H7,ejÈ©ÉQ¥Ò¡ƒeG?µ(8� F°±š"[6ÒY´”Ô®ÕÓ6ÀÛ¤qåÎ¥[×î]¤oõÔׯM›P&,XÐaÄ I%4ÑØ1#È‘M¦üÈòå"™5;~ ÙÇçÁóÜŠ1bQ©Uoeݺ¥æÏ> ̦-Õjÿ'Ü< ¶äÜ­SC'Jµm¥â„¥5’`¾÷­è&iÓÖYæFåëµ;sfðP‰ç€‘2åÞ&"¯gßþüäTñ凡_íZ¦xõïç¿ß9_¿ú¬¦Â „â´Ã�C(=÷Þ» 3Í2cÐ3Ðí0Ò´2 AÕVsíß`ûlºÙŠ›·Nt+ˆ·Þ~sJ8‰ÆËÁ¸ãJNÃåšs:/¤#±ºE®Ó(»íàªë?ðª�¸òzÏ‘ Û“R²÷䛯>úîS+¿þºô’¿ÿp@ CPóˆ’Êó´,B {‹,¶Ð*m%9:³ÃÔ@ôse#ÑDUœ„EÎ\ ÿ®¢áÆ£qŽ4³cŽ„ÿxôq: …Ì*Ï"�:Ò¹$—”ªI>ž\sÊϳ2>,³Ô’Ë/c•5®0ÅЊ2 ;3ÍSyr¤†à,"J:-´C<Úð4>EùÄ@I,€ÐÜTÚ�¥ô…ñ �4ÏI+�®$i3} ;NãîÓ½B-IFRM•Õ)Ÿ\5•VÃøÖYûõ²ÖoÍu°]m\pÞõ~VXb+„âBA2T¶£=ù|öÃh�ê¶j‘¸v€lÏnÛniüvbÂÝq\1Ê­NS"Õ5’.$Ã{WÆñ6Ñyç^é…ìÉÿ‚vŽ_‹Öà¿Èø@yE˜MÊ€í�a„‹}ÿøØˆ“miYÔ,¾¸µŒ§£6EkWĶE‘_d4FGM68IuÜËRr|ùÜ!Ód]šAµY œsÞYçž}Zhĉ6zñ¾Päq1ÉÕ&@*·üÌ„{²|¥¦š³Øb²'­YÚH±3¿~6ì“h$Ý'­Ò8œØÎáÜ­JóÆ6šTå€3éR“,ÒÝŸÎ<Úï$«œ¸Á ßÜgȰþzÄg|{¼ôz\�ˤÜòÊÃÊü`μ“©ó…áÌ7ôÏF'=;ÅÂRýOÖKzôõ­üðÿÿÙ9¥vÜŠ î¡»·ñÎw¿£Ô[„7¼–ͦxÖÁG¶¢¼î1/IÏ“Jô6Qÿ¸õ0…)×Ã^ö‚Æ=6î{á3ÐøÈg¾ó¥G}ˆ`ßH„õ>øÉ¯'ô[ˆýî­ÌĆ6­3ÿ´ò?p€R1 s¾­åèwzyàð†XãUy-Áà]jÖ<FŃ ŒŒ—BBë™ð„)dc^Þ²B¥µ°&ä+XΧ¦Þ̰†"!C§C‰E‘õ‹Ÿ4qHD¶g+ùÃþæwD$ú!€†XbsW£'fN� l`ðžÁ+Š!‹YÀÊ´¼v5¯ `e+eäÁ{µ‡³¤¥7€F¨ñ?mdâà˜ÉÍ‘Ž0Ìœ–(¡ÇVI­�­‚ŸYºÞi„�Ù ZЂÈDÿ²g‘A‘õçºGþ$’’Tbí˜xIH%!›d ?iEoŠ’‚¤Ä ÅN™ÁT6¯•®Üàî• €”–µ4#.ué^.Η�ca�\h9b&ĘÈÄ’2›äGÑULj(›æÇZbͳ`ó�ŠÔ #¹CH"q’•¼:w·NÓIxU$çYO{ž•zQå*÷i€WFïŸè@giKƒ”o í.yÄ£‰„Ò$¥ jUO†-aY%)¸üCW½:ÃëÑ´nÞ|T)µâß´ggd`ë(ͺµfRE'– dL9bË_Jd:ƒ±‰UÚ¢‡­p&3�úžE‚i«åC Ù%>÷¨XDVÿ²?5À£pÉTÌúË©OõBTã9ÕªRõª Ë*Jú󟰾óRø¦qÞÚ´¶D­:c+ÜÚ Å•s­\]£yW3æõ {L_Qò×À:f°4*lE›Ø ,–�Ý.)û¨Ìf×h›}ªgY ÁЊöm±+íNëœÔ‚$+�^˒زd¶›¨ím-¨,Ýò¾Å ^Z½Ò†¯5ñk[’ۘ姹‹x.JëÆ"”{Öý)vµ{aYqªþîðÂ[ŠÑš ¼çÝKz×;�ÖZ彚o}oŠ[üÂO®¡+4ûÜÿZ�Ã0b�kàØ)·„}œaÅG`GÂÓÿ•puѨF GÙK¸4 ½»Þ‡xÄ`B¯õÄÊÞï–Æ_kæZÛúâûÂUÆ»¥qomÜÿ‚ÀÃpq‘<äÁCfn‘�{dÏáÁ­‰ð^P˜ÔìIYÑû¡r•qeð†WËpÒ*—KìeÕŽ5Ì?ÖÊýTfÚž9HZÌ›šC7ãŠÔv(«jœoBçÙô¸À€Õ³ˆù¬`?3ÐÐ…ƒt©Ë8DkoÑîKz}i™„˶ª:áö[Aq;}‹‰AyÅY{º5”ifm]Ù“>‚²ê£9Oš�õ’ Ð ­øÊ�\€Åa $ŒG‰À­  Z"•ÙÀBÊ“ØX¯8Aߺ£f’xy±|©gc� ¨Á[Yºõ‚Å8<�°%ËK@ 4šü2,‰‹À Œ� ¼À¥ÈÀÁAjê»ÉøÀ& A‰À�(A:ÁHÁóYA�aÄ ´t�¼€¼¸|ˆÿÌÄ¡ B:”•!Ì4À‰Š¬*$„%¼,£Á@G³Bãà@­ðÀYÁ€B�²+-.ôÂÌC±ˆxÁt64´ÁÁAÒÁ…àAðÁ&«CSŒ•;t¸á)B18Âü‰$L…% Ä&ÄE¼ÂWt DäEÔ@\ŒB”yD“ˆDhRAøaAKÃN(Ã3l�4\CokC>xC”‰C¦˜ÃSÌÆî™¤ÔC# ¯>t Ä¢Ä*+�¥3DXœÂD¬ÂÂHÇ\tÄÏ0A,Æ/<Æ0edFMtFN OP$Q$E|ÓF„<n„ VtE`l‰XœÅr¬Ås|Ç‹SGÿˆdG^tG€LJ”G Ç.´ÇIÄÇJC>ÀD3ìGüG›H“È‚4#lLH›Ì IÈI�\¯%ù°2,Ã�ÈÈó@¢,J Üžÿ@Ç‹#¦lJ¤{�¢„¥ô¶¦tJ8Ô7y.äBXèJ¯ˆ„hdDI•,CL8˃۶÷€É’ ¯üJ�؈S˜Kº ¨²»I¼ �ÔÉ•ñøI J–x’¢4Jîù�JHLÅ\ºªdJÀ´„„J¢„Å\Ì¥lÌÇÄŠ¬ÜÊ|Ë®K„h�¬lÁ”$CÀãÊ­ájjãÖáöá:æ„;®­6Ôc(àc †[y=ÝÔõÞ(&d56d áó©aäFZËØâJaõ™d5ªdKBLÞßã[áü(O~ãP>àQ.e¶:eÞcÆ^%þã ÞË v]Yžâ¾Ed‘,¾G.Ì_öâ`æì!æb®¾c¶M¦áÿíä±m^nœ9Žæ&aK1Ý#vÛUÎ^mvbn†â,� )ßp¶åD&r^ä¯9çÿÔ� `övnçú}gSÌI™Š¨-IcKÈS*ÖÞ-¾F¡™ã…ž©uV©á U¶a?žËdUiùTÌ—�èéPøéWx…�t„G(OŠ]:É’,©{¦Í-®Ö”Ý7=HŽÖF�ÎßEY‘’6éCNé¥@– õzéF�éç™i­¨å›ë·ÐI�® 2àiŸj¡nD¢6êgEꤎ…¥)ödâ¬É6"ìªNÀ«Ž\‹ØjâèêÔ”Ó .Jœþ�±f@2kª@ëÀQk‚¶idÅi¸NÌ�&Žž�Ÿ… ê¢.Ì£¾¸¾öëèaêÀÞbÃN¡Ú>ì´Kl�Öj¶iÿÿÏÇöà›ë kni“Àl:ÐlœáìlölO휌k+˜kÒ®kÔ¾ëx•ÀÕ–l3âë¤þkk l™ƒc¦ºmܦ9ÝVÞ¶îÆþí’l¢œlç˜ãnäß—fnqîš>…¶.î·žnÑ–kº6m»Víò´%ðVêèé© œ>óNo ×�õÎjÆ– ǦeúFûÞ üfÈñPnþÿnå%p½íJm©(íÓNm¼îîúþn×îk‚ð/!ª®pÇ‹ _ìÞŽŠ¦ÜpÈì$¡lQ®ãüNf’†Á'ŽgëÏvëœ.ðê>ð×nVæî·qo{íW¥çñ÷üqÿ4OŠ é!o<åp$%‡f&qþÛ2Œr©˜òÓUñ—êv切ñŸñ/—á]/sôNóô^óööí7?ò¢Lòû^r nòÆs(™¾fP¥i§K?¿ò7ðëFðìVðÂ4H½�ÞEßñFwôÆô � #n”&JKqL8MŸgN·aùt$vQ§òè¶rwñAÇnßî¼nušLô´�õŸuZçh[os ‡o¯¦àJ—óK§óL·s'‡o–ª•rPGöµîó*pSwö ôU7tjGô½€u2/ó\*Åmwônt\wùþj^'w_7w`G÷Mrÿb‡“vßówOvy_vzovTqhçòC¤q¯ö~Wôgt�x ÿ�­mòh’ÔðŠ;*Vù àˆÚQ奓:„-ˆÉð§øx`B ÕǼ#Í ¥6Xz»p'CXº©¿Ý ìŒÕv•¿zðÛ‹–·R‰yíLš�›w œ×ù‹ãy:*ÓuúT z£L¤Ï ¥gzv¨/ ©/ªŸV¬ï{Ìbyýuù®™?Ÿ°O…±7„²¯ã��žWûŒd{·ß`Œû"˜û6hzrŠ»'Œ¼ß{¢ò{Ñ/lçØú®|¯ØŠÃO|œŸÊ[Ï�ǯѵßù˜|Y†ÁmºüYZúÿ̯{ο¸¨—úÀ¶úÑ/þ…[ÀW;}˜'üef‰ÕÿàX(Xº‚I_)”|k.zVm>–HúݧûƱ{à/ŒžB@ã?qzÓ×Çòðú5þ‰ç'‚è_êo‰ÎPìOe¦¤UîˆEr(Øæ €„ 0lhè!™ˆ¡P¬Xå"Ɔ7*ìèñ#È�"G’,iò$Ê”*W²lér¥Ã‡2­ÐÌaó&Ÿœ‹vŠuéç¥B‡(j”Ò¤—2•(QÔ¨¤¦Rjõª#G›¶nb …ذHÆ’½*�`A‘5:�ècƵ_Ò­k÷.Þ¼z÷’Œ)ÓM+7qêäé¨Y£G“ÿ"õêµ-™¨R©N5k6+×®LÊ%;ÖìÀ"9¨•@êÔoáV1­‘/ìØ²gÓ®ríÌšƒsää³sQO A¯*.ʸ±ã¥�%C¥\Ù²UÌ\½rëùóÕУK®M­š)ëÖ®Ú.oþ<úô 7æ¼»÷ïàˆ‰?N$ùÒÀ�™ rN ztZM·Yu×!Z¤õµ‘w ¦Þxä©7!…Zˆn¶o…wØO‰Õw~éGþ8”t[QWàuŠ–Ö‚9è „^¸#�=ª—!`º Ÿa‰¨˜}%Rt¢):·¢P-j¶Tu„(ãv56tcƒ9Žç#˜aŠÿÛi¨yq&~�…U›PÀ&œ…ôÖ[•¥Øy§“è¹'#}ú™ ŽÌ™“…Ê¡‰* £�Rò(¤u­5&¥•Z:[™œéEš4­Ù&”q²9(uÞi§ŠWùùg Ž8hè¡»)ºh£Œ:(é\—êº+¯*eºi§V|Zˆ›¢Ê9¨©§¦jÕª}¶êjƒ°Šè¬>Ôjkƒ¸¾Ö+·Ýz›Ð¯h&§&Xp+*©Éâù¤ªÍ>ûª´ÔÎzm$·~{/¾ù¦.§ãzZ.¨+›nu§Úéf³Œ ²0ÃðÂ*¯¢\z§/Å[ ¿Á{nœsfp)7ËpÃÑÆ+kµ§v1Ë-÷šÿijÈŒ_•€8ð ˜è¼óž{м*É ;ë`ᩌšËI+-&̨ÉüÍÕÙì¦P=ë¹3ÏVÿìgЈ8¸Öa‹môÑK›}v…M ðtÔœMMµÕ“`­sÜ[÷Ùõ׉=6kG €6à�Û¦6ÛÉÕœÕU[=7&uC™0Þ ‚½÷d«,8æ™ëEøÌ†K�xâq3îøŠs˜~zäÞM¾·åkþ:ì-qµçnƒ÷âs“àé¨�·F”WÞwÙ±¼–�NóÍ{•T£ ›0=õnROý³™mµ2òÝ{ïcCË7ÏüóHEßìõÓ[Ÿ~öÚsÿ=üñ§¾éã“ÏôŒJŸÿþú×·ŸÙûä'À’‰!â_ùˆp¾U¥ÏýÃ^«´·‰°‚¤ ýæ`?:$p�~jà§÷¬î í‚&<¡¯ X?ûuPèã”8B•…6¼!HÖ²Á&e× ¡ f¸-±ˆ‹‘Òƒ%2„1LßA¢Ø†I±Š6ŒP’H&6†+j BE+’Ñ‚Xìš}¸¸D º)n|c§˜«2ÒQ~g ZÕ(ÁSð±�~äãáÆ1Ö±�Þ»#ÉòÈÅ=þ±‘�tc iÈIph…Š&3†MrRZÍhìEÉQÑ’Ȥ&9¹IOJ’”®Ä¡)Q‰IU®RÿZ­|%.‰HB•a1—¾4â.%ÖË_óŠ4ä¥ŽŠ©Ì “KÃ\&4ØÌ=3šÖ<ä1…™ÌkróxÓžkº)ÎØ}SrÛ':WNÕ�3�î|'<ã)ÏyÒ³žö¼'>ó©Ï}ò³Ÿþü'@*Ð�´ =(BªÐ…2´¡}(D#*щR´¢½(F3ªÑ�r´£ý(HC*Ò‘’´¤&=)JSªÒ•²´¥.})Lc*Ó™Ò´¦6½)NsªÓ�ò´§>­ !Ô¡U¨à”ÐOÇÔ¢2õ¨H*:—ÊT¢:ªJ�ÐT‹ZU«vSªYÄV¹zM¯f5¬b�&Y1°µ­·ÿ<+1פ¶¶u­tÃ[áêK¹žè®b°+]óª×I©=�ñ+`Ý:ÇÁº²°êë]ËV&16—Ž ’~Û¿R¶²†¼,“”… n0¦=­Ø(SªYÙ¢%Œ—b˜Ió€Í›€fšjºé”£P,zf]u8çuæ©é¦œîie]~š7ál]z)({…v(P‰Jª€š@ÿ ©«”Šd)�×qªë®Pz*Þ•u„Ê©] za`þ ì²‚ت¤°ò*qTk-­µÞŠi®¼vëm�¾Ò¬ŸÃ–jê—©ê´,³Ö9+¤«Ñ6ªµôÖ‹-¥Úfúí¾ü’nŸänIa ‚¦›ÓºÊ6[ܳ‹Æ[Ù¼õF|o¥Ò]ªo¿g\V[ ÆåÑ™W„|t¼arz/%¡2{]´ì²0ǼÂÌ4Ó·Ãh¡óÎ$§áóÏË&›ÉD¿QÈÑHß ôL»ìrO4D€ÆTWMÇáŲÈ$�2 *'Á²Ó]Ä,3Í3ÛŒó™;ó ÝÏ@×+ôJE›<ÀÝx+}Ó�ÿÝÔR[-øà a]¥Ç[‡ÜõÉ:†=¶ÓfÃŒvÚô­­@Û:÷ wAÏ]÷xç½tÓdNÃÔ„§®:†{ü±"� �×�« Áí¸û¹“¯ ö»’nž†æp»`üñƆ®¼è{“î´é¨¯.}Õ­»ž¸ì˜Ñ^!ضã~»î‘÷þ»™ÁoNòÜj�¼ Ë/¯7ß~C?ýüW�8ì\ÏÎøöa{ÿ=Ù»_倷(á�onê3^òÚº÷9ïi<‰ÚéèGA~ÙOkøSœþÞðµþùo !4¾·¸Ê€ÐA_]°@ÞMozÛ‚ !è F¯‚8ÔÕ_»Åq°vIðÿB(ÂæH HL¢åPˆ&°….„¡Òd¸Ú0‡XäÔgp=v°{Þ#"G(�$*‘€hbâUœ¨>(2PŠ7 ¢—Å:Þi‹×»€÷¨=Ûx0Œb$£f̈Ä osècãú¾äBæÅp†-“Ÿ'™ án.sÉãõØÇ”�wb\‚ µBH)ò�?K$ŸÈ¾FŽrŒdéHÉZvÇ’©y&A¢ÉMv’{Aü` �XFBž•iP¥ÐVèÆöÁ’›åm)–XóšÔdˆp@$‚nzSx)!šmÔ“=†’ èLgÖÉθó�ü�U¨�†4&ØóžÆÊƒ>÷ ÿG øóŸJ¨@@Ð)Ôi(@Aï²YÍkZ“¡ Ùfq¼ùÍÍ…Ódã´�9ŘNu²s�ï„gsäé'zížøÔ>ù)ÅT %( :„*tr­ˆCšÓƒH´1í&8Q"ÎŒâf£Dì(:? Ò� žjš§IQjÏ|®4ýt©`Ó‚Ôe ]hO%²ÓŽU ?5JPE0Ô>uœGÕã9•ÊÔ08õ©#�jI§JU«®”¦4ÕêVQª™ÒÔ¦b=ëCʪX‚¤µ(kmë[É©¤†P©d¨ë]¡Z$©Ò“ªLðë>kPÁ*�°†ýjËÂŠÓÆ:„±®ÀcY°Öÿ¦á¢´'e- BÌÖu—:øƒpÿ’fɤ…­hõIÚ)àá¹xðçiïYX¯Ö¬(pÚÌ ú²î4¶²M 7ƒj[ÜÞs·rå(]™ Üá7ÆÍ r•+(Ø÷¾Í…ntKÝÔ^wµÙuÙvÚ݈ÀÖµ‰æŽP^¢šì¼MoR•ú¹ö7*¡ •¹Œe¬ûâ—´ú•.j­kSí®€»ñ®CÁ›àâ,X²5j9%|Y ×m³òÊp–6Ìá/yؾÍ5-Wý‹ØÖfó;m1H–ÌäCPŽr¢†@å*¿Ø¢~CFwTY=6àË`^áçpü0?ÁáÌhæñ—„øcYÿ«\­îLUÛÖ¢ ÅhK[@Àç>3™É4òôœ,�(KYHU¶2æ`¬ewù`sÇìTi™ÍgV3nØüã7»4ÎDÆnb©‰d�ôÙÏÎ@ ïL?BÀÐPžr¢‡pe¸ávËq…t¤ æW:ÇYÂt¦Ke,N{ØÓ/…i¨7×Ò^2Ê„8ëM'œQ^À6é~sÙ’WðÝ,z;ÚÒ¦v¨°�m„q›>Þ÷¸É]n ;Ýÿô»ß ïxO€ÞõÎè½ùÍoãà1xJÆÙ‚‚sõà9I¸ˆþå†ë–Ë•�xË&^q,^¼8Ò�ÆýÄñkkûã‹ 9¬G.î’›üäP÷VÎr:¸üå0烽[‚š»Òæ8×9JÆÉ„\iÏkgMÂp•9ü¨JïÓWlñgcüÔÔ^NÕ_ ¬Eë†æzÊNþœ]Ö‰¦üÙÓ®v™³=&no$Ü~£�¿¤ç0¸û ò^ãö= /gà�ÍÂëDì†Ôâ§n?Ü”§¼å]Nyv“lói_û¹BïÂÑç¼ôsIÝSÿs¼]ï ç{Ñý~ô‡Ï>'¼ÿÓ _œÜ'‰*»—Žã…ù(¿ìÃ�wñg}|—s^ùmg~ûœ/÷>œž /¡z¬'®·}°×}€§t´ÇSãw{å7k�2"Ø _P�Râ{z¶`ïÇrñÇ7ó—hõo÷çhù§ÊcsÂ’eÒW!µG"Þ4Ù7¯{I§€à×t9ämke~•±xmh�Qu®¢�ènÈ4”G2!È7èƒk­Ä|6‡‚ãV…zP.è0ØM28tÚ×F€Hq8~µ×€mуx~O„Œ'øRb„’‚„I¸„ЄNˆg…$zúW…þ–‚X¨eÓ·…JÐ……ÿñ…"†@tdÈ}fè}i¨ƒÎöln˜h("H‡D˜ ‡×gGˆ9I¨„Íqv~ø‡V¡L²ÑcŒTˆþ–ˆ(NfȈŽÈz13Xƒ({™(~3[pŒÈØʸŒ�XeŸh¡¨u.âuÒvŠm“Š•·ŠÄWv®¸F°¨²X‚ÍgˆÐe‹WH4G§‹zô‚QÑ‹:ð‹hƒhq hVýbŒÈxŒËÈŒA僖Ar8„vxKÕØx¸(z¸�|ØŠ®Žâ8ŽPsæø\è˜%æ•Q-ØŽ^øŽ`è‹bHƒóŒ7h�9HŒQ"6c3àuî%\±2®*g1z ÿ÷<Ðd 8%i–sv˜%DY”°’ †Y$³Ge.ð”PÉop¤!‹·Vy•s!26§=q¶G.³xk••!ó3{”¥"Pzó\J7'_`x¢’+¹-)m/ù1y––%5Y/7™“Ä“ø˜³”.7”EI”G™I©TK©GMY*P•®4•¾Q•Wi•by[¹?]©G_Yua "C–zd–]‚–J£–Ç–ny'p—B1—§V—w™—y±—ôҗئ“€é/?Y„o†y˜‰‹ÙQ�y�Ù%‘ù”R)ETYu—‰™¢2›ùCvÇU^Ù2`T™Iš`š´ÿ�š7 š~Úžñ–ó›± k.ù’HRfzér+¤›×Æ›K¶†> îB>‹"”Ju˜ˆ©&H‰9J LPNÙœÏ C"Ó¹™y�ã©�žÉ� é�Õyà)ž-AžæI6èy1½²žì |ewWñ)¡²Bõ‰“»ù—ùÙ“ 1[ ö„L3œFI Ši Œ‰ ŽP‚ÕœÀo~S‡u¡Ó9¡þÆ•Z�ÝIQßé3ey–•–x°–gЖééš& ›(Êr*ºÀ–.š@öùø™úY£¿É7 ÚQ*ÅÉÇ™NÉ)PCÊ ®t¤HúJz™Lª_N SÛÙQ �£ÿI¥¥i¥J€¥ZÊ¥$ú$¯9Ô+”7¦ml’v¦Æ“¦:éjfa8o\q ˆ…©Tèc,Ú6êzg}™å˜¥d¨‚ZX¹¡Zù\¸a.Y�Ÿù}¶VwÙ¡�*©«¹¥­i' r™ª&›êT+ŠacªÇ#ªDª“K§ºK©z�ŽÆB¤B�®êŠs8w³ÊUµ*™û¢-£«ƒš™¿ŠÁ ©‰Z¬ÇTÉê¨á¹¬©‰«çé¬] ­öqÓZ$ÕR×”¨­¡ £÷Ù­šx¦Ê¨Š98:y®Í©®ëÊ®1à®JC«ZE¤· ¨Hz¯¾j�ÀÂÊ…ÿê4Øö¯°iP¥§y¥;©Ïê"O×ÒZ+šš¢ÖJ¦òù© Ê­²ä­d±±º$® `�µZ²‚‚®$+&{²Vñ®0¯ÎÉ@Ðå²Iʫԩw ]ûú³�x³þÊg÷Á³>[¡‘´ÍJ©ÜÒ"Eë�Ѱ#ò°ï±K±PMee3Ô‘½#µTÛ±mC2Z»µæÚµ#ûµa‹²7 ².µIz´Bx“¶¹¨0ë¶1 ·4˯t‹¡Æj·Ç�·�*·Ìz°~K 0¸ÆÁ°HK­J ±LË¢Ùª¸«¦ëPŽK‘›±1¹V[¹X{¹`Àµ_âµ$Û¹c›²ðªU¢{¤ÿ{7¦ë4öʶ³š9³P³sK¬°Ûgw“Êj»|‹»Ck¸¤gQuì†YÈsÂC½`�W±GHpÀ´q<ÿ´G‡E6ý¨Œ’÷Àmp)—’j°�Ç8^å*ßhÈe.‚µÓÃþÿôÃAü\Cìr[ìŠGœ@IKNÓÄÊòÄûYj0ÅT• M.ƒÉ? Én Þu˜Å¡,‚i·BÜ\¬GŒÊ_¬ÊaÌÊuvl¸î$Ë´¼�¶ÌVæ“B«¤>vÌË¡ãËùÌï&Ì!]i0xpÌæÃ"Š+4Ì7ŒÃ¡Ã"ÁÃÓ¼ÈÕ Ä_&Ä tvgw@B³eËóÍK|ÉYáÄÚŦÿ&méÜë,oíœ@ïLZñ|óœÊ.°Ê@SúüÀüŒW•‘PL�kÐjôŠ}<=ǽ\Ç$ÜÔ Ey÷]c�};/Üí4ÃÌ]È}È�È!mŒ\ÒŽ|Ò(o*-,­<.í7âLÎjAÓ�lÓJ¥ÎV,Ê0çÎÔ ÏVqÊBMÔFírû¼"µÔZýÔTQíŠd½ØÏ]*Ñ=Ý.WÝïFfRÑá׆Œ ÎT"Ž$NÂ&ÎU(^gZ}Þ¥­Þ.^40î¾2ßí’ÖÎLß9îR;NÒ àãü ‘B>DÞ2F^.$ ÿ®& .wÐèŽîà+á` áUÞ%W~áYžá[~Ý]®Õ¾aþQc‹ežogS¥^ÞLÍæ�QÌÐÅÞŸ÷h~3ã5~ç7ŽyNÍÙ©ùÝãbôã@‹�>è]Pè¤qè’èE²èQáè�þä‘å>åÎ}>Ôþ„åñ¦åîÆåQáå/æ»âˆDæ Tâþg©žâ«¾âÇÁ4†úâ±îÞsNãu>ß·^ß›sßP½Þçb”?ðå*ìVÍÛB Ä~cì£�ìáŠIKÞQüáì�éÊ-í“Nínå®í|ÃítàíîâŽIä7#~îfžî\µîj®ârcÿPñçóã´~ï6Žãû®ãýÎë<ðD4ðïr€~ðžð–\äSà!vkµÍN(ˆp5…xsUy ß D2EÐõ^o]¯_aˇ°ÂnœGôŸNua|@ºIæÂßK2í><@6#�÷zß«:0oñfµeÿÔÊ„66cë¿2"ª2¶Qá°O¸Ó\Ô†>f[ìáq’ÇžroõÉÑÁš=7Î@X¯õKÀõ^ßõ`_bo²d¯&fŸvhŸj/l�ßûöº÷Ð1÷_÷wï4z¿÷më÷|ø%øÙ>ÆÑdøô�ø’¸øIÐøØîO�;’_+”¿²Íÿyù¼‘ù'°ù‹‘(ž Oõ¶Áo¥ïë§©¯ú±öÐ5öܸí°?kg�öµ_·^ X°ÅA„.,XPàC}$NtQÑ¢ŒS4òèÒ±ã�!wŒÔQ’Ÿ )'4`©Ä% ˜11ZÐ8Å£GVì\±ÀçO*f �QR‡¤i”LÒ4fÅ™òL…PµfÍ:YµªáÚ5*Æ aÅ.\xÀìÙiÕ®M Àí[¸qåÎ¥ûóç¼yÃìå ÑïØ1»vPØðaƧ.ÎòÁÈÃD¨Ár‘"x4ã‰ÑÙsСUªDZÚÀÔ©O®æ“Âõk2±µŽ¡]û/ÿ„du+4�ôïàÁ-^̸ñfÉ•�ÜaôähÇ.•L†1³æñ.9yö´» (Ñ¢%K+MÃÔ)L¨3W…pU£eøÄŠýja~ØÝgѲÐß?]0(U0Ê(¾úò뤮¾Ä"DŒ±©ƒl É&«ì²Ì6«­¶ÐBŒ+é¤KM5ÖPm‚ØÈ˜íÃ1‚ ·ƒvsoŠÞ øMÆ7†K�&ãnRn9’LR1¥è^šÌ:�°Óާ(£Æ[Š ¦’xÊ…¨Ö«ŠÂ<â³ì¾ ê#s·�BbëÿþðÍ7 êÀ’Üë¯\ò+ û`1Ç,Œl ‚¨ÛPÌ6ÃÿÆ1BmD5JtéDÔR3ïC3ÍÖl³?8£•«jå4�N;ÃÀ3Ï;äÓÏeé *ÈЃàKÔC�RI•HŒzW[‘Åcc”SOA½JT�Hå‘ ‚‰£UU�XmµHžS)V‚™� U'u‚Ò'9w¯×ò°<†¥³X1ɬ¯”S^6MgŸ•öe·¨íÀZ:uÈvÛ<½� Üp+—\ ½ÝÔíP3FÝ…WÒyëux´|õ…‘_ý­ÿ àˆ$â4bƒkB¸#…]5º–\ŠxbZ+Þ.W5>Šcó´DïTŒF&9>“¿JYeݘm–?—a–Vfš±µg=ƒ�ç ):hˆˆ6ZѤ]ºÄ¦°wōɨ—Ç~u»뇶.øG¯� ›á§W*[‰³ab²Ö›nåήï¨ÜØòâV=»36ï¨öFye5oSðÁ«•³æ›äVç™oœ±Ç3 ìÐu‘†ÒË¥Ë|s¨£þ\ÆÐɽ·eäõ fUì†a}=öê(¶Õb\»Ë}(^ñÎWÀš›°‚¦’ÝÇ3ž1^^ð@úíYó¢E¸ç.Aˆcõ0bÿ½Ã€){~‘‡(÷=ð &^ãk]J:w¾UMt¡bŸ_LÇ„®Ålóc�ý üÍNmÃÝ”¸»ÞyLn £›È8<.0 „`™EÁÀYP@,ô'½œÍªz ,Œ�¦½˜pïh‹Ba IÄ4ÄÐKs-ÄW¾`œô-d}¦i_pÞG·Ô­jHôkƶëìomþ3bxÞ&ÀŽýêc!;àT 8)NÑxU| ±è&-@f2A)M©T¦ò/™uŒ¦ÄR–ìalyK\ÚÒ»ä%D4s`¦ñ Ò‘#{¥H‹Œ…)ˆgw¯[ni8B f5ypMlÿ¦’9¨$O6sKÐ>ŽÙÂqÔÒtå” èæf0S„pâ&KI` í:¢ ä3q¥óºH'YÊr7»‘£ÁD˪ @¡ ýBCðÐíD”'¡´`?;`Êu¦R«de\)&X4…@.MŠ^öò!¿ &e†é’bVå˜xH¦˜–9€fvæ™+пܦYMjb3›¨Ü&;ÉóM[ÆóPä4gZÐÙu–’›GÕÌ;•z�yÖ³©'È'ö ÂH¤!¨n J¯ƒ"t¡ uèC)úÖ¹X£RÕèFýÒQ�Næ•+IOšË”îÒ—xæ „ÙbÒ˘Ǭi|nšÓìtÿ4=eâO�*Ôkjs$SU R‘pÕ¢Y†©79g:‡²ÎvV3 ÍjìÙ|êS@a5ÊXËJ–³2 ­´\«Bú…‡~®Ãe?ç*‚ºÚ"xýh|BP¿þõ–�µÁ` {ØÄ2`±Šj,|Kg 𶔦E€TÌjvœõ¦fÀ)NѲ¤œ¤uªig€ZªâÁª4jíkcëÕÙfP¬"½íBr»[öô¿ .q‰k­ãvS)h¤LŒ…Yô¡Ò�n`­ÛR $»ìÙM¼”¹LÈJV%”5†1¬^öz´ã”ïVŸUäµ³ª…'³¤UúrU¶`pm \`ä6Kÿfòœüd¹0Ø­†+„ç*á4P¸ÂƬ†iÉa]zx¥„±ˆaªØª”XR'&cŠ!³8� å­ˆ‹ÓKÔÍ긽xx/nhÜ€ùz¤´P=-]S«ßÕú¸)@tZº*\ºÐ¶$¶E²’™¼ä'C9.R†4•µheŒbYËÍ…†Çª0“jE+Ôý°a]ŠØ3TÍ%b3ݼ8oá^Ôi±�±Éœ¢ºÏK­q�o\èz¿òü±k·úh!@ÚÓ®ÙXçpmlô¬—Æt¦ —à6ØÓµ)EM †ËB=5«Êðnx«:+Ém5vc-ÇYK§Ö2Ö­s½ëÉôÚ×<vÿž…�Tøj`´�>Á±ïkèü.!ý}ö�4mŒgœç8¶±�‡œÛ#Ï€·¿—pOyÜŸ–S„%C2,ÃXúD‹HC)ZÃ6<«7´=9”7:l;Ô <„=D%>$¾ÉøÃãĈ2D¸¸Da•Õ?¥Õ@ ”AÅÕBÕÕ]}×·@a,dFò¨ ÇØÖ˜€�³Èµ~Ì€¥ŒŒ£Ž#Š¢*¿Â²3S2),l’ɺ²wŠ>9Ú ÿÝ‚î»SÁŽíØLºFù‘Ù¿<$˜èØÄÐ�ª(ÕT²H4•™xc²€…×ò”×  ×+´W¥ÀW–ÐW ³Œ~…³­Ù7Ø(Ø¡8ØÔJØŠX؆¦‡Mˈ•°‰•@éc‹…SŒí¾�íXŽýX÷ّْ•˜“娔=‹•ÍÖ–íÆ—õ‘˜ˆ™]2£µYÖÄYÐY,àÙ4ðÙZàW³ð×_´Û0=Úi#Ø�3؃R.^ic\pܦƒ\�m^Î%“B¦ lcºž`9ʤ{qOÑÍ­I®dJ¾d%Èäòáó-aOÆ3`+SåÞšeS.FTÞY7þ[8\9n:NI;ÆãIØæã!n¯"vÞùøå1æ‚f'>+c^ÊìXevfnæ‰höbóc¦ÃfÑæµâæn6ÄoîÛpîÝÿr>g’LgY^g=nç[NÞ\^Þ]d†½z¶g`ÃçÍí9zÙçÑègŽýç«h=pæ‚6Œ/F_Hh‘š)†^(‡~hŒhÞgßµŒWî‚Xþiäh\N%�–Ü^&iÌ2äkf&–à|.(–V —Æ�ÜZC™¦é ÖäªÀ¶fæ+žö‹ Rj n;¡žh¢®èV>ê¤ÖhÅ­åãíè>þè?i#žç©檾ç«&æ•–¢–ÌJ>+°h±[²†³®æœ.8µ>¦¿hk¼~ëq{Mú) L…Q^Fˆ5ÄŽXNÕFL»¨ÁĈmÙV˜mÄ‚„j‹Ð£&ÙŸ!ÑÿÈŠaøpH˜‚ .w©�x!žÑ³È­ZÃ×x ¨nëÞìÎnðŠ?ènïÎ ðv€®ê*Ï&OÐfÑ^VÐj�Ó>ŽÔ^í¸ˆ×@ÙžmV©íÛæåÜVˆDªèí#úí:îªî).îA¾ävå–æç>è6éžî°në–¯“BΖÈò¦ËónŽÝm¨6m»Cí;Ví`í‚ä¸×®ïئímÌo¥Úoèoœøoåðmà® á¶ â6n¬äþŠå¾�ævî ß› Ÿn ¯n Ï8·þðÞ ñ"ñÒ>ˆö¾‰÷^ñøîŽùþ=§�{Áoÿ ÓÏwÝ~­ìÐñäàñ÷ñòò‘/‘÷“_ò”irê~ò(Ǹ)o“*·ò•ÃòWoOérŒVq?ÆÙcFf„LÏô3Ÿñ4ÏÔ5oóŠpGêqÚøq òÏóÐØsFrwîðΉ’( O),ôi;tÿHtE÷4F$-_oH‡å‡olóJ·tÈtM_4ï&5?ÇñŽÈ Q7 RSGõ°8n"gp#wpW÷sX�õY�¨Z¿õ”Ûð”ëð»íuüõô†—¤‘aï—ô0oíd·tfÇô{i ÿtþÞmÿ¾ö’Èöm¿óTÿö+2�ÿ±Hrýˆu8÷íÈwÕV÷pc÷ps÷†÷+§tƒÌYôö�Éô‘G?ñãÐx0?v~;e_öxãxi¯Pçíp…¯óSgønò”rˆ¿‰ Š? ‹wy‰ryŽ.�.�a‘_t’Ÿ×“ב”Ž•oìpùI_€œù‡›ßœV6/x7·öžõ9/u çö ðö¢w”£Ÿ�¤¯€¥7‹¦×ø§×ø¨¨©¨ª¿z€”w¤ ©ŒÔ€Š o—·¨¼È‹ä2ûš_�ïtÒ®q�wûP�{lŸ{m¯{¡¿û K£©ˆ¥ ü|ü|/ü8üH|Åo»ÿ¯c|p|ì“ÈïÉï§ÊÇ‹ËWö³Oû”Yûi7øGx'p0ðœr°<íßþ½‹¾�p°ŒýXwúˆ‚úÂÇ}Ýßýqëý¬7y$à�Êøþœ(þQ:þH~Ïüш¦)hðB [0Tè‚Ä)»P¬èÀˆŒ fpÔá±N�1"Ç@(©á$Æ.*°¬€p ̘GfÒ aófË–'5´<àóg̘(†½hÔA‚¤JW0mªTi€¨R§FE`õ*Õ¶rÍ à+ذbÇ’-kö,Ú´jײíàVÜrçr¨kÐÞ"z¦Ü¹“GÅÀ]h^`ø0‹ÄŠ=ÿ2ÖA“&ÞÈèP®<ä2f(š7�yã3ŒÐ)•�þ|ƒjÁ]2dÀàƒ ޲‡©mPnÒJ˜ðö{²$„Š/†aüøã™x–3ï,òô謧gðÊö:öìÚ·sïîý«ÛpUÌ¥k·`d½Eø2ô­°êÁ…V¼¸±ãä’ñV¶Œùòfœ9gZh0ŒVÚg¨Ák¯Á&[GÕÆm¹‘Æî'qÇ\rÌ5ç\tÑY÷Š)ª¸"‹Ú…7^yrÕÅÁ]yíµP{¾-(a4ÐWŸ},à—ßcûMÖÿ Î�A h éfš‚ª5øZlÒf[A¸ ¡†–Äÿa‡—Ü".çd‰Ð�Ø"œqÊ9'v/ÆãŒ5z {-¸·c`=þ¸@�B⇦‘H&©$“MZ”-L™`j‚]éZ–³IÈe^‚Ù›oRÔ¡‡f¢©&NrÕUtºú*¬sÚIžç¥‘Þ�.ô¥c|òùøc¡C"ºŸ¢JѨ“P(%‚§UÊ`kXB8Övián ú%j¤¾�VVY­ºÕ›±š{.ºkÍãy¢gãz8úÉk|‚¤°ú‹¤±È>zC�*Aå³]ú –›ZÛ)¶a†:樤‚îTã PnºklîaãÁ(—!d�zê¥äÐNMh�öÒWÿ¨1Ël¤‘Ø/“#õ±³²¼ Qg¡Vø¥n¤íÔÓª×ÔÄGe1Æ[}u‹{Lë!+0rA%ëu²B)KÄrË4<°6Û^{-óÌûÝ17Ý6‡†Þ,±7ß:ó é²’6[%EAG‹é´Õ�´Ò'1Ý€ÓÃA�–ÔRQÝ*Ö™kž¢ÖÏå5Øiˆ]Ù.˜½2�i³Ý¶Û À³‘t×mwÞñÝ·H;÷Ñ3³S ôPB'®ðâŒ/Ý´`O3µÔ—Oµ9ôÑg×ùÇ]‹ ö襟ŽvË«¯Ýºë¯Ç.ûvÃP»Þ·/á÷î€ûü{E†;84µÄ_‹tÒÇCžÿ¼äËS^¹VÆU5é°€_¡Þ�¬÷5ì‰M{'Q÷zä½€ïuŸì̇>õ­/wX¤&å,à¡@x +§“éÈeT 5(„ 6….t\½)NÃQq΀œ°<§Ó9GÜœ¤F ©/ÿHÒ¤™Ÿ)å§2ÿ©J Æ’[Á¤[Ær¬P…¦`hNÃÚÐ�fʧ�eFkIT|õ¨ñÿ”ç/—ª›¦ó©ýdéT�YUh^UšÐêV�¯‚U¬†=%Y'ZQ5ŽiUçZ‹ÙV£¾U –½¬\Iƒª“Ú5ªrlé^Ú׳V°]¥ia«Ú&vœ®,'c/ÔÇUE�ìG+{YËfV ›Å'‚+\•úó³y hh j–Òµ6]-t ØÚž¾ö§²u¬FIã¥Ûâö�ºÝmo[Láª+•j¨« ¢�m®BSÝùfnºf�-Z³«„í²µ»Þ�çny[OƉ7‘ä .qÝÚõòµ½haîiãû\úRkö­îY1ª_þJÖ¿» 0ˆÕ`>T¡jHæCÿ‚}У°X¹e�ðT;á Ó8c¦(lc™_µÚ¶¿Ž@ˆ3ˆ—9Lô©æn~³&Oü¸Çµég¸3žå;å=?´Ê‰¹2G²¼e½tÙ˦³˜KBf°�ÍVó'Ù,˜7ÃyZržsêŒçy˜G¼ÞO[ÅËoŒkœã6—žÇÿ è�Ûdä_^5ʃ®r¿°Üݪ±7ÅdñUaü5¿9ÔëØ�k’ç!ðyÉ�ô“}'E§öÑ_Þ²˜ouæý~zÔÓ®±œ‹zç<Ǻª·Žò®ŸäëÓ{(“®o™_œæÿV;à7ÆöQ[î —{ÊÝýð~ÎïDÑûa–Ε¦£=ð–wÕàÝrÿÛ\ît×€Ý!âø¡@Þ0’ß åÿ~ùÕ§«´[£ß ¬>:÷ä„%¸=îò“aֹТÎY/ü°¾¾ê<Ÿ½oj_Üç^÷à}­D�ê`nøÖ7lñ§%{±Ñ¾öÌ¿½óŸÿÉÞKøÕ¿>úoªíi™IÈ÷‹ò¿?€ðC?(ª`Ò¯ÿ‡®BíÿNÄß÷ÑßøÕÑ…Ëþ%`7õŸlü÷%Ÿ÷  óÕ_L`ð) Fr„–L÷å„ü…)‘RS4Åf ¢ÒÎ@û�϶„ü-ÙŽR 2Å ¦ ÞÐ�hR ¶Î ÚÞ÷Éà Öà Ü`¡ô Jx„Gºÿ�ÕÍS D¡ á¡"!fŽ.a4¡×<á/Iá²Ø J€ Ðùe¡jÌ.¡† þ‘F!’` ^áæ!ô°�bh„F| âôe^ ¢já".b¸)"#>"Ÿ9"$N"�I"%^btY"&n¢ai"'~âMy"(Žb7‰")ž¢™"*®b©"+¾âæ¸",Î"-Ö¢-Þ".æ¢.î"/ö¢/þ"0£0#1£1#2&£2.#36£3>#4F£4N#5V£5^#6f£6n#7v£7~#8†£8Ž#9–£9ž#:¦£:®#;¶£;¾#<Æ£<Î#=Ö£=Þÿ#>z‡,æãî#?^i9ˆ@¾F¤A¢ NþãÍä@ ¤A$B~Á .$CrœC>$AFdL$E*$>ÏEF]Fj$pdGNdE†$ �$Ô•¤F*Ê@ DïÕ™!ºä§ÁäCÊäL@M¶ÉMâ$ŸÊ@ÎÈŒðäLþd‰LGK 寥@e] %MÖQ�1%9åSIQJ%U „RJk4¥VŠ[¡€�TrÀWú¤U¶ Væ_YÒJb ¥W"IO²eP\åXfe\RØ\Ò¥]åZ†%t¼å_®V`އנÉ[ÉdF&,©øŒ€e^¦ d¦fRY®Ei�ÞŤÿ!eb6Y¨)c†ŒcÆSdJædVæeZ¦fn¦hšæg"ÀB’fi’ÖÔIj*ÀjöRkBædŠlÆælf&gú%[ÜfÙ±$s~…nîæ‹õ¦}üfpöÑpÊAq'f&çrÂåu8çUäfmRgsZ'jÂEc&Çcgw¶NlÊ&xž'o’§yŠ$zjÇb²§jº'kÂçkÊç|&§ „gv�§Uäggîgz"@¡ød'm'ˆ’z|çl"(v((nB§x‚Åt:(XœfbHhëPèXh€a¨^\¦•Øçr)¨Å”��Þè¯�Áˆ’(˜(  ¨Û¨(‹î–‹ŒZŠŒV'~Ž~Ë�âè¯í(‰ú(�z�“|W�©A‘)ƒ$) ¤fÄ„©˜fY–5©�æ¨Gòh‡’[�LiÈ8‰ Ò•^V–ZfŒê'X Š—~©˜Ž)™Ö�™–šN$”&¦”øÀiœœZV�ŽÀ�6¨ž ä—‚@Ÿ†éŸª™*Bîh@!ù,*±ÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‹ ;hÌÆQ›Çm ±ˆ¬S'�É@9R¶Z鎜K—ßbÊlD³›M{8sêÄy¯§Ï@ƒ‚º ŸÑ£’¦YÊ”iʧ9LI�º¯ªÕkX³‚ÙÊ•�ׯgÂþ‹±¬Ù³hÓª]˶mC�8fó¨m¨H,$O¢TÉò%L™1i6²Ùm§a{>}Ò¥KäQ¤J›6…šr*U«U³jåºõ+X±dÝŠMº´éÓ¥áÊerdÉ“OW¶jépàš7ëLÜsñÇÆ��&å y2eËR1gÖ|�sgÏìžûµõëØ³k'­ºãïmwóÂÿæ;Û/9ÛßÖ­3hPßu�^Ü)eqøó+ßǼ¹sèÑ�VÝvhà�v7×wá½fRl}Õf›z¹±g�{@Á×XQóEVe9ä§Ÿrý9€ÒQ‡àŠ,¶è"Z ²žkzAXž„€QX˜…b¨¡|�ÑW_ Šˆß~%þ]Š¡½èä“PF @Œ Ò8^²ÑöÒL¸¶£N†„)&† ü8#|¤©fq™´é¦yä)Î8tÖ‰Ã�x &Šà§”€*(jTÆw¦x’§å_éu¹ÞNbŽé£ov‰¤æš’¹ù¦yrÖi'žwêI“aLþàgƒ¦ªêªeZ)^îÿ…e„[Þ6˜—_æi˜dšy×¥i²©i&pvêé8 †**©}þÉê³ÐF‹�«­ÁZ£¢æqy«—ïtëí®†ôJiµÀò!¬¦Åy,²ÉŠÚ³Ó�uª´ôÖË*µ‡Æjã¢çÙŠk7Þ~»«¸‹½Zî¹›úe¬§Éâà.¼ÔÍkïÄC‰oƒ×Îzc­�nKXÀÝ‚K°Œ¿‹p›éЏnÃïTªÄÇ,óvØÔló†¬ä¬³<Ëâó~èQC�7DmôH'­—IÖ4ítpø õÔ±Tmµœr†£õÖÕtí51`‡=ÀØd M {õÔ3ÈÚƒÌìöÛ×Ù|sc:ïÜóÏÊ=´Ñ|'ÿ­ôÒN?ÜÔT[]5ÖFn͵×]‡-6Ùc›�¶ÚlÃmùånÉ]3Îu³Â³>Ë´mBóÝ·ß,HàMC½´†Žx~ŠkÍxãŽyäBOÎvÛ˜/:`¥›^4ê©κëzÁûì´×~{5¹ë¾»äº¥ýûðä—QñÇÛ :Þ˜éíüó¨ÇKô×OýIÖŽ=~µ‡³}÷»ø#¾Ê™ï€4úèÖ¹ä±Ï*î{Ÿ7 '¿úÙ/8¯“ßþÄÑ¿ÿå.€4L×–À&p�Déœç>dzåɤyï£`ì,H?(Øð†¼Þþ:x;~Ïl½ÛÉÿ�gÂ"…CQ! [˜7Òí-†ñ›! oˆÃêip‡ÚëaîÖÄ êdˆF cð�%.Ñ…1�¡ódh8F€Š6Ì¡þ°¨8:Ž‹]!åH(Æ>¾�ŒÛ0# Ñø 5šŽ�Vs#¡ Ç«‰�Œäö¶·.<Q�ãó£&éU<¹È…pRsãå°.w©ÑDû©àáJ”ã•°lX$%y»#Øò–•6JDpÈ�ž,ç:Ñ™N÷°“� • <çIO{ÖŸú„%?ûùOiÔH-‡AŠº„îS—]lèCoщb¥¢[»hFϱQ}tÔ£ÚI)GDjN’–(']§T³±R–êÀ¥/]b>÷ÙÏÔô¦"ÊéN ŠPPæt¡B*D‘&Q)P´…F5ÊQ¨h«T=§½®”¬šs«ð\$X{S²Ò Ì‘S5 °V´•p9�ì.åJTºõHÕšRùêT¿~Cã ¬F¬zUöµÄÎp ÖÆÿÊ´¬geŽ,«¹½ËN-³ÕÜe¹†ZT»¯IÕëR›úTÓZ°šc'kKêZ�lU¶I¡­KmûÊ™0·šÙí,{ÛS·T³]î\?P×»æ•l{ej_�k�׺gœØå€aéEX¬V÷ºØÕî=ÅÓî–•lý/-—4-8xjw-G�Ð ÄrA¯½Ç}ïØâË\úÖw#ÄTa~÷«ªqÂjw¹ J1D‚»8¿‹t°ŒµÀ] xl ¦&oo×àK-®æ¿,Œ: ƒ¹¢U.i›ëaÑ(H."Æ.‰Seâé'Å"Y±{\üâÃqÆ®±wËšcPM–¼�1„�+a:MvÿÈÀºðgCŽÑÊ·´M6Í“9eÙ†áÏ€,•ßiåÇ` CH´¢¡ÆåÃøË`ó�Pf<�™ÇHSó�ÙäYÂùRr6î‘5<Ï7Ïܱ'û<@zµR¦'O|e,+zÑÁi4 ME0k!ŸÀ¶c\é;]šÁ™ö±€ìf!ãŠÈ~32�íÜaT§:.!î\~]ýgACIÖ*-ôQ}ëD3ºÑ¼¾¡¯ƒìa“¹v ¶&¦Ó¬lf�ãÍÏŽs‘çŒä:+ùÎL¶vBÈT ¡W}pw}sxÚ§ÜWpÞÇ|~H7~ —˜b~Nƒ~¶—{ë‡:‹å~‹W'¢r¸b:÷wrùw'ûÇyžÇv çvlVwBz&€}tw€‘€— °WO7�xÞ&Ø4(hxì×8Œ7|ð6ó÷ÿbL4¤|˜w'f³=gÇ-8}&ƒ8�sfcƒ�IÚWk¹!‡Ö™>sš4š,Ez¤Ö• JJ›Á ŒÿÚ¨Ì)OÎ)Å!”à'èQ¥Zw¥ê‡\Ú¥¹Ó¡ê� ž"*ž$Jž&Z?sZ'ݳ¢-/ªš1J3Z£+�§å³§�ѧ©êFôÛ½ ¤¿ù[CŠ…ÚK{YR‰ê,‹Ú¨Œú¨:©“*”–j˜úxšz�œÚ©}à¥ÝwßiáÉ6ãIå £jê8®ú¦qÊ«J'uê wjŸ¸J>#ó¯r~JCÀ¨H35²aˆEZ¤ì´!d²¬P<Îú¬Ûà¤PÊ”Z­€q­dã.ÿò/ÜÚnªè®9�•r±!nä” )'­ 2*äFÅÑ,Û²p¯Ec³i@Ãs¯†ÿ’¯"±¯Ô¯Â* R#ò´B›S[ mÚ¦|Še«° ­Ò*›-ÖZ;Vª'‹+»±ŠðÉ#öàb!Ë@uC²¨°0uÒP¦gz*+-ë²æ±.¦/yÉG5;)³«X¦³õó.uY@+´AK´E»TG[šI›bK«9 Ë Nû Ï µÔ*µKµ™jµWKYKCk]Ë#`Ëé“3dk¶t‚¶i;kÛm˲p·|#·aA³Â3Nf‚³X ·ôC¶‹õ¼Û»»€¸5¸„[¸‡{v�¼Ê›ÌÛ¼Lë¬�û¤¶7,™µ8";6{¹6‘¹$²ÿÁµæéµŸ› ¡Ë £«.ÇbºiëF›ð¾ð»ºíкÇ·.ƒ—g »n³ƒµ[-úÚ«¿ðK¶‡Ö»¾û³À¼‚K¼…«Ç+Ê»¼Í˼Ïë¨ ÛœŽ+Ôk½ƒ½”‹­–˽Þ[?à»⫚äÛba›B�“¾*³¾ sº¨KCü¾òK¿žb¿:�¿ùK·¤9´;.DÁ«gJÃ5LÀXfÀ¼û»­¼ò°ÀƒÛÀŒœ¼LÁŠÛ´ ©¼Á‘{½1‘½Ä'*ÜÛ½ÜêF%Ü ' š)L+œD-L²¤;ì«¶F,À7ü¶õûº÷‹—ú;X°åI‹»!mPȆœ„ò:Êÿ£rÒ»ðÈ�L™vèÄ/ –,AES.‹ä‡ÅÁžüÉ7¤3„lÈ…Œ¦�Ç~‘S¦SS5@uÂEŠ´ 1qnÒ²�ŒìÁ÷ ‹Û¨Nò!¿ùK:B¦SÛ°8Üi‘ô(Â6õ*-[5È�AÊ…ŒÈ±£ÈT·¬ %ÉuHÉ.aɰ€ÉD£ÉpÄÉ’ñÉ lC¢\ÍÖlʨüªÌ7¬üO®L'°l´†;ËåVË,Û͹̼ÜËÜðË[Ì«;̯TÌ6qÌ5¬Ìzì)ø–+ºñÇ3ÍZLÖÜØl8Ú,:Œl$ýñÍ“9ÉÁ[É—lÎèLEêÜììÉ¡œ3£ÿLÊò¼º*M«|Ïù<û<œ²¼ ´Ü&¶LÒ¸¬º\нŒÐ` ÐmËÐåàÐÝÑ,Ñ~±.íµ=] 0NÔÌÑÖüÑVÒûÑÍYaÒÏ€Ò€«ÒåÌÒÀ²ÉÜÖÉ1=Ó¬PÓ†ìÄóìæì ÷, =ýÓÅëÀþ|kÝ�ÔÍ}ÐMÌ+!ÌøAÌŽòÐ|ƒÌVýXíl}[ Èî±Ø Ö¤,ÖU“SemÔÞ 2à âLä¼×-}C/Í1Ítm×…Œ×8m{Ý×o¥ÏºËý,ÔÿLÔ�Ú�J½¸LíÔE-’í16Ñ?¦­ËÜlžV!ìÑÙõB& ÿͰ¢}È(?Õ�f�h­ÖBËÖ°ýÖé×ë<×îLÓðLʺݶpÒÛ÷üÛ>Üü,ØÄMØÆmØÈ�ØÊ­ØÝÜ�½Ð‘ÝÐ“Ý Ô=P—í™�Ý›=�>ÌIšßÍ IH½­MÏ®0K4 ÅÁãLÎ+½FHÛ64ÛKaxÛxŠdëÄ9å 8žãT,!î9Õ?%î 'þÅlMÎ’—4! ×®V2ž3ÜXã OnQ¾èS.*U^;9%뜎+žn ÞK¢¾á¾Qê£}êfžê©¼êµ³æ¯n‡±®é´þ!M©~¨Bºžç½Nì¿ìÂèüþJ„î%†Nˆ>ŠþÔøáìÐþèÓŽÕ®ð"béq‡é¯Äí·ÓéžîjX/£nîâ�~¨¾Öª.M¬>Ÿ|óîuï*>ïõîæ.�ïPÿ7ãp¨ç€{ãþþçÃ~ó?n셎쇮ì‰Îì‹ÎðŽíñÏ}íz’튳íšÞí^òíÿåªòñ Kæè®)gNiÞî­žò ƒâ®-ï%H4r®Íd/óGó4góCËç9ï<€îëïóô/ôOôoôíÒéÔ>éÖ^éØ~éÚ>PÏ8¿åUŸáR²–^½ÑC¡ÄàÂP|yÐùžï.Ûë%»D©ýa:ÿ‚¥$'ðY.{ÓmÛ…û²oú¸bP³pûB›h°û¼oEêÀü*¤ô,Û^ÛTÁá ›_iìÎÿü“úËÂ#º¬ËÒØŸý`-”ÿOL_}ùJ¬ù |åàùŸ/ýR=úBYú|súšúFBû^ÒúÈ!¿°/û±/ÿ„aû¸òä‰#ˆÆàA{ žcØÐÏCˆ¬$NSÑb;Œ¯mä¨ÐãG}!ŒÔVÒ$7”)9¬dÙÊåKw1e Y³ÑMœ9o~äiïÞO A²#ZtÐQ¤”.ÙÔéS¨Q¥N¥ZUê¬YµbÍÖÕkÊ”ÛÄŽýSÖ,*´i ®WÎí[¸nóÌ¥«Ón£nyõRãÛÜ_À9z#\X¯Þ‰³eÜxmaÇ»õ¡\ÙÔeÌ5 ¾VÈógÈ„%wóQzÖi� 4ȳ¡Cˆ'R´XQ3ÿFÎ×z‚IÒdI°(Y¶|éRæÌš4ïêÜíQèó{E�"=º”©UìÙµo¹uÁoàÁÅ_™ÖüùÆqË=cßžn]�ÕäÏÝ·ï>üùs‡öæÈÿrÐ1ƈ1ð@þF«¬²ÛÚi,·Ñø;bB Kóá´YR[‹µÖ>z�¡±ÆšM" 1Ì/¿çšS($}šO›ñÈ+θãÜIN9æTì :¡¨ó1)ëànH"‰ôîEñbî<&QI/®öÜ{/»æ£O2ûø:¿ýBû@$�­ MÁûhðAÎ" � MCM  9tíÃÅ‘•OÛrŸud±© 5TI⊫ÿÑÆíÒqÇ””º …,òRL§:¼$ƒ#�ƒ&ÑcL½(Ù›’Êø¬¬¦¾,ÿì²/ý SÌ1 *ÓÀ%KSÍÛØÌMÈàœÐB 5\�µ;_Ës›=ûœåÏ@Ut$CõTƽ‘Gýè¹IäÒLË5€M¯ vÛý”ÉYÉY zU­¦ÔgN­RU½ ë+€]ÝÈ‚¥1øàX‰·±vøVbr=¬²—Ödì9`AÑXØ#œ5V„vkHcP–¥ g¡ª¹i�ª¶PDWš±moôVGqsÒºs{. ƒF2¸vÝ%ÞYç­WU|õMÕÊ~ û7à-9"ÿØ™ƒŽ5ÞqºöÚá‡o•X/Š]²˜-Œ%+ŒdŽ=¦óØæFÖØd‰,JyËhyj™Ð—cæ`f6¼ ¿Ù£|W\g�Éõùq킚S¢‹nãÝó&ˆ^8ìmzÊ}¡ÎË_¾ŽDàk®ÎÚà„¹öºk°†xì¼ÊnåìµÒ>lí�…u[5�;ìIî’ó<ùîóæ­Å§^îÀoÀ¼pÃOHñÅ×qÈ»§Jr ‡ËòË�Î<éÍ—¶òó÷B¿²Ò©1uÕWo}Ö×a�}ö3u¥¬â^]L(ëœ~W'4Ä�!$£+ìÖ'•…e½qÙ˼㯘Å,Ò›õúaÿ½ëa/ÚÛ^�¼wB©€âK ù0g͉ƒsžÃW©4qCÚ+jÞ˜Úéª6°‚ÙokøË_ìÀ?È ©ÔLct·C¶ù®O Ùð87ãÕ­"ÈCÑÊv³7jYp+ìŠËÂA6xðƒ:ªGÝ(Â’pRÜCa B¢Ä…æƒ!úd¨¾ùÔІ8¼¡G'µÒQíDV bÖî¦ü�ÈHŒÌÄþg¶¢m€j#L 8Å·/�"»bñBt<âÍ‹=#œwA2šñhTã£ÜøFÊqŽ&´#ä²29ug,íÂLf2¹–·ÌC™<á�B܈ÆDSš· f5íÕ Ôÿ Ûä¦öÎ]­0²KÂøÃÀæO]¼Oôòx.ëS ʈ€>tŽÑèEûÄG?ý9‘—8K=‡ÛÙu¨R©3$T¡`hCÊP…*޽¤( >Ê�e˜ì*æepG�d.ó#ÍLÈ39(ÍiV“š×¼M6ÄÍnzsग8 CN�˜óœ�Iç_Ö‰ ¸3/ð|‡<ÉCOŒØóCùÌË>uàÏJ$ }èÍ ª”!Uê¡[u+úUï]t… ‹XˆÙÑ�¶Å-Êœ3CãÌ6B¥PéJU…M�h¦H�éLÝN‚�Ó@åŒÕNyÚÓŸê'BíQ�:¤¶Cÿ©¯aj7œ Õ~Ô%� A«ÃËíh•«õ*XMÛ3±æ‘mCGM‘Ö�¶õf&•Þ\éZW–jÆ¥äØ+_eJS8ØÔ8͉N ë�ž‚#±AýÈ;ã™§y"u² ©ìe1«ÙVp.žhµS)ð†× §%¯¹RKV”°Öµ°]«H½E[ÁÙ¶®·À,>ð*½Â´¯À.qqb\Ã&w¹‹mîPŸ¢èÒsº ©.?¯+ÕÍRµ³Vý,ϸ#^ {·¼.Òyƒ©Q³r­Çi{eûÞ¸žt®ó­ï}óSoò7°7lN {\ä"ö§Ìõˆs‹ Ý£J7@÷lðSÌŠ©–¨ªÞÿºª¥B›a(sXÊÞ 0ų¬³š"[>›zxÜ7VÊy,Æì§Ró±µ|CÍ}½špùó_ÿ ™ ° ³aç÷ÓiäY!£i3Á–U@:­yžFeë»§@c¨A^&0¤î1Þì@9ÊS¦´v¼ceaæ)Ë[ÎD—ãòåÝ„9HÎ[V}Í|fà¥yÍ2í³3 gGÈYt†…�ù'BïY2­þs =è5;>ä åcŒê«µÐ€¾èë©é˳ äìÓ¾ìã>Yð¾3?·?Â(?óô›•õc¿�x?øCŠù›Á°ZÖó ×Ë¿~нþAdr Ük?žŠºD/nHÀó >tÀ,Œd‹ ¬@ ,éËÀ)„Œô@ÁÝ ?N‚ $¿ó›‘ôkÁ]Bl£ø£Aÿ7D-´?Ä¿”пò‘=ÚóAŠ B!Â�è½ï‡C0òp–ÆpÂ'ô†™I+äK®å«>þ¸'üÀ �·MÜDä+Ãâh4LC6ª‡6|CSÄ”ú»¿$±CþËCKüÁràÃÑ#À?¬ ıøCd D|ÂEœ¹Fì©Gd¾Hü�I”ƒ.´Ä/t‹MäDóD&ʈPBž`C9D�HD(œFÄ1G”@H IœÄdÌ�ïÃDflÆpPÂFLÒŒkp ‰äI€È� ÊxJ™1KŒ(£T?rôk<Š¥,Ì…»Á®ÈÁ:„ÊVô?ŒÂqìCZÄJtÄ´Õ²áðJsk@” Cþ KpI±G <'µ·`KÉpË·¼�¸”KrÈD€D>¼ÔË¿áËv˜ÆQLJÃìMˆLL:D ÿoÄCǤÊȜūüÈÒJ‘ÄL’lÇÅãL¼ðÌÐMÑDKÓ|>ÀXK:kËiM×,ØŒÍlFÚÊ !ÊÛÐM…äÍÞ,ÌßÌÅNƬÈâG� Ì„èH匊�4:®ä͇“œÎÝÙ)ëÄMìä�Ód‹·PÍÃ`Í·t–ñ”MóıÚLϽ¼�õDCýt?÷|O¥ŒÏùä†á”JÛƒÌü”ÌäÌJÉÙJçìJè4IéKÂHP�8)´>*´Â¿àNXðÎ×O …M uÆãÊÐ#POÍ`O¤dH]Ê ™Cm ´@ÈÒ@È.å4™˜Kn—j|¿Òòçy‘+´4XÓÿ4ˆ…XP ÆðšƒÑ‹ë¶².|`I`SD‹0±P±¢ÂK7�…ÔÈ�¯‰|©‰·°ºâ‹¤Õ‘1Õ=  K½T4’¢¨¥|¿‰RÜRà¬R±HS-ÝÒ.ݲ/õÇrà¦Gù‘2ÝŠ3�4­6mÓ7E‹Æ�Sƒ¡S]»SËS–äSîóÓ¹ÜÄ@��A ÊB=TüHT°YTšhÔè|Ôü‰ÔI-ÇJ½TKÍTMåT�(-P-LQ•Ï’°Ò~ÂR-åÒðÒ˜ÓmzU‰U­˜ÕߨÕ[uS8e ^•_m9`52aÝÓ5íSTøÓòLVùXÖxhV�@Tý‰ÖRaT·pÔÿsƒÔÕÉVŽ níVÒTvW…×qUÊr5 tÅuÍRvuWw€W$�WJA=3}4MW5eS}ÕÕ8íš9Í‹: XÒSb•ceUd%A…'BuSgÝhí+Š-‹U³ÑÀÖRBŽíXo•5ú° [’-Ù†<Ùs-Uœ=Õ–UÕweUWÅ™y¥YYµYZÅY[ÕÙ\u’ž‡Ÿí† U&<%Ú‚-Öƒ=VMTØj`X‡•ˆ•¤¾j˜©­Úo¸ÚŒÍZJ�;ëèÚ¢øÚ°Û±%[l4[RÝS]×TÍ„U%ÏV�W¸�Y 3Âz¥Û{µÛ|ÍÛ]õÙ^Ú_Ü`Ü40Xÿ„¥Ëp@\ÅuÚ‡}Öˆ•Úi­Øj=7ÊÍ�ÝO¡¨ÍÝTê\ÏE=Ð-[ÄDY´UÙ:PÛÓ�—·x[Vúøµ2Ê†š­–›ß»]Ó�Õ[~Å]ÕÝ–sªÀÖÁ5ÚÂEÚÃUZe%*x*ÔBý“¨��mÙœ\Éà �ÕÚ ¨”Ù¸` ÆÞøÜí}CÑMÙ•EÕvÝ2òu óÕô¥Zße±W“ÀW¼Ý×µè×½<ýí]þý] ޤ]Z6`7EàäUàNŽÊªá„ˆà�€Õ Ñ Î`ìåà¦ÁþÞ^ÛL(áÕ�Ù/Ja¤Xa2jaÙ}aÚ�až­_¾Í]ÿ¿ÕµXß^Ã^^X~ Ž!v\o*b#>â5ö%ö&¶'~âÐ`)žâù«bÒM[Óá,ž•òeÝóõHc 7¨zß@«]&Æ_¾á¡Ía8`9öa¢ºã&?þc…Ù ¨e[ä¥(ä'FdíUdîÞ³mdð_HÖâ^žÁd¯ÐdêX€aùµÝ½íÛ:mãR&Xö_`U.` ne™zešˆeÖT[¾åôÍåœ1äCŽâ^öe*æÑ-]–_I6aJFaKVaðaa©ƒ*g†f\ýdqeYn*Rî§7Þá8&Þ:få-I`°gÿXöãr–Žs®e\V ]†âÎMdxN8Ëô§!(i)8éHi•®§iàÂhÅ1”ÿ$c¨ú”¸iœ.i�‚˜«-øiÜIêgèb}è Ä–¸UÂý_@5½à·yPi•¾cÓ1�H�Gy8Òà�þjLé~Òé“–ªNi–&—& ˜N™fÎÙ­iòÀiº®ëžþi-ê¼bÕ¡Æ�¢®d¤^L¥^ ¦ö_§NX¨Î ©>ë°ê«Ž„¬~àÖ…R°®ìsk| k”>ë´^kohë|xë­[¹Žº>í¸k æ>¡&j£lúl(ì´hèĶS~clǾêÈ> ÿ™¥lËîKÁlÍ6kÎNª–fÀ—Þ�˜.”™. Äc Ô®kÛÂk½Æ/¾vmÀΆ¤^jb­mT>�¨Îí³Þm¬^­žlÂnöíâfìÎVn¶fn·vn¸¦i²ééÆéê^mYhm¿~mîlï\ðVݤ%$¶Ýâ­Š¨„JoùÔö¾pî n“Þlªžïâ[îžhîxnmˆî•èoÿž+ëfí½Vݾþk}†mí§×ájå„xpŽp §ðæ°p r¦ŒÃ¢ìøNé�së‹ Òç!ñ1䃨r+Gñ›þï¼fqìvqíŽñ�íojÛÎqY!ÿì¹c�( O�!r8� Cò 7îXòäþ'7ê(Ïï’˜r+¿r,×òëžË'ðî&ìï>Zop8Êè Xs… ]êÏ8‡ó9‡ï:Wi•æ4ׇùà ¶Ú _XŽ[]S¤ “ܸwÛú“îšžïÔzЇ­X–)w­~Þ[o™ßúî¡ù0þޛϾœ'a"âyùðyeú=z'�¢Oƒ£�¤7õ¥ß’¦7ûjÓ¨Ÿú<©úŽºzAIa®üÇñúLû•Àù”Öù²z�øù 'í¡¯q£?¤ç ¥Ÿ+¦e§?{¨—z­ ú1´zÄzÁ'|Ô/Ã_fÄçÅ/Ƈ¤ÎÏû�€üµ—ü¶'ú¢�ûÿÉ�:~‡º?‘»w|¸ÚûÐïûÑÿûÒü}N}ç¿”Õ {9ûH–}¼GûyP{¶Ç‡SÍÒ·ç}ÞÚ«ßþü~ÏÌ6ý¬}t­@~ò˜~ú§ŠèφéO|±_|²rÉ�+Xí ½„ ç1ÜãPĈø&R dñbšŒQqì8p ’�"ß‘,ùá$Ê}*WŠkYpÜÁj Ö«©oNœÛvòäãó§© BÙ-:ó¨B}J1àô)Ô¨R§R­jõ*Ö¬Z·ríêõ+ذb¥æÌf–'Ojå°-à6\wr¾|éí.^†zçE”HqâEŒ3vôø‘œÈ‘%IÿvkŒn&–. "DšðfÎR;pî,thQ¢–�2-=h,êÔªW³níú5ײgÑnSË�­· ËuG·î8¼y÷òí«í/àÀ�.Œê0âÄH3v|²dq/c޶‡9çæÎœí�/š¨ƒôꑚn û=üøòçÓÏ*;íÚkÛ¾�;W pÁ ç qÅõ…>Ê-ÇœsÏ&ÝtÔ5ÖÍcpe·]e–}‡Sxâ•gÞyê­GZ{õ™x"Š)ªhÕ}ùÙ†›n¼ýGpH9êh�=*¸ �ABW‘EBHÝ;V™J-iG™L£m¨YTâ�÷¡ç±#bzíyyÚŠaŠ9ÿ&™cµHÛ‹üíæŸoÖ8`�:îØ#�? ä�Ey¤„Ö}€]““Á”!RSvØ–Y†Èå—%–ù(¤‘Bz&ZiæÖ_&½ýV—�qʉ�u*w'ž‡é¹§tH*y�…�>9h”fF%TVv�¨–\:Шi’úú+°óå„ ±ñ”£ÉбäŒ4ð,1ÅTÒ-ÕFp-¶Ì¥! ·Ý:ù-¸vJ\åš ºéˆÔ=íº›¼^0/õÚëe°ùê»ï{à ѱX(»,«™¶é&´ÑJ[ µÖb{­¶Ýz .ÅâÂI®¹å¦«.pìºÛ.¼ùÈ;/¿%›|rkþbcìNÈ*ËÿìÁÎB»0Ã$U{ËÃ3'1·W,ݸ{e¬ñÆà¬{ÔÇ ÇÛÕ¼ ü4ÔQÛ‡±+ܲÀ/ÜlA ÓÜ0Î9G̳ÏáJ‡T�C÷P´Ñ#�tÈ#;-5ÝuG­2ËÛ¸œ,Ìu=óÂ`çÁØ—ý-„hcœ1ÛGÏ”ô=q3M²Ý•[®/ÞWë�5ß[Çü÷³_ÛìðÃ…O|¸8‰•öÐ�»ý8ÜKsÕôåµÛ>)ÕÿjðÀ}ÿæuࣇ]:sÐQÜòÉw·Ðâæj©¥Çß>=õOg¾;Ö½{î÷8ÀK+xÎ+­Ý7囟¼òËÛ3ëj?{ŽV??ý¿^Ï»ÖúÇÿ½÷Ó ?¸øTB>ó•}ÈSßúfå¾÷…D½ª#8¦ûe/2â´L Á ‚ïaÜÇ hÀF �}ö²8|I°….¬7§=ý ƒÏÚ …÷Á†ð|,á¬NX¯%d!cá “¨Ä”åÎjØ“¡÷÷» âÐ`Ûa{XÀªÏ„B$";Œ/$.±ŒfL�q´ÁŠ5²ñ'?‘ã бŽy¸#Q×’pð±�Äø# è®ÒHÅKg8$"…H�32²‘¯I#ÛèF>ÄQŽÀ©#&3©IŠõÑ�€ü£ ÛEHG’²”+‚d$Y1IJVRsÔ$,1ÉÉN†ãÿ“ Tß ÝcÊ]òòDfùe6V™ƒa“m±<æðˆGZÖÒ–¡¼Ç({)Íi˜f&1‡iLdÂR™wd¦-‰ñÌhR³œæ‹5ƒ9Élj³hÜì¦7ÁéL\ŠR—ç¼'>³’Ξø„�9pÝ8ÞiÇxÒ2œ$c>ªÐ§ìs'?ñ'@JGoæ�™c>ºÐ�Þ³¡Ûx(;#*QŠZT}Õ(GS:M�‚4›"(Eˆ”“ÊO¥6•&KûÒ¢½D¢Éôæ3ß%F”Þ´¨�Ì) ÊÓ‚ø4¦ôüMhÔ©ö2�a¸*Vu£pµ«Ôø*X'4¡ ¶K‘M£UÓJM«bõªZÿuKW½ ֝е1d½‡TÎJ9µòu—lmë[ W®Î•®u½k^õÚ×ÅN“}�¬ K�ºv±Œ½l>ûVÈ"‘”E ^ç†ÙÑ–S³ZålgÏðYõ…–´®mì¬V ÛÙf ¶¶MílkÛø™¦µ¯ý­)Ù7[Úê6¸-n†+[/ù¸Îe¤p•‹ÜãW¹+`®bŸ«Ý2Fw¸ÓM-r­‹Ý³n·¼Iì.quK]ÝŠ·=Í5/|ë‡^Ù~·³áUîxÑßý:2´ïå/€,à¸À>0‚¬à3¸Á~0„#,á S¸Â¾0†3¬á s¸Ãþ0ˆC,⓸Ä&>1ÿŠS¬â³¸Å.~1Œc,ãÓ¸Æ6¾1Žs¬ãó¸Ç>þ1�ƒ,ä!¹ÈF>2’“¬ä%3¹ÉN~2”·RµªÙÊ¿Ù�2…§L¬*[Y¿X–°–±Áå.‹öËó˜»læ§ÍV"ó^לà6k9ÍV–ó‚éô•½][-º/�–Ó£ �hI—ÒÖ 4m�é?芨œ^¬§� j´ˆ:Ó¥®é©oÊ>[­š'R®s­¶Áiɺ±žê¬­Të�  Æ>ö®sÖkåþÚ¨Áϰ·Qìc;Ù[öp›]Tö¥1�uø6¸qÿƒjW{h¼>�¯µmSnw»/à·¸å@n(X[Øž­º×=«v»ûÝuˆ·¼É]ïkÝ[¶ùV)»ù­ ÿ;Þóxr•|œ£aN#‚ð‡›[Ù‹rÅ+¾Ð‹'ãþÞ¸À;~í�‡\ä %ù��£q‡“»7š:ŒÄAnð«°/ÌéL§Ë«s¿üeæâž·Í›%ܪ§åTé¹–.õ_ÝrC‡ˆÉß�rj'=fKOmÓw΢Yù|êR¯:ÔhÍhÚ0Üt=t 9w9j·t~hsë\ã:~ÿ{hM�vÝ=o"$F¢$N"%V¢%^"&f¢&n"'vâ�!ù,(*†üÿH° Áƒ*\Ȱ¡Ã‡#JœH±¢Å‚Š2j<ÄŠÇU CÎI’’ÉS(S:Z9©¥KZ0c ›IS•Í›rê´Â³gÈ�ƒBC´(I’C’*]šT”ӧ΢JEFu™Õ«¿²^Üʵ«×¯`Ê}¨qcÇ�?Wi’RJ•,]¶Œ)“æÌ›8uæìé3­P�E�®eJxÈS¨R£REv«Ö±�#KžL¹2ò9 šVíÚ¶oQ®t$w.]ZvïâU¥w/_+�ÿ fíœÂL;M¬¸jãeYYN¼¸ñã 1+ÒÌ9­mСG—žtuêÕ¬[¿†í÷/íÚƒ™2ÿO~€ùóyÒ«_üøcäðãËŸ_Q9s´?ŸŸŒWn¨ÿ¦& v­m [lÞÑfÛh£‘WÞyæ©·žo�Gß…fˆ¡}gAÑ™~nñGZixÝjØ�P¶-È #Ža„æÁÞoj¨ãŽ<Ž%À�fmö—Hkybdh§¼8â$‹•øŸ€7U!¥f÷ X ¢å–¶=âå—JÆÈÈŒÔh#…Ž ×ãšl¶ Ñ�©¢gGé ’JºÔ¤“PÚ$eTvØÜ*Xò±%—k} æ‹b’iæ�¾ç椔N §œC‚d›�x¾¨'UN†Ò§**¤• z¨–ß)êe˜1:ÿZ#¤iVjë­<^š™ ømz¤ˆÒµ´g‰£–蜪®Úª«°:(«„´Z•#®ÔV Ÿ®ËñꡦEþúVžÂ‚êd¡…F9å±™𥲴¹úH³Bø(šÒJjí½øJ†m•ƒúz'°ý ¹Xš (º¨ªk(»�¹ ¯Œ3ÎËŽöækñÅÁ §w,› ‡L’Ä”l²2(§|ËÊ,çàòËórÈ/¿\ÇÍ8öÉÎ<7q�b ôЮÝÞU'­´DÿرÇÍ òÈ¡™|rÊ(³ÜrÍ9Ä,µ\ç€sÎLñÜs¬?KôÐBíÊÑV--÷Ü 5-ÀÓ,5ÕoYÿ]2ÖYk}KØ^KöØ7ëlö'>Ë tŒl·m4ÜtWn¹Ýx{¡÷Ì|§ä71€+#øà\>óáˆ+nvãèÕènä¸ ÷2–×.·Ý‰ä®û‡k¡âûï‘/üç¡`üñ„üµmˆ×ᮘbê&Š�v¾¹ìVñ¢ýö¶w�1îºçÎûQ¿/|ðÄ~<ò¥6óˆ?½ƒÒSo¤õlc¿ÌöÜ{ïÿ½à ßøHR>ß�}~+Þú �Í�ˆTdùŠ4®’‘äÍ$+I+J0“wää]ÅÇ6f‡¤ÿõÍàñÓŸ(A *Lg"T/ Eæ2úТJ”šõ‚Ek†Qmv3Ÿ(§8AR‘ê�¤&0)-P �w&%žQuiŒê•{ ªa�ÄM›Ѐ”§õiÓŽÔ¡R«¨F=ª4“¶l6õ©4m©G§ƒU¬j•«^XO1ϱ´¬2=k`[ªÖ–ô“­9}+\{ÚÌê.¨�°+®ðúP½îµ5dH­jûzÑ¿j­R 'a ëÑÃÿ®�]UéWYšV1%ã·À�)%gŠ$ÆÚÔ²8ý§N7ËÙb6Í� í­HëPÓVµªM-k™êZAlT°âœ-mKjžuÞ6¥‚X)*(ë[àþV¸b .’ö‰\Ì*W³Ì%1�E%CÊf‡Á™Ö¤ž¹�¯}-¢ÛÉ®v·ë²¦Ò°óíhxK3^qÚV¸]• Ty>òôѽ¿ [|%[\úNâ²m]n~õ;LþjÆ¿p€wº£¤ØÀ8Y‚Ì`—i°îŠ­ Ä;Þ gxUn,#> bË·¦•=qrÝJãüî÷\ý á78ã*kÈÆ¯ÉqŽwœÝçàǯݥ¢„LdÚÿ½[J²X—ŒA'ÃÉ$Žp”QœY/oöÊËrø6².³ Ì|3ŽÉ¼Z®qâÑ�F³w;ù%6S¸ÂY-ïIQväCÉ9®s“¹6â§–ø¸R¶/•WÌ⸘#0Ê׺,Ýâ<Ñ=Q´�½àšA:ÒhÖc¥%,ÛKWøÍ¹õ4;<&»ϦÖóZSŒ_VÚT±ʬg\kâܺ5™»±®gÆk2„í×�–´°½di¹`:Ó0/†á¬¥O‡ºv†ökO½ç)«Øvµ[ÓþÄ_ÙÜ#_ó�ÂuÁð`8üá¶v¦rÂýÙ˜ùkfîƒÆ!�›¥XÑ„X5Ótªó¹Ñù+%ÃÿŽò1V~Yq§3«àIIösŠYØÜKºìe¯Ò¿î\àp"8–nð„/¼áwxÄ›9q¼=(7\�5ÞŽw<)é$SÚÔ3òÓ RŒµôVÊ]²òc´ü?/ïŒÌÙBs›ÏçäÑy?yÎAïýèz Ÿ5©)Ü ×EÒ•îm‰c&s|‡BÔO7õ�?úêX‘Ö·žž®Óåëù™#ÊÙ�겟=iOËÚç�šßü9—;Ýyhw¹â=ïBçß�x¤'}éÄlúÓ¿xš5¾ê�gJ+†Oü¬OžF²|L0O$KÒtì-ñ|?]s�Œ¾ôn‡ûxäÞŒÕûïî@×»ÿì…¢aÚ~ðÁÀý0•“íƒ÷~’Û¥ºÕ—BüâKþøÈçziFÁÿþ3Ÿ[ηy�`bÒ× ÔW}××v§—z:ç}­×Y¯{7~AQ~~wt‚7xêì§e|÷~`ó{ó§õ7|Æw|"·ýÇÿ· ˆ2}“P€s "¦÷v¨wª—=uçsÎd*_£w‰g�3ówç‡~„GÏÔ�ƒö�\C'‚ÁG%x‚“g&í±‚,Diñ‚1Èy*ÇrÓ‡vÕsV0s8˜};81±sÄz–óLB(5V„«b~ ×WMˆígp¶!…Rc †xˆa#UH‚Wxøÿ§…¿Á…£Ð‚`(vbHvdh€fˆ€iÈvk¸€äñ†s‡„�ò5wÈwF2H¸‡¿Ñ‡Lhxeˆ²1ˆLñ5‡ˆˆ\£ˆœ@%Ø X¨u�ؒ؂'‡2Hƒ›hƒ�Hz ¨ƒ"ŠÝGе“9u83©øt¶8ŸÐŠºÀ‡K8ÏdH´ø¶¸¸˜‹–:¼è‹�È ø—é±…\hŒš‡Œ—}™Xƒj׌ØŠnpøK?@'tÖxŠvØT²!i[Â�ÞŽéç#MFä˜; ¹*ç¨HБ©Žë8¼HD¿ŒdÂ}ô¸‚ö€ø8€�·�ËØ�j˜l�9Šÿ)‡©1z—�T‚Š ù©%‰� ˜SH©;y(™ù‘êÈŽŽÇ $ùŽ£�€’‘X�^˜y,y É“ w†7H“ÉÒJ<~q‚z·GjRÇ`ODSÁRvÇÐn Z á–ÛÑßAmѶä*†5#éƒ5/C|nçvb¢$°sF•&A‘ZG±%™Ð™�isb’2‹Q ¤Iu²Ñ<…Is”%NnSvWñpÒÔ–®‡-—÷"V—Ûu—p1"zÉ—³ù#~¹€ù‚I„™šV$&‰ !‹™2�9|Ÿ9 ‘ù"“iF•Y/¿p™ šIœé™Ÿÿš(3š¥©q§‰8©‰ƒ«N­¹r¯ép±¹#n©¶ÉsY3Sh—s´Qy隿їAõ—Á)�™ƒÉ빜1Òœçñœ(�­0�ÕÉ ×ù ÙéÛ¹+‡€™Pð�#ž™@¡1"šTAšµ`š�š©©g¬Y4º °M² �£ fn\“ŸM¤›¬eÅ%qñ›Z Ã©t(9*˜‡ÉY˜Djª :�ë‰$š¡ÁÁ�«à�d°™ZÒ™#:ž%Zž'zž}�žc“¥Pö¢®£3* 5ê\7Š96<G>ÚW@¤ÿ ŸEj£pZ†VIJ%KŠ Mÿú¤m¥ã1¥P¥Ê¢…©¥‘C™ÿd™ê¡ :"J¢b¢È€¢**–Zzíiï¹—V1§u:Lvƒ£<¶£¸I—ŒÇŸG¤I2¤1zªP‡ÚjÄd*‹ú`Ш šš�Ê’J©.C|©ªš(±¥›ª�^ ¦b*d*ªäAª¦Šž+ªž-ú¦î £‚*£òI£ôY †”§¶*¹™«»9ß%¤ ¢�éz¦â`†:c‘¨šq¬!‘¬[â¤LaBÍú¬ 8¨Ó¦åú°ÓVÿÔe¦"ŸJ¦ÝjsJ&o)Cu§ÓJ J‚U­ŸÙ# k!¯5Ó”[²Ÿõ ƒh.zÿ‰[¸Õ¯Mµm]`>9° fË*Av@ KRd¢—+GLÛ´‹3n*±‘C±Ì`±£­$¡±â9 »iX²?cã0/b²èêªê𲱨ֲµú²B™‡}ú@4;Y½š¯3Xv8ÛN:‹Q<Û³Yñ³‘£BÛ.®¢°�*©J{ Më´\3²˜Ê6TkµT‚±ašµZëv]»U" ¶b‹3dË f§é ‹kÛ¶áã²/³Zò5°T { ag·6«·{Û·Ûô·€+¸‡@¸k±,kf´‰‹´3²¸�Ë´O{3Q›K±”;~›¹;g‹2`ÛŸ{3¡;£+§á8HÚÿñ¨«;ªë2Û±�‹óº±;»�‚·7{»�â`ºÛ³¼ë»G¼)§dä.˜Ð¿þk¼Ç›¼u°¼(±¸“;cûÑ«±šK½^û±ž»ܸ½+ѽ¥û½óQ Û1¾¹S¾9p¾«Â�ê»·ì 0¾i»8‹»Ú4¿]V¿Aû»†¼Ì¥üë¿ý À�+À| ì¼|µ™y¹#¡µeʵ̹_ÁG1ÁÌR¶$u²¯ŠÁL� Q pÅXlH±°Å\ÜÅ[Ü<Í£:&TÕ�<ÈX=3]Ö œÝÙ\ÍÑÍàÑaýc#}Ö4ä6n£ÖæÄ}+ý§áÒ!×!D×v­ÊáSÓ\¬×uÀׯfaç�2ûØ_2Ø…ýÆ¿ÆZ¿Ü"¿HD$ëùØâÙ“m>çcÙ wÕÑ,5›ÝÙœÿýÙ^Ú`½Íb=ÖîXàL&ª]4fÒÉ®ýÚÔÛo­¶ALa7�1×ð|ÛWŒ$Ó9�HÒ<¾ínÄkÂÝÓ¶¬±‹±ëMØ�s o¬ÉÝWË�$Í]@²Ý mþk þáèÆ ] NÕ�$ÐìÌ€`ÞÍÙ¡cgVôß2îv^‚é=# ÞÞVÅ}½âÁÑhÒ‚ú�ÊVÄ«h9ã³€$%Ž îzà}ÆÖä ®2+á1á±KUJRãõçÜ#EPæfN&âÔáîá!>âM~â¡‘â‚ìãYÑâ�ðâ ãJþß`N|7!9^#TËãÙLç~6Bÿ.%D^Ûð|äHžƒ3Îä%þä-�U~íÓU^âWþàZ~aÓå õ塱ØÂ|f~æ3’æý»ælŽnn^âpþrΆnçxî^z¾çŸùè—\Ò©½Þ¡2èr×ãtî‰^‹>tíèH®ë’¾à”> –NË^ ™¾à›.:YîÆšñé{ëå/ÒçÃÇØ§^æhNj¾æm.Ðo~(NÈ*Nç¶80n?ºà�ΚÔàÁN±„þȆnì-&tÉ®;Ën?¼îì¡ÑäÑ>íú\í×Îàë�åÎíáí8 î "î­@îå~î¾ê¬¾î¼Üîtñî©ï>>ïXSïÔsﻞï$ÿ=ûìN"ì:Gì>.ð®Fð_EŽÅÌΫ ÿ R}MíSní«båÏéïé\êä$êoAêK½å^ Ÿî îêìëîçð>çòÞâ·\¹óK.ó¨=Cü~óþ>ì…^ìñ‡ea*gØ|³Ëöºn=S” eÃý;AnCU>íÓþéµ!Œð%Äw½nd ”_ùn£©nB2›}д ^bâ;$0ú$°=�ÍÙõÆlDNEs ®/òêTÙŠ2™Éà\Ì3V«—DïýI‰ÒÔ{~­fÝzµE‹ÉdÏvKÐ`ÿAˆBœH6°ŽÁ…OFYÜ8Ê•,]¶Œ)Óæóœ:y¥N�hÑ£I—b…•qÕ«X{måºókرw ª–íÚÚÎâʵZ7�ú¼{õúý8ÇàÂSl1Æ‹L²�*ëä2Í6ë쳦BM¯ÒNKÍ5 ù ˜Ùh«í6ÜrSh·…z“CáR܈¸ãZl19•.“ÑŠç ‹îFœºªnÇŸ¾3*)¥Äëî©ïÀsE¼^Ll¥«óÆ"ë.öqï½øæƒk.ûðC’¿¾üû�0B C±¿30²ÉdP3Î ð¬Ð\íÒ|2-5Õ2lmÃe‹ÄXDÑ'ˆ&› E9*ÿ‰E= Æf¼¬F›pÄQG3�ÅÇì�Ú®©!1)Rª¹�T’I„ÀrR½(§l«6+�ÁÒ®»LØ’K/ SÀ2 | Í-ÃŒÍáŒPÎ #©O=÷ü­ÏdþQЄHTÈÐ�MT£EArô[’”SDR)MäÜK»šNÓ 4q÷]N�ü”)uw•‘R™"e_%!R5=(¯ê‚ ~ËÊYí»¯Ö[ùËUL1ÉTl*‡Î„,MalóÍ8笳§;/löµgû”ö6jòI–[Æ–m…wæoÅ%—ÒUÎM$]uÙuè¹wáeìGíīדI ¯—}Iéw¡ÅbUàG 6ÿX XÎ’añ¸ãaˆÇpвAÊ2&ÖM™’�N í´µ‘I†�¼ó>Ù �u†OÔZv[ U1üpšŸÙfIqÖ™gL}:hMâ-«£“Æw馟V(ê'ÍŠ’(« >x>­i5ËÖ®qõ¯�°Åî•‘Š½8؇Ílã¶{yûc‡B¦»î óÖûCû>÷oÀgùåÂ7\qêe|FÇѽ1󕜨­/tg¡Úûâw¥úÐOKâ E�6ˆñ�lR©Ý�0–;�«cÉ¢šðò4²â=P‚T�‚*ˆÁ 6Ïyl U1B4𤄓2—ö¢Ã½êxÏ&”«ÜÐ:$öÌ'5Ôúz£¾Uµï:>Ä‚¨°!bňG|]ì”X¶Yœí‰kÚ��å1½TqnWlV�·Åv±2_c4ÈA2²ÆŒid%J\âX:§F0�%,sâTT+(Ž©D/+áµ÷¬ZHš [h‚A$S—@Á%.©$�m`¡¦#ì£ lÿÖB›ºàf29€Ë„ìEš l¹ pN¶ÄnNs:@;"#_úRFç¤'nqÏhŽí']9”ž& €fä�ÆËHI ÕJ„&T$¯Œ%LpFËZÞÒ1Ëü /} Ì`S<Å\Ë1/èMŠú¤™ŽyæBò9 j‚åšÙÜf7“ N„ˆslä4':×¢Îu^¢�xçeâÙËyÖÓžø�4÷¹“~fèŸÅÈ@óVP…FUª$a¨dùˆÚ'0=u,ÚKŒ¾G£XáhŒµ)e=kZ»ºK¶šE[\WZ×–æõ¥�©^Æ ÊšB!°ìN{j…ŸV"±ô\lc'ñØÈºf²•u*f5{Ý4rÖ¡”úlhCÚ“¯VC oy9BLÙs&ÈTæhE[ Ì+Ò¤ŸÂèjW¼ê•·§à«bü:#ÀÞT°95®a}ŠØËu¨Œ¥í€ ›-~ ”mªe­‹] Ó¬eÚ=ÄCQKÐnu¿^-­/Ç[^òžw£éíèz?ÚÞ×®µ™mMˆsë{[üºô›ûíobþ›ØáŠ©¸…íÉaã¹Üs6·ÁŠÿy0Ì"Ì‹ Sw Îp•µá–Ô²³5鮈EcÒšÖ5(NñFЛ õÖěތœÏ’ƒØøÆ ³«]× ã„üv‹Á¥'N×¹Ó÷$¹|>§sÛA$ºYž°E,Ë +GÚQXV„–·;ËGÔËß­�˜[Cfap„œ¬µÉ�9Ðf7ù ¨�Õœé\çZ˜"T ’ŒZ$šÈÙD¯}MháIF!6Ž–hA,šÑÁp´e7$ih»2Ë í0w3­Õ9p•Äžf ¨E JR«ùΨö™ªcÁj+¹Ú>°Žõ�g-°Z‹çÖÂ�®yê_ÿú¯BŵxŠm”c+ZOËfvÿEýìh'|$ö0ˆ½ë^ð–¸—'Fñ··nš˜šÜì27ºç£îº°[Ö ¡õ�lÍozcÅÞ?Éw¯�Ýo¬üÛØõB¶²Ýl§"\á g¸µ¾iˆwÚÄc&³Å%ˆñ™h|]nžEǃÙj�‹ÜÝ$‡·Éå�ò÷äZ×,oùËSÞ™<Ù_6Ϊó�G»ç˜þy¶G [n¯ÆÛ5‹ÍZêq/=Õ1ˆÇãò¬ýÅÞ¾)—P�½ý0 ðƒ¿nrà7tÆÌcxó\=ÎpúÑG¼ô×ê-«z6²Þõ­‡½lBûÚ ícŠÜÛ=Þó=¾¾>Ó ¾†0>û@¾äS†å;§æ’§€>�‘¾� >N¸>ìË>Ã î» ï ?ñk »1¿ß@¿ô»®õ«‚ö£”÷3�ø«�ù¯ú+¿Gcü+ýÛ¿þ‹¯ÿÀ0°=¢Â=ݳÞ3T@1`@JpÀY€Àº�Àä«@(¸@îÈÀºˆ¾…˜¾êA:ÁܾîÓµïCÁñ³?ÿf8¿Ä®œÁ©AÑ#)ÒÃ%ÓÃ7¨|Žýã¿нS0Â#À$lŠdÂü½^ >œ>‰(>½8>Z˜@ &æÓ çóÂ<C…Ã$C3D’4‹dC4;¼�Ã8Ô¬9Ì?÷=ÄCùÓCú;=L½"¢Ã@üƒ!´–„0D$v³Ê� Ç�ÇÄ¢züJÄ Ë¨K,˳ĉ´´EtI]ìJ†™ Â׳I"ÄÉdÒÉÙ+F$ÑË l9¿|Æ£ŒÆ¤œÆ¥”�ÂtJÄLLÿú‘ÊSÅÇœÀ«DŬTEË4Í7¬°ÔL…âL_ D´Ü-–”?ÒäÃzôJ¸Ä›øÅ¹ì‰„°KNÀËDe…fg}Ö&DõÿjkÅVmÍVníÖç0Äq×r]Žs]…t]×v�=“ x€yMŽWµWI˜Õ*}~ý2¥ €m�­¶U XƒÕQ¤,ÖcMÖemÖ…xÖH˜Xñ¨Ø‹�Œ˜�åØ�èV ýV# ÙNYšEI›8Ù}ÅU[DUU­V}ÙˆY{ýZ»ÙœMˆ��ŠžýYšZAMȽ0Ú…¥«†}؈Õ�&¬X¨¥Ÿj�T�ÝXŽ€”çà ®åR¯ÅײUR[v-[wí+xE[yUÛµ­W™u[›Í ”íסØÕ§èUnúÕs Ö¼ÝѽMØ£eؤ…Ø¥•XÞ#\õˆZŘÚë×ÿ‘ðÜÏœÇUÐÈ—ÉE×ÊÅY²�GÝ\ÙjYáeÛ{E^+x[ÒµÜ\=ÝMÝ€]Ý�mÝ‚}Ý¢•ݾŦ¿UZ…`ÚÁÕ]³àÝÄð]¢Þ´}YÇ-^ÍÙ’åþE¶t)T`Zÿ¥ò2(Ï¥^X6¸m^¹å^FèYÕÕÖ­Õñ=ÈAÕ ¾EZ‡eVTá/Ü $÷µXÛRªá5`µ½_ü%IýMÞUà_>ðßQ`ö1&/^‰ÅZ™•Î^æ½\�u`þ^ _ Ú nZóÕà‡í`öÍÝa…Á+¼*á—vžËÛš€a®~ÖÞ¢ÖâÿäØáníá&ƒÒâG [ïÝ"»� ¼µ`½Åà&¦Ý (þ`€ áú²bnÂbÏÍáyUá.ŽÃ/Æ1N´ÿ©NÕE6nŽn$/É�âžc©(bŸ_ Íã]â öã'6ˆk_B¦CÖDVÛL†Fnäôã ¯…äþ•ä¦d3¶a4ÆaªBÑMމN–”Oåí%å®ãž`×ÕcØåc±PX'æ`X³†�e÷=r.çZ¾å—Íez%^^ŽC_–\0¦‰H„In¦J&§4^8evP¬mæyf Ž[„ØYS¾ã _%Þc&ÞæÙõÛÚíàŸgÝ-gÿs6dtžWu†Y.n笪s© ÃÑDÊž(òÚ”Ni•NMšød—ö’nD¶Ð£Ž½(i¼)gC¤‰ÇÁ‰#èiÝÐÍÁÂDÔ2¢.jˆø¤NêûD‚ZF;Ž~êÄñèDi¡içõ‰š®c“•îê `é™xi±Î�˜N´™ЬÆ Êœ6B�v£ž>‚ŸæÑ ®Æ`*j£^ˆ¤Vêû¬e¨þk4’jª®'«Š´^ë:i¯Ni°^…±~鲄³6l½°ifhk|kšƒ¸žë½¨k‡|¼&ê£ÞëOXj¿lÕVÁ¾Ûª¾‘‘ÖMËÎÅFéÆ~lÜ&k2”iÓ éÿÊÖê›&眞‰�ælŸ^¤må»ëÑ.í½¦ßՎ6/øh×&lؾêž8ìÚꕎ˚ÈíÇŽìÉþ în¶n·&n¸>îA¡ëœjæÆk¯Îbé¾ïIc™ÖÆãsâ™ØæQËΈÚþjðniñkòîm´þmµîîà>†áΙö–käjÑ� ùíÑ®ïDÆooJ«%ëæo(ðoí&ià¾,ŒðÛ>pÈÞmdK´�kˆÙƼ¢½çˆk)ü®9!' ê ïjûþp"7‰‡¥?èO!Oøïó~ªçjÆ.ð°~ìtM×OŽld›ñY¨qf¸ñÙËñžÞqˆëqo†ÿÅ…Çå"oó“Øo%§§Â6oGlãaq*wl+¿ò:Èr�q.÷r01?2çY,rJóäXótvsH×çJCò©¾n9ÏnÊŽ/Çsð o/‰qa¾ò6i3uAôÏ›A/ôCÿ E%F_ GÇèH¯u8iL§sMOu¼át:üdSçó:uÎ(uPGõGïZu›ÐñƒäñœZô�€”YoÕZ·uêNr\�'¯s¿s)·í<vPvb/ct½ë Aç&oö1ö2�vXŸv5ò¿v7oKlzBS\­ðY й8ófPÖæ¨ 3†_לÅ%ªÁDÿÙX$ÜÜQ‡ &Uv(_Hèx¬ýX#„N}/ù™á÷†ò÷sxvx‚· ƒGø˜Px¡bxpøæ…x�‘ød xµø†ÀøÕx¼ÉˆŽ‡„�· Cù‘âˆU2y¨w”·ª¬U0–ÿ2µzyWˆyhHxåYø†·Ü‡wŒˆŸÀ‰7¢Šÿ ¡¢WqŽ÷x�Uú�_ˆ‘߈§�z¼G‰©÷V«x¬�1­çúæx°¿y±Ïy²ßy³ïy´ÿyµ‹Œ £‡ûÁ—{dúfrzÊ{Î7r–éwK_y¿wù¡(ø3—yo%qz²yœb�¿ž÷ùÞx|Gˆ|‚ˆ£OúšXúÿ…Øe¸ûÎþ½¯z¡ºzÒÓ÷qÔÏZÕ?'Ö?|×O|Ø_|٧‹‡ü¡—|ܧü-ã}…ð}àþ¨_‰áì8þ{‡Ðú¹€–å'üþÆ d³y¦šúúѳ/¢´×͵oûÉH‡\eð`˜„ 0l(à!D'ªªhq"ÆŒ7rìèñ#È�"G’,iò$ÊŽ½°xp”˜2‡Ð¬‰êNœ³v>êéê'ÐdB‡BƒFðÐKƒ2ç0äÔTTR§ö¬ú(֬ʶrêk(J”Z‘mµóì,Gj_±mÆìíÛer!ÑmØ0é*… í€1£Å‹).lø0âÄ'Wÿ¶DzPæÌš4oæ:iÞyC3(¡»…±!œÀ(ºè}÷©òQofJ:)¥7¢™æ*Ñä&pž5g$vÞ™žž{ò9‡Ÿ¤=èu„º¢Ó-Êh£Ëû¸¿Uq;îxqJ¬Ýx³;qè|c2<ñZRºÎ§žºê¼lð<ô­3þ¸˜jÓ~=ö‹ÙŽûíºË]Gï�ÿjð{_üß8®¼áÍ;ýóÒ+B½`±g?þÁÈÿ}÷Iq:løâ4¾9•ïjçžñ�·³<®}̓_ü¤G¿áX/¼ Jr”�< âϱâ3€’p&<á%R¨B(‘�„*Tá1b(Ãmƒ6¼a� ²ÁCtðƒP á‰Z(Ä!±ˆ/L¡ eˆÃ%2Q@:Ü`}Dµ±ŠVtá“Ã&r±‹ÊÑ ŸãCLÑW<#�x -Ën|£Ižx”(~°Œh¼#_(‰=òŽ~üc°C:‚ÐeAÄãÕÈÇ>²‘Ž”È "“1†ð,ˆ¼# ¹ÇGrò�½‘dc‹Q’>º$3©ÉN²Ò�Ÿä`(¡@ÊRÆæÿ”¨¢*ÙÊ]6ñ•<Œå,GiJÓ RÆÄ¥b¸.v�û‹írWº¥®¬‹Ýëj—»Ûõn@ÁK†õ²w¼äõ­yÏ‹^{öÆW¾Ú!{ÛëÞòšw¾ôå‹}s”ü®×½bàowý{Nù˜9$0 ̇ S8¾¿Pð‚¥×`üXž°…-ŒáV28Àίÿ‡?âøŽØ‹A…߆7˜ƒÓ¸Æ6¦±¡:¡ã[Xr ñ_Z,®C¯Áx¹1’mœãë¸Ç%²]„."?ÏÈII2–s°d&;™$Pnˆ”³šTZù%YNò–y_CêË󷨼�DйÎG>3ƒÒÜä5?ÙÍpÞ•œëlç+ã9:zîD—Gâæ7ÿ9W½±¤#-h:ß¹Æñ2ôn˜¼gó²Ù#‹n´£ùiIOºÒ4¾´d …ŒU³šž}þ²FD j=zÔV˜t"L=cT×DÕ¬^µ«½ìçŒÈzÖ’Ÿ­o]ê¤<‹×4A´£ýk`o«Óé xÀó¬l;ÅÂî36r�ÿmk\ã¥Ù§bP´¥=í`"ü«·±mn{»yà>ޏGMnf›»OÑI7´§� vsdü‹÷¼³]oÕÝû0õ p�ŸY‡‰SœAv³[‡L ñ�Ÿ�V�’󻟕ìgÊ„&?ùŠ9íц_À§³Ä)>q‹_Ü¿9Î;έZ�œÏ"9Ðe’rîFר·oÄc)ó™G§æ6Ç9ÔuŒnõœ{?:Ї¾Ý¢Ïúè¾Jz(ëÀdtE‡kP�º =~ŸªãënºÖ¹j¯³ìûŽÉ.³ŸýæR§ú˜á‡ë·þ9=^9Ë7Bw/Øý9x×±ÞkÂ÷¾küï<<ô_øÆÍþ¤‰çHC÷u˜ýñ�ˆ} ¾Æ‡ÿq¾ÒÈ—ý¦—_ûÏã^ºï೨ÿûëcŸ†½yw÷ýý·+ëÌo~FÊþç¤éëÔ�ŽûñümÐñÅRÂ�GÐÕß/4þM„þEßîñß©¨Ÿõ Î à¶¼ÿÄ_ã…R:ņŸýùX@!ù,(*˜üÿH° Áƒ*\Ȱ¡Ã‡#JœH±bÅ3ºÙX¦c„� ÈüCrŽÉ“RªÀ²e£—%bn›I3›Í›Ørê´Â³gŽŸ@A‚D´è´£Hß(eÄ´¥Ó§P™2GU§N‹X³jÝʵ«×¯`fÔÈÑ£Ð"Ã�üs¥Ê”P_6ŠY‚fÍ›6­æìéèϳŠEzTé©P?•Juœ^la#KžL¹²e°c1ntÓ± à´kÛš| ÷©\ºvgâÍ«—/O¿Ï &J¸ðÒ¦Šs3®ª÷²ïßÀƒ çš9ÀæÎŸG–Mš@\˜2S¯ÎöصØ9ÏT{šaĹïÿvÜ{¸ùóèÓû.~ܬPÐËÛ6>7&”ûø§Ww�]ûìîßá^TL5ö˜z&¨à‚±WVRD(ÅGð±%Z!RšS§Ù‡ß}úµÆlþ àmŒ ˜ØxR1’ƒ0Æ(£zrÖ‘„¢¥œ…me¨¡sOÑEׇ÷`ä‘ûñÕŸlÿÕÖ¢€¹ÉÕ‹R½8ã•XfY��áHᎢÍáã†- éá‡G"©‘P`·Ýv8Ä)ç“)>UÍ�xJÉ•LY©åŸ€Ú`fíyvV…aΤ™l¦iäclºù¦`rÎù$TxæùÒ”òf•  †*ª@+”jj¡É©E’�6çÈ«°šÿYB£ŽZÇ&Žng˜a•ÆI§7À›é�z0Þ�£&«ìŒ¦žú`ªk±úã[°ÆÊ(‘Ž`+‘¸J¡ë®oôŠÃ¯Á;l5Å[޲춛^³¥¢zèŽÒºZ­#²Òšæ¶vûí®â’[î¹évJÞ§î&¬ðd 4ìpG|ÈÄg»glÂÆâ1 §!òÈW”l²)(§ òÊdÜâòËÛ]#óÌ÷:B'.8ç\ÊÎ<Ãâ³\y-´œ„ ï ƒ$­tL7�ÏÓPGýôÂTW=�ÃG 1Å;zqÆsÜñÇ!�,²É'§Œ2Ë ¿ ól3Ó|ïÍ9ãÌsÏ?oúÑFÃÿ«ôÒM3-õàùXm¸ÂX7¬õÖ\bñl`‡-¶ ²²Ùg£}…Úk³í¶Ë1Ç}MÍt×}÷Î>ÃRlK|rôßI.8áQn;»‰/°x�;î5ä‘ï#üð•_޹æ›sÎvËŸ‡7éOÖm÷驯ÎRë¯Ã.{´×~û÷¢æ®Íøäscþùè›?�:ì·?<ñd“�yâÔo¿¸ç~~‹órW+Ëÿä€xºRTOoNiÝ ÈÀ 8ð�öˆ 'ÁÁ�ï‚‚ùÆ—¾rc}ícßû„W¼²™Í~÷ëUþnÑþɬ0Œ!8@ ‚$À›êȺ8� làÿHÁ"ÚÂLb–¦³Az} á÷Q¹Ê¡âŠXDaýð7,—µn¢‹¡ g(‹ �DÑ¡õ À ž`ˆD4¢¡¦Ä:Έ‰M|"WBްŠÃbµÈÅLyñ$ÛiŽaHÆ2š�‚P#¯çâ¹ñ�p”ã§fÇN.�Ôãù¢è¾?R�WÔ¢8 ‰§CÎa³±—ÿÈhFð€�€JƒÇ h²ˆtô¤E¦3†点eùDùA>öqŠ€ü*Q¡JVÞÉ•·x†6·)KX5²–·Ì[.÷VI º±—¿¤`0…é�d/È"Hq@ÏzÚ“žÇ<ÏcÞ ÿO½¸/MÔ3›‰—>ªš§De5UØEš$›ÛÔf7_õM3†s‡ãL`9/‰ÎtJp�ìdÈ?ùÏ�Ìóž(ͧyöÉOÖXe¤6 è@IéÇ÷Esš ­Ô OшNÔ­áE׸K!Ñ£ådH ÓlÈ”™¹œ9¦JÕî�4,MU¦E9�Ôl` +ÇJÖ±ŠîX\¤ÝÁÖ¶Nñp�+1æJ×r«xÍ«\ä"®høõ¯�¬`@ØÂ¦.¯ÒH¬b¥b¿áiá±—Ô‡d'ëÑ{XV˜]êAšúTQFUjT­ªU ǰĵ4¦ydfWSV±–õµgM«ZaØV·ÿŽ0®r¥ë\íê�¼êu¯�èë_ý*ØÁ–°‡Å«bË”Æ ï±Zˆìd%[ÙËfV³álj=›8©†Ö£%­d²ºšÎêqµvi-X_ [ÑÉv¶µeë[qû ÝîÖ®¾Å+pƒÛ«á·¸�8.r}†ØåJƒ±õs,dÝ8]ê¦Ó²÷À¬*°›]Ó–w»zülÔ¾kŽK"q¼né@;ˆ^š¨ì-kl¯8[ÚÆw¾¸µ/1x›ßnìW¸Ãp€œÜnøÀÍMðsÄ룺¾.…ÒÔ§/wˆ²”/éa©Q¦ÉNÖc¶–]è6²½q{¯ZãëÇ•·4Îï�ûë_ Xÿ=þ1‚Å¡àè2¸ÁH–ð’¯â›dù|P–r”©ìÆGËîà–ÙÖåÇ~YÅîeq‹Élf¸¢¿j.Ž à7ÇÙÀs®³t§›g%kV'ÓI4úhb‡V»ZЃ&4¥ µŒpE«Uuú†Àë^/še�ÖB#[Llø¾x„5N³o#ªÍ5ãàe숶´Û@íjãÚØ®±bËÁmU›�®ž,„5 a ë™Â¨^�®ÍÇjW·Ö�õ¬£\kŒÜú¡\÷ùzíkGq¹ÑÃ.ölÉAð‚“ÂN6¦—ÍlgC[ÚÑ®¶µ±}mm'–Ûåðv£ÁÝjq[–ÜÖ5÷’Ó�}·ÛÝðÿ–÷iý4[o×úÞ7¿‡ðë•;à_dÁ _„[Váåª1³Ÿáp—A<âoÅ+žßmw[‹ß^`¸%;n9–ÛÜFwNR½î“¿Ö*?Ëóáò‰h7ßÞÎÌiîoFœŒ9WëÎ �ºÛÝç÷z°„ÞpMÇéáOºÒ—nqi`\ã]æ¸<~�'YäàË]E9~ÚI_z1 x¨o\ê§úÇ­òsOò뢼Mfzynx}ó‚»çíM‘Ðo5ËjŸ¹éÉ€úª~õsw}ÿÝñûÞΞٵÿ»Ñ�.xÝóþé(Œú ¦®�ªñê�oòc®‹Ò«Ö€èUéP€h—¤yvp ؀Ȁ4�(R‰óæe>åU¯µk�<œc u‚"8‚!H_ß@fj%*¸‚gU.ø‚¥ly%-¬7E:8˜ƒ©“:¼5 >øƒ¬‡E#stìð‚0˜N Ø4 ³ü·uͧG(€H€X€èF ø€Zx8� Á„9q�Ü��©±�øÈ9$¸†u`‚(¸H+È‚¢c„.ƒ 7ƒ¬Rƒ#tƒ9ˆƒ;è3=øƒ>„W4„GG‡õàQIÈ4KX�Mÿ¨|Ù0PQ(…TX…WDY¸…Ø…H�Xc�†�M¤�eu†h¨9Ȇ$è†ñ•‚q(-H‡vtùEƒsgƒÖ‡~ø‡�(ˆ„ˆ †qˆ¨ˆ ¨„î†Øs˜gR8…©Q…H„ ¨yšè€*•¹ÓA¹†�Ú8ŠeXVc_©¨Š"ÈŠµåŠqxV³xiÞîøŽÅzȇ}X~ªô‹Á(mÈ„ÅȈÇèˆV¡ŒÎ—ˆŽ+(�XH�ÕȀ׈þw>Û8†Ý¸A^õŠò޵5Žä؆ôõ†bd‘ê˜Nì,ï�}$�œC�9h�Z„�"C„ûøK‹˜�ø‰z!�^ÿU�pøŠ‰‰ ¹� yÉ�9‘äS‘¯ˆ‘m¥‘ähŽm¥VÃ#‡q³Ž—V’î�s7�¹¨‹,‰B.™0)‹üxÆØ.!�ʘ“œc�*Ø“ŠçjšÔ€AiC)‘Pdh©”l¥JY‚ÙŠ‹´õ#•HAì˜WVXIã•�€’™ƒÙ–_ÁB ˜y�s'„/mt„H5“ÉrZ‘¨Œ’yšXÐ;:ù‘›g”µYy胗M¤›¼™”¾_À9‚Â9,Ä™ž†y˜ËÙ Íy’÷œj#XÒ‰ƒ•Y�À‚™´ JÙYˆ�ÉŸY‡‡)š€Ÿï¤j'Vž©Ù8«C¹žp›r$—³YZšóIŸäcŸ#Ô›k¥ŸZ¤{ý™)ÿÉšé(3É9 B‡ )£ “É Ô™WÖ¡ØùŠÚ)mšˆÚ�4¹¡z1ž‰ö¡åyžjÖò`¢C„¢F¤¢cA›Wú„¢£Ú £ïC£1ô›7ºt9Š'¼ vz§ é£Ä‡p@j•Î)<�¹ €Ð Jú ×‰B Œ¥Éÿ©¡Ò¢u9PZŠš\š2^ ¦$¦ED¦Ÿ'-j”ôɦQ‰Ÿ5Z[ª„£sZ uz§vš§×àxÖ§%ù§û¨G:¨IŠWK*¡NJ¡Ûi¡Ý‰¡¡I¥WÒÆz¬‘ÊL'¶˜-»ð¬Ð:Mjµ ÔZ­lp­Ø&# ,!(…¹³à®Íh ’øŒÐ¨Jà�®ê*ws×ôð®ºWDÛê Îà Ëøš¯&ØüÚ¯½„ˆ¼õ‡° ›ëP°k‘ó³vkWrq§j•¯ùš-F–œI%^Åz¬Æš¬¢´¬³Ñ¬Ž­ÑŠJÓZ­ÔŠ­Ù*óÚ­ø­á ®ãZ®v¡›èª®éÊ®;ÿç®ðºtòº­õz¯ ûÚ¯üú¯t°H°[°‹9 [´ û»H? ‹g{DJu±«±zı‚á±i²Ï*­‹D²%k²l ­Ûª²Ȳ-û²ÌT‰8³4k³‡³ô¯4¯=«XS´BK´Fh´;ˆ´I»´fÓ´ƒû´�µb4µUKjW{U2‚±Æº<óÓ-kçµE¶G"¶» 4B¤[º¥ç(aÂ&G°º¬Ë¶Öà¶áŠÖñf^E'ûE³éúcP�·º§cË&}›XPa‚(ÕKó“-»_t‚¸#£¸/h»Pk§¢4S›;Å�uØ›½”‹ ^нÞKàÿ¾˜‹9š;s'6µžk$ ;½yPº¦«}Ž‚ªËº«ëº¹Ó;²ëo澤 ½{¥{ºûxˉ4à»l¼öªXÃK_Å GÇë(É \ËûŠ ;sàrOÒ°Ò;½Õ›8×›½ ŒYÛ«Þû½á ¾ãk6åËoçû³ékЪXìË¿ápºi"¿DB¿õ[Þš8ø ³+`4ì¿rÀ¶»Tñ®ô@ÀÌ2¼\ Œ[ ½I^¯LÞäù5—€åRNåbå&RY> [ ]Î_ aþc^æfþ nFj¾æf;á�óæp®‹r®á>9v"žFzŽ™&.6(.3*Þ²€!‚þ„nì†îˆNŠnŒînŽN�N’.º”Ž[–n_Gžé›¾ä5æéêõÝ8÷�9ùmêô¥åóßà&1àÃPàsàf;ë´Žæ¶~ëlN¿nþæqþëÁ.6Ã^ì‘tì´�ì³ì×ÐìáúìRí90í_í-qíÙ^ÛîjÝþíá.4ξå®[çžäé~ëÿ¾¢áãÃJílòfè %*©¾ê­þêoO²¦Xë5tëžpð¬»Ü<�áŠâúóðxn쥰çÊÞçÌþç^àâiãG ã¥ò6Nº8®ãôÄã˜ãã!äÚ$ä“ÃòEn_ˆÈaGSì®%÷{ó@‘ó¶óuÒó-ñóùîåûæý.æÿNæf{ôŸôŸë:ìôVõ¤S�3!^õõÈÎç8àçÎÞõ�þõƒö…®X5>"�ö öfÃöuàöÏ÷b#÷•"cuÿ]w�÷e:*{¯ÜÅM$:Î-"øNAøŸ ïsÀïþ¾1E_­Ž?‚�ÑJ�àXÔôKÍ–ÿÿ˜ÿ9´"öž?ñ /úOúÐnúÒŽúÔ®ú‡nö‰¾°?2ËCû¶Ï1¸/'ºO‡v+ PÐàÁ‚.dØÐáCˆ%Nt¸ÀâÅC5æàØÊG� DŽ|SÒ$#”)¬dÙÒ%K1#ÍüT“ÃÍ99aí6¬ÑÏF1c:r´ÉèÑ?I•ÖaÚtÜS¨)S¥êÕÕ#Y;v´ÒÕ+ °a Œ%ûòÖY´ A0 È­ RqiÍ *Ô¼×ônÛз¯/RKI“fkÖ·pKIc,­‘Ëp‘éMÎ61ÁeÌì4o&ÓÙ3!ÐÏDW#]ÚnÌ<©Uãe�ƒØkØõdÏ6WÛöÿÀ�u ØÛ÷oà /bÔ˜q+GµG’4YR*Ê—Ñ] �©æ§›rÎÙ «'кC‹5ªtiS¦P£>¯Jô*ª¬GŽçðú5,X²e]¢M›œmâ¸J™‹–ðbbM¯køòkÀ#̰Ž{+®ÆƒL2Ê,Ãì²Í8ó¬3Ðí™ÒL;MµÕZs ¶×f£Í¶Úp#h·ƒ‚³ñFÓÑ‹âŒ;.1·–©9çž“îȨ£É&œtâÉ' ì"мòÌûƒÈ7Ô{ê9FÚ³ +­Ž«¯«ûðË�³ø»%9(þ›P.ºN;p¯ l°Â;ÀÅ{¬¥È™ŒžÊ$Ú�ÃÙùÿÄÐF+±šÓL@15WdÑEÙ`ŒQFkÄñSPªÓÎ{ R,¹DR:%­cR;'½ƒò')Ù0+¯$RËq¸ôò½øæÓ $’UöLPÍ5ýkëMã´kÎëlO9’Ð- ý¼PÐ =4QE qÄG«ï§Ió°g^zó±÷^LëÑÔWèÔ P¾qÔ]yìU WmÕÈW_Šõºì¶ëî»(…"ªà^±VØöˆ s«c•]öLgç‚–M7Á…“@9ó¢sÁmË3Â=߬ðO–´ÐˆMÝEÉX×Ñßm$^zë½×Þ|÷í÷ß„–Ú·ƒ‚ÿBG¯è £®».@£·Fºcle#�´Ýv�fñµ  Ðè—¦‘{î¹¡Š ÉH�~ï=*7Iµ'À‡1;¦B ¯âpÄ S<�TK¦¥BÆTCpTe^œq ‡{%­ñüs‡t³ctÒÑeãtÔûQ}uÖUOúuzU‘}vݦ¶ýöÐ ²ë®´öºk°ƒiì;Ê\(´U{í¶Ý.eó–è–Þîpð>Mï½QéûïÀ¼ðBOüòÆK†\Éõ¢¼òË1OLówYêüsÏ)"½ôDQO½uþaäâN€ŒHÕ®˜¬míw_ËH؆G¶dyÉ+ÍòXÔ<·A�%Ò£õ¬gÿìím{@êž÷Ì>ñ®}åsÖùÒw�õ9h…™+ôæG?ûÝÏ¦Óø×¿×0€$" È;+øn�ÁSÕ‹A š€‚|×Úˆ�Á·ÅÏ%¬ÛSîv¤¼i±%#LL �‡Â¶/kd#z˜âÂÔL®N•{ÐâX8 ê…~õ õ÷ÃÖùOˆƒ(b!xDöN�¿c¢Ø ˆ„(JñQc d%=pILZ1hlᤜWŠ—p©‹ãø"¬®'F–ô­“láD+]yFÃ¥ñrll£á˜ÁC—»ÄF/}Ù¾¦*�ר£5l¤›ú�«d3 iHhJ ‘^Hàxÿ*€xÊ’ÊàÚUIKbò’V,QgVéIç…ò9£,etž—¨r•®|å÷b)>5Ò2n¬Ã-s¹K]úò—— &�†YÌc"$™Ëd¦3…Mˆ†jšÕ\b…§ÍGvÓlßçÄ9ε•“ çüdcXÂ%`µÓa§ñFK�r¤£œ“ž­ÜñL‚8äTqúܧ]Ù˜x4 ÅFŒª¸‚&¦;/•肵øÌg}hD­šÐ‚ì.‘I\¤×éDn¦dpùê¨G?z´¦U¤$užIW‚R-©Ô%íj©7˜�˜Îs¦5ÜM—SìTŸüüiä&%Txµ¨G-LRß²ÔŸÉÿ©À�ªTEÕ!^U³½™¨"­ùUŒ>’Q$kG?ê�´¦u“«,)cNúœ”VïHtuid¥“×NΔ|5›_«XÁÒ’°­êa…ªX£–©¿Kdqö’Éþ¦²–Å fÿ·YìN¤³\ý¬E›ZãI°´à%®a|\¢&w¹^kîNRì’èR�Á N€uŸa$`Â]ÿž…Á E»hSe-¯yAÌ¿¶q•íJNü¨ºþxŒ+έ}Møâüþu¿iè/�ÿkcÕ8Ç6° ÜTKwÈ 6r’ýÜ«Á+ƒ ƒD+ë%FƒF£ ²¯3DZÒýlrZ†AÓÙqewЇ¢@Š5&žT4Lí™”)¦OÒà˜#®c Xsº•àû´jˆG<|äZ×Jñ̵F‡·„p8Í7Œ}l,$[ÙÜJÃ9©U8ð„:2& òŸ­­Ù@Z0…þ��E»„ÑŽŽCtCéœZÓlÔtdÍ OO*R£ör©OmÎi©lÕ‘¢Ê«c}WÒzR•Òõÿ®“Òëßý:Ø`öi¼¤ìe[®[yv!Àƒæ7TûÚ�f¶»Bè�ú-ßwKÆ €5äÜ2ª´Q/�éM¼•ñFѼñBj™:¨Î·ªÃo¢øÛï8Š^p|ðº3¾ÖÚÂÑð\UâÉf¶¡íŠÙ…Úyæx× éq+€ "w É“µèw5åå^T[^†—³;æèôNj�›ãçªÑ9Ïù´o‡½&°ºÌ9QôµéI?øÒÞt·»'ÄŽ:U¦Ž…ªw[ÕXÇÕi¶nL¯‡¾�`;Ùav$ §ƒ:‹i�Ë›>ŠÓ7Î+�˜ø¼í{@©ñ‹ca®èŠ·˜‘?“û WªôûØc¿˜=ë=¼;�—P \XÁÕâ=ƺßûÂã¿B(¾ãÓµ ©3ÉÊ+@©“>‰³º¸X@ŒË>7¤8ä19t>„>¢8À Ô¼«³¸=l@ìãº?œÅˆD¯D'4D(DÄ)TÄÖk»ôsÄõƒDÚ›DÛ«Dœ[AL,Ãû i€ÁN ¸þ3ºP$�QìšT™CTtÄÂÃÐÃÎÓºX=Z,Gˆ°Å®ÀÅB„C™Dl%dÄN Ab”DøC»HÁÔPÆLÔ·M¬Ãh¾ô¿ÖxÃEÑ„LÈl4E:4/éÆU¤>tÅpäÃq4GÿŒtt´u´‚'œ†(|GNˆG`lÄG”»HìB̃HÑÇ<àGftÁgLCà+ê´ÎtœÊE©Jít‰ÎôÎÏO-¤¥ñl’Ó¼G1O²@OµTO}cÏÙtO]ŠË¬˜Ë�¨Ë»ªÏ¼¼Ï¹ÉÏýŠþ ”ÿlŸå<‚�‡u†èLЦDˆ§ŒÊ½ÌÍLpÓ@–˜Ðï ÍðüʰÔÐòt ³´ QØ\OÙŒ Úvƒ?Æ×@fâAvâé0ä(Fäö©bþÄG^~d-^ጵafÑ+f+Ød‰ü;efcf4gÖ4hf‹¶c!æ"Ve>>b?Nb@^â&¶� çZ&çË1gEçÿ˜ÈâuÞ[¥ ˜w†ç�ÃŒ‚‰azYð1šÓXceicßHÞ}ƒ+3€2åj^à˜8¶Èeåƒv儆eYN‡¶åöñŒÆdätd à]v^DŽf�Þ�>æéLcFH^”~ˆª‚sZé–~i€>e�NåH¡éÈmåìÕ4…þf†.dØ¥dúéÎh̺ª«x¡ÝºÕ»¾k£ÆèvNêK^êij樦Ȧꉸê¬Þç­þ˜Fek6±²þÜv;ëXç†^k]jëËjƌ떚kº¾k¼Ü£Þh¾^Z¿ÖÀîˆÁ&i»˜jÇ­jÝ@ìUÒjfì$®žæ€èÿ°6¶šžìWöæËNëYvhÎ^ÏvÐöØ¡ën m»Îë¡ÍèÔVíËøè¦ví¤x‹‘~—’6ly,Ûî$Üþ�sÚmjvl™6�ÈÎæm~Ín^è'Fîrk2€kÐ~îÑ–nêŽXë¾no]mÀhmÁîn·ønë Ù¦ZÚFˆòæ¤óæ9Ýf쮎éÁyoƒÖf„æfËÞiZNnÅYîææoÚ•n}øoˆ p?Õÿy;Á %Ï0Íé‰+މ±¨Šˆ\Ã5žº4 Â#<[&ÍÈŠíØ^yE@_ŠXÀ)Ÿòùà'1�xù<²ƒèr/ÿò.çgñ¿îÏÂÿg£×І7�÷¥à šr!rS(rÒDòœPò7'ï%(Ï©)§òã°r�ÅòIÑrsH?.sJŽ3Æ2Hó5ZóCmó7�ó^šó‹¨óE¹ó ×ó=Gd#÷ó9t&tl(t8t)¯r7ºògÈòqÜòHóI¯t`ŸˆKO.M�NOò¸°ñ]Æñ;Ðñ†¨iRÿSrTçs°duWOã&׋'‡Ø(§u[G\×u¥´Ýh&þâ`_wˆv£*öcÿódwóe‡óf—ógçñpµs}Âó<rk?ò#@öj ô»€uY§õ÷¦÷FÇs¤ÿt¯dv¯x†p÷L—ï Ÿ÷O¿÷PÏw:ß÷Rïw<¯vUïó�—÷‚un'to7tpOô[_ô\ør�x!šøˆµxŸŒ‡wŽgs�¯wPÇQ·ˆ ï žâ T7ÓU_ùV‡ƒßökèö¡µ�)OÈŽPô&÷ÏÑyâyˆýy‹z�Wó¡ïô¢j¡8z‡(˜¥ÿX+á Ä‚z•'xºpù«‡ù¬¯�­GÈ®¯ù¯Çù°Gt'{³¯x´ßx2èøRPv·gvgg¹WìEé»*¼¿v©Ïv´z¬�X­—r®ç¯°÷±ÿ²€Åg÷ÆWûÇ'úȧ÷É·÷Ê_ˆÿËwæ Ñ|é¹{ߌz½_rmGø½-ý8ýXi‡G‘ÏkýAxýØ_÷Ùßôµ'xÉÏ`9úîìÎÞo·ß¯ûàçüáÏ{–ßûãùXO~À7}Áçç·yèŽ~Ä—xů~`¿~c2d8œc°ÂaÃò0Ì3î!Ä;w°QÄFâ"F/7†éèQ H2F’œfò$¼”*?±lÙãe�#G ÎAXŠ­F:™èÙǵ -jî舤Z–æhêÑ#,XϦ>ëfõꛬֶèêuذEÇ’`ö,Ú´jײmëö-ܸrçÒ­k÷.^· ¸é[æoš4ðØæ0§ÄTyÿú41àñ€”A'_dù²�ÌšsNC’dœÐ¢³’~Ó¸§£ÔªŸvä:*,iÒv6‚ yò‚Ü^½öííÆðàì†/>ÜòäaÃæmîü9ôèÒ§S¿»·÷ß2� îx¸MbN‹OÛ–L¹òeËš7wöüù�èÑ¥MŸV½šµk@°eÓ¶ýwnp'œq&§ÜrƒT· ƒ :ø „q]ç`‚fbŠMŘOåÁszé­—Y{î}_hóÑט}©±F~ûͶ“¸€€ÚQ �Ú“ ‚ 9$‘E©Ö„nd·Ý…Þe(Þ†äAfeéY–Y–ø|(Öxš -:òÿbŒQñG£7æ8 �ÆíÖÕ‘qÊ9'�Ð%¹¤…ƒaž†ÏpØ“‡ †$P–Z¶Ç%‰*úåi8ú(™¯™9£N5ªùYø&§Ôù)¨¡Šzg…ÜíÞx�zÞ dŠå–ï)º¨`> iG:èZfl”Ö–fP¹áˆ)Y›vº›¨É*»,„¤j—gwa|‡j”ªN �)ÙjÛê«ÄúÙ¬‰2ÚØ­Žz¤«¼žY© W¦ÇÊë)³õÚ{¯u|Qø¬©Nò ¥ŸR>–’¶ÛÚí·$…‹Ä¸>•ëÁ¹»JÚkíº;¬[ñÎÛ)¾{ü1ZÎ2©§¿ÔlíÀØl ·¯&<ÿÒ ÷ôp¤úMZ±mcÜ–Æ¿ 2ÐA/+2´§öù§c×®ÌòÁ¯Z)ˆDQß³ÑX}5ÍøM¼n#TQ¥3¼dùÌ©Ðe›='ÑýJûdª*½rË…>-µDTÛv5ÖåÖ,#m^O6±c�ýóÙ…Þ¬¾J–ÚäÚÿ¶ èÛÇ�åÜtÛ ÞVgý”º¾úý à‹=¸W‡›~zuËuÆK-Uìd6í6Us;š¶á°;8½{ò;ð ÏÁI'AQC ѦUù8ŸôÑÈõÕ÷s=ö>ÚC6êÝ{Ï¬êæ°îº±ËníCØŽ;»ºóî;ð¿OPñ&ÿPò -ßÿõTÎç½ôŒS=ëaïzÚãÞ÷¨À9…o|®3ßìj‡�ÛU#w�ÙzŽøÉo~õ›ÆýÆ‘¿<ì¯yÏ`¦7@6Ѐ>Bàc(C5°uŒ]Õ7AöýÊ}„_üæG¼ú…p„%ìŸóԢ¶°@‚á £(ÅèÔ�|DŸKAA >ƒä '„øÁqy&Ì’ö¢Æ²H@š"ã(�*Þv9\_ÛwÁ÷m�ƒb¬ówÄgø/�jLݘ 92²‘v¡ãëpˆEj‘‡�ñ 1Æfrw�LÞþüWÈ´r/ŠÙ_ð²—¢L")K‰JE²²˜Ætåc¹Ã<ö�–™´åñp©K†ôÒ—¿4¤‡éFcrS•È„e·Ø>g⃜ìä4óPM^þ�Á<¤6ߨÍyÆñ›vœ¤,Çù“rfòœ™¬Ñ9*Ðuú¢�Ø4e<—CÏ…JÑžçSf%™yÉ}òswþÄ @P‚ô�ÙL(s*ÒrÊ7}I JGP¢b°´¥ŸÛßÁ& R°6½iQFªÓ�ÎŤnHiRVÚR–¾ty1•ichz»›â”(<}*TÕâS ª´=C%ªß`š?¤&U©LµiN£*Ö§N¨BjQisT®š@©ÕÿP\ãÖ±ÒªT-ù–’Ö�¬•«n�«\�Z×Áîô®íÉ«öª“¾"õ¯€UÅ\ +Yz¶3ˆUl#k‚{p¶³í|¬*&+Z†–2xÍëçæ¡ÚÕŽP{�õì/A;ÚÙv³´§%_jW«ÚÖú赜ýìci+\V–ö(Æ5bK¤[Õ^å*®õ-p;Üé6²¸ÇEn^•»ÜæZ幯�n\©+^8Z÷¸ÉmÏrçÁÝnx¶¢”íxã+ÅLEGvp~ó{‚ýò·@>-�|\Lú…SùÕ/÷ë_“XÀn$�`à; Á 6Îáôà Ç1Â>ëYƒÏb“8†Þÿˆ5Œ–—¸ÅÞ;ñ¼RL¯«ØÅ6žá‡G‡¬ó˜‘9áz,d)þ¸(P2’Xä9ÉNöÞ’%Üä'SùpQ>r•³¬å-s¹Ë^þ2˜Ã,æ1“¹Ìf>3šÓ¬æ5³¹Ín~3œã,ç9Ó¹Îv¾3žó¬ç=ó¹Ï~þ3 -èAºÐ†>4¢­èE3ºÑŽ~4¤#-éISºÒ–¾4¦3­éMsºÓžþ4¨9\‘Šd£Ô¦5EB�e�¡¦>5ªU]eV£úÕ¥nµ¬[¬³ ðº×OûÎw¶!ìa[ظÎu€wÝk^ÿØm(6´·qldÇWÙËn6°£]ìiS[¼Ööµ•&ÿ‡%hs»ÛÓý6³ÃÝ´B½¨Üæ.ºƒð4qG Ý±~7uŸ6"´ŠÞ/ÂÀ+‚ï|[ißý^w–þðT|¸úÑÁCÒ-…ãCà îÃ×q�Lœ5¯8Ã/>Øe§[D߸«^Eq‹‹¼®$—wÁO¾ñŽ?åã,oùN9õr+ð¼çPø9ÐKôÇâ�QFöÎ⢳0½éNgz«m-õl„çuÒ9É{îs ÿ\è¬_Ñ�.ì¤ÃeéO?{Ô§þêª[}NX_¶ÖyÎõ®·gè' »<�^³ŸÝéiW{©ÙÞö8q*îVh âs0w(x}xÄ»ÞéÂ÷¾C½Ö€üÅõÿ7>ñMY|ã…÷x=ïcßûÅ(ïwË_^ðš/RáãîyÅÏ=ôô;éž ²¿eò”ÿ;à]ÿzqj#�÷<гƒ.t 1Î~�Jù¹ø¾2¹þö½o© ø*¾FŽŸøäÿeùºRÑó¡ï韞.Á—°/í�HêÐö>ìßd|Ù#ÿçÊ7?ú¥_8DŸîñž[¼ßEÄŸüÑßzØ_±á‘€Ÿˆâ‘_˜Ÿ`ú éíÞ[œ’€b2àýA �H ~žÿ•·àúà>]Žàõ• ý‘Û½¡`u¨ ÿ�_ ^à –F ràô±" ÎÿŸîŽšN‡W¬€n„dápÇ€ÄF\Æ�D ΔRÁl¨…Î ‚®¡á!L‰¼ag´ÊÒHÝJG^¡Fd¡l!wx¡F€¡IŒ![µUš!, áŬ!Æ�Â!ÊáÊÐaBÇ®j!ú¡â4"[¹•!bZ¤¡""BºŒ#>â Ì¡­M"%v…Zbbb ÄZ† à "M•–Z”""ì›ùÀN#¦b{@bÁH¢+6G%^âf¢-þ!.¢.¢[ùbZ£0c1#g £¶(ã2âE3Îâ3Ö"Ü¢ äbúíâ5–Ò/–â6šO7zc€ÿc¶ˆã8ÚE9z�ò!ah"'z"˜8ƒA¾ã!‰XWh㈠cÔ㕃DN$>š*\¤©íc^ôã?Bc:Jã:Rc;"•A:ƒOa#xC®‡Cv‹³µADN¤D~MÖ¤iÐE¢BFjä]p$-d4nâ4vb5ÊTIž$<š…JÊcCr㫼dLÊdMÚäM‚CNî$OÖ…Ož#P~¤P†$QޤQ$R&¤R.$S²ä0[¶%TÖ�LÎäT~CUZ%F–ZVò#,â¡?þä`äPäi¥I¡äR*â<ÆN[º¥³EåDÎ%]VåUbž»äå[l%@þePdQ$YfR¦$Z"fSšÏb²å[O\–dÖådR]æ9G@!ù!,=*ƒüÿH° Áƒ*\Ȱ¡Ã‡#JœH±"‚‹1hTÁQ„Ç�rBŠl@²¤‹“LR&YÉò†Ë—[bÊt@³¦¡›8èÜ© §Ï4@ƒ~J�Ñ£-’*ÕÀ´©…§PH�z ªÕ%X³Ö¬) «×Š`ÊK¶¬Ù³1fÜØñ£G‘#K’<é"%–,³f•9s«œ9wêôù3(P¢Da(^¬tiS¦P£N•jÕj—˘ý:@˹³çÏ C§U‹@#Ž*ܾ…+Gî\”*ñ&Ñ‹•oLÍ€o LX�áÈ?,fܸÅcÈ‘-L¦\ùæÌ~EKŸN½ºu†¤K³M­šuk×tíÊÿžMÛ†ùó¸sï~ÐÛ÷ïà‡Ã(nüxråË›;ÞEóõÿ( XÙ™†šj"xçZáņmKœw^V8Á…®×ÞoiÀ'ß|ŧÁ}Ë  ýE7àŠ,¶Èb�Û!¨ x°Ý%„šW¡…^¨aoz(}"’˜_s(úçâ’L6ùÙZ§¡Ö–uT)Q%-f],Åà%Ž9îHa�VifZ¤©fP´I߇Ä)§ˆ/I6™U(ä™$Môé䟀:”RNiæ•Ce©Ø–'uùeyaŠIægV©æš@µyÁ›òÉ9çqu>U"žzòWSŸªêª¬Dh¡ÿ–$i™—+y˜ŠÁ¤•¢y©lºYœžV@§KvRUUž(ì骭Vk-“¯J«•³&Z뢷6šë£zåhƒ¯ÀV:,±™Û²žB*~w>[ês§úyí¾üþ—í�É*­ ØÊ®IèÊë„’’ìºÅnzl§ÉÊËìSô‘­©|êÛïÇ ?y‘�°ÌíÀÞ îÁâ&LnVæ¢ë°ºÃFÌépÉV`ñ PelïÆøvœjÈ+fG´ÈÙ©µ‚…¥áÁÓ%½!5}Žêƒm[p õÖqtíõ`c8ÆØdaöÙH¤­]tÝ·` p£­vq, !´@c–ªÿ  Ñ~s–4iK«ÖôÓD=5ÝãZ�õÖ\{Ý5ØGˆMöØgË�ÄÚl»pߤp§ 9Õ+Ù�7Š{óx€€¯nÖàJïÆtOA!®ø¤»ì¸m�k-ùäa_x9晑öæIuîyr Çmöñ¹›-ê|íºu­_?ìîÖáP“$5îŒë®ëã½ÿå–_^¼ñs· üçd†>zùÒß«wõÚcOZÿdÉÎz¼÷ð%N|‹kLÕtu¼ã)O}ìÞðÞ½äuÎj^jžèž?¥ÔínÓãOê¨Àéd¯„à3;÷8-| _î0ƒ¦í�¿‹à†7 ÆOy4ÔàýÿX:êï2#ì ‘†‘%‚E…+Ô å(Ç!Û!�|D4Ÿ—lˆåá‹`œßG bPˆD^ó—7$òω 9!Å(NlU„¡ ËÇ€>ú‘‹^ãÅ8Áâ•ñ‚g¬Ÿóà§Fñt"|ã;#ÇIb‡pQ”âóxÀ&БIðãmHAÒ}†,Ž­†FFFψmìB­gɰ°à–¸ÌÎvÉËêѲ–uä aîxNÞ.w¢ì# ;'ÈA’iŒ©lÌ*uÕÊ ®–ÔS]-/©\zó›¹1/{)IVuàœèü¦:Y°€vºó�í̤0}BLc^™É\&ÛšYÿ„I-È.v¡„‚¨È º°”€B:Ëmr#ëgnƹK_Z �éŒ(.áÉÑÈ“=½©ço¬èI,‚2™ Ð']øéO×4%¥ A{d¿4¾o eh9zŒžÓ—_ªP£@Ô¢æT¡HªR×ý‹ø´ÖñŠWÜ@Õª†³¨E-ƒV·J‚®zu` «ÆZ€²ž’líQƒZ×J€¶ºB Ò�~¦@׺Šè¥L‘°2)4øõ¯/yɇø‰¢ y5OHìSMcšJ^Ï—@jPO@ÙʾಘUêRw3ƒÎzö³�}jT¥*€ªZ57X%êV¹êÕ®†U¬d5ë3‡×1ÿØö¶u­+\]#׿Üç®/Õ+¹úúW¿ÞçC<„�a»ŠØÄrá¹Ð¥‚t§ëX×A¶z’�le)‹ÙÌjvë­xg Úê�¶´¦uÃUS»Z­¶Öµ¯ÂX PÖœulµ½­msK×ÝÊ¥·•ùíqð*Ü]ñ•LÅ5nr�;<åRè°Iì ÝéJ·º«».ß²û…ír·»/àaxÇûÙòRç¼éuˆ_Àƒ»xR¾Š¯|ck_2µ'¿úåïü[[EÀ�!ðqöºâ÷¸òI.m–K‚æN˜Â\°ð…ÿ·D £ŠÃ>ÁŠEÌY{y´RMñŠ]üb2ùª¾õ�o}'uãÞèwÿ¿üå1I|\ 7EÈ�!²‘ÿŠäá(Y/Lv2”£,e ÎÊ}²‡·<¼{y¼`žjzÇLfÀXLh.«šeÛ£6æÍbбœ@çØ™)xnŠžœà>/æÏY t„� e)SAÂO¸ˆEo—Ñ—»íNMbožå+Añ¤A\iK›Ó™Ž6›=ÝP‹š6q¥ó©5€×IAhÏ Ž ƒ/çà@X´­q­ë*W/ðŽw–³ l² ['Ćtg$mZÍà-O”&ó¥wíhS»'Ѷ6Qj‚†;\?Úv{ËàmÚ H Ïø}ÁñŽÃ+²F7­)¼n ·…¾ÿŒ·¼çýkóðÞÈ·x=Ãïªúûß/s�Î\p4\ ³Žîð†C\>ooÅõrñŒc|ãçøÇ—òt׺ÐTFù»Už–·¼»/·í°eþYšw%Å7Ç[Î[<ð õÜçzŽžÌ¢7üf‹¹ÏÄ'¾ô¬4ÝéP�úÔ«>ò [ØÐ­òeÏø”sÝë–uùð`Nö²ïûìéM;´Öîì�Cûíø¹ÜqKwQÚÝxWŒÞ÷¾Ú¾cåïONÔ¥Þà%?˜¹³~2ɱ®–£)žñ‹w¼Ê!ÿa°O^ìø®|gÍŽÞ~ûåß(à|Û)ú²Š>Ó Ï-Ñ‹žz¬žõZuýÿ`ÿtÙÏ~ð·orîÕÍû&:É—çþâS|†úÛŸë�þ÷?)Ïáÿm 0€X(* ^ê$¾´ Ø€ø—eзbÁ‚c v[ðA˜�‚°�h.4¤F�RN‡qƒ–jLQW5�û§[´a.ø‚kµVãÁE€d!Yñ‚/(aÓ5hMðƒžÅ«¤% @öW*¸ú×ñUƒÿ'€8€ˆ€ß¤€ÕÓ€øx� 6�nV�úu�ˆ�Ø�9ò�Y‚É4‚JP‚Áu(HK8,¨:è‚1¨V3hCP87ˆƒK�‡VÀƒÒåƒ@ØYB¨*D(UFÿˆ„IX‡üG&þ…R8…UZ  ¨…+ð€]ˆs_X)(†dX†g¸�ˆA ˆ"8‚pP"2‡P‡w˜ƒy¸‡jЇ ô‡�ˆƒ„hˆT€ˆM„CX=ñ'�x\Ç„MH‰Oh‰™6…TX(¶¶‰щZŠÛå…݆Ÿ&†eˆ�㱊VÓŠ¯èt±h³HW)ØŒúw‹XAˆºÈ‹Çã‹c#ˆƒ˜‡ÂHŒÆÈˆÈX„òÇy�IX¡:2Ó#2f.—H€¶v�WȉYè‰ÄwÐ,àèâ8Žˆ!"ø˜6jˆl(JnØŽ)ñŽS�*·‚ýÕ‚¹¸‡#‰ú8üÿŒ‰ÕƒPöƒÅ¨ˆÇÈ7É|‰� ¹�pÓ�ò�9‘8‘Ræ“MpKXÈ7ž¸¹‘y&¥X�ð!’²ÁE%¹'éG) e&¨´h‹1‰‡3ƒ5y“9é�;yˆ=™ˆ3°ˆ‚Òˆ^¡Ei�H˜) ””â” •&•Ti‘V‰‘ħ•[Y%“ò‘¶•3`‰\t6DF–®Ø†#è“Е–š�׿–:xq …üˆ‹:hk ”É7 y~ù—‚‰”¾Ò†yˆ©˜ÓŘzù¾$Æyœù‡“i&•ùfú�™ÇQ“œù2eÙGkp�Ø)šÏEš~ašq&“©™ãÿ¡>!XCˆ°y—?™—A‰*µy›E™› ¹›½Ñ›æñ›ÀIØHœÕsœÈI|ʹœuМúõœÉ’™,±™fÓ™ÕÉØ™�?8šqø¥Éu§éš/¨š²Až¬I癇éIa>�LB&z¢G%ïéÉòÉ�bÒæb.ïERùƒù©Ÿ )êŸÆ™e©z&X3)�åê)º j ŠåHz�ÚÉnØlš˜:¦cš¢)÷�C’mæi7Ú! ]#*›r^'Š¢Gµ¢[Ñ¢/š”1Ú3š#5Z¦9ªNO¥NAð§€Ú£> ¤©5¤fR¤dr¤7�¤ŸÿòÒ¹ Ô ¥å8¥kP¥WZiYŠ”[Ê_]Ú&_Ú9ê#¦J¦7z¦Ï•¦ì¹"lÚ¦�¢pZr:§ôIw*!yZªùɧ>å§€ú§‚ꟄŠU†Z%ˆÚ#ŠÊ¨q²¤IФO¥”j©#ˆ¥~¡¥›ZW�zŸÊ6¡šicÊz*e±™ª¡Á—]AQ?�¢œ˜R°®ì*c¾Hò:¯FÑ#óêU”zHl¤Ô;𯋠}Y6¬u!: »°§wznè†"2>ã#T¡#ºb.hknX•å’5!ßF&ïã†ôQ&{²“‚54d,Ë“ƒ¶{::œ A®`®èÿÊl•¦®ìº®î*&ð …óJ¯x`¯òНSª¯tÁ¯Ô°«ûo …Á‚°üµ° Û°E÷°#±û 7ë%k�R¶±$ѱto!Û##;‚%{²&›²¶±²-k—/kx¸44k³G•®H¹³<_ïñ´dP¯r¯]•¯ªÔ9J;…Lû¯Û^ëaKµ¹eµ ‹µY«µǵûµ)¶10¶R¢±#ȱ”å±4²´1)oëtq+·tËvk.›·„³|;�Rå·9¸ )„!=»#?[ƒˆ›¸C»¸EÛ¸Gû¸lã+ý:¹;€ Í{¹Û•¹´‘°œÿ빺¡{]ëµAU±1q±9’±e»ºgÛºi›k»m‹!³›qµ‹²d¢²IJº‹·¼;]{+4Ko+†³d¦®Ç›¼²¼¨Š{!ŒK"""ïc½K;¹ó5_Ûûo„ø‡X£¹vuâÛp” ±Ç1q¤kº·*•ªët¬{®ë°«²[<$[r;·ýknÀ»›·ܘ¢qÀ‹–ÀÝÕl ìÈK¸>k¸P(ÁÏKÁÑkÁü,&×ËÁlŒ7! …#ü½ü%"'l”êŠQ¾�ÁÂé ¶ëë%/ì“1œq3\Ã7œ9œ9xU»:‡!XÄw;Œ¼û\E,³ŸÿáKµ‰ÀJ|YÍÖÆëĈƒ8…‹nHÅD´Y¬ÅÅ£Á’ëÅܼGˆæRÆz¡®+@~£BÞÃDž�F~äIÿÞVKžM>$OÞ”ŠxeQå¬zåY^ƒÁÂå¹ååV æb>dN$Û\”æjž+nÍ-Û/^)1ޏ3^5ŽÏï¥ç�q}îçu‹A�.•ƒ.·…ž„‡Þš‰N‹�>�éS*édAémjé~qáˆ;tÞGžÞ9 âe>î�W¦®æ©^ɫ׭~&·+tÞ@4×J€ç]eëôÜùnî%½^¥Ð5äüQä•väKPìÇÉN�ñTM…¿Ë7Vþ|ÿvé˜éÕ^zžíl³íÞíßþRá¾æAëÞå~ºç=‚5ënM¹ìîðNò^Óôžë÷ùÿ¡PÆïÏáïdðowL>‚N^ßT á•îðxñÿ'ñAkí×nñ³¡Þ£×à.§ŽênNê6$"#ïê?Ìóª)±ÞJ ò´~ã{("H]ï1?óMðë'ìö7ìü¸óE×óN÷óïS èí'*í[AíKOñÊíô�ÂP/â¢Î_Gq�_õÃqõ!o\Äõ{,š"ȶöm2ö)ïî%.V£-_×/ßç>Žn÷&+÷õG÷‚HCÿ¯ôôÜã÷ç´:ðûÀ�Ñ ùĹÃ%R"×ÞGìÜ9I øŠáVÝ>õÄ/ùy—•�—ºÿø!›!&/¯b_ç²nö1PúïÕ¯Á‚ÔÊs¾ºÂúÔx^Oõ#„ñ>üt§GC°ˆDPÐàÁ‚.dØÐáCˆL¤¨ÃâE)5zàØñÎG�-DŽLRÒä”)U¢dÐÒåË–KdÎtQÓ& œ9 ìlÐsÊO x„‚dRÔhΜ”.%ÓÔ©P¨xœ>�ŠGÍU¬Hq^à:Áë°a§6ERÖìÈ‘JÔ®�Ñ–Ç[qå‚ [·Î]¼…ôîµióÍ_Àmct!\·®Ä‰J¤8QÁcÈF$O.RÙòÒ¥&4o,˜ðç.gD�Fˆ"ÃÅK—>ÝÚµCÆ�/bÔ˜±£ÿG�ÑŠ4yråo˜ÁÌœÙÓx­0v04èÐ�F�jŬtóæªRÇfÇšU+× ^'„;6ÍyôfÍ®eëö- øñ ÓÅ›w¯Þ¾5n ÚbÅRkÌ1È›Œ2Ë*«Î‚ë4ë¬?ÿF# ¡×Rë`5 _Ó°µØ*šM‡Úl»ÍƒÜtÛ­·’~N¸—ˆ“鸞’[®9禀Š(é˜HnÁMÈn,2¸ëN�äÀ�<°€D/=õ�`O-ÁÞâ!>ùæ«ï®ûðËo¿¿<óï3³pÀ 4ð@#T°º,B Ï`Í5 1å�xbRµÝ–Œ¿Ì`cŽðøc‡Tyä>?0ùdtSã–[Nb–9škföfœñtÚ¥¥ÖZްÒbn5ð¶*pw—\sËMY]ØÍÏ]xK’ÿEzSº_÷í·¦+ X` 6øa+®Œá&F;â‰%®x7n1æCcŽ7þd×J>Ùd•ÑmÙåT÷ö8gÄmg ¢ýpÚCªÕâZɲ¥»h£aú6é¥ÅmÚétוÚ&ª…ˆW«y³`k{óõÚ^wø<²Ë6{´Ó>oáÝö/w¸ãž­º3ö/o½ Íï¿_yð^6<Å«·~!ÆŸ rÉ)7Ârâ1?:ª¤ 輂ÏmxZôÑ](ýt¤RÏšõ\¯ñkÂ.bl�oÇmµ�mêqÛÂG±&ÍnxËÛôn†+çAïÓsàõ,ˆ¸ìõìq?›\Ð*7ÿ´Ëm|P)ßùÒ·¾¨µÏ}Uy—鬆:¬©Ž~ösþôÇ¿�Ý.w Y ±ÅMn á�‡¼ æ W¸¢`ùvA(æ)ƒ²Ù`䀿¡u‡hÝŠ‰L6.~…*t�z„ÒBøåD~ôša×î;°ÉNl´#›ÿv¸»µõ®m¿{[…8¼‘ïnGl ò˜µÄ09щQdä†J£½‹pïŠ_ Å×Å%d'walšóþf²X‘ �%ÙŒc8—ü†~àÏë¶6¨ÖÎk eÂDå+Rù xªËÄœ7(»Ù�•\A^’ˆ'DH‘Mld3[SšéQ@šÓ”doã¿VÿÑÏ%3y’rç¼î“ðŸñ0Ê$”'j*‚êVǺa^ Gôó_pO|v“–k°å’|å?_õ(V½”˜óŽpP„cñü�úÐ&1ˤ 3-êhnšÔä  °y%m¤›ß \8U6Nÿ½�”šÉ ;ݹÊaΓuõÄcð™Ï'í³ŸèùçíÚ �ÒÅ—�ChBÊЕ<¢‡”¨(zÌ‹Z4£{Û¨4«éÑÛe“uÁ)ÚÀ)Fq~2¥,¬Z:YºN5¹“kekky0Q¥¡§fûéu‚ ‚¡ª¬¨U(�ª¥:4¢}ª!£zÑ©~¬ÿª¸êˆ>ZŸ�¾¤«sÞ<ûYOŠõv*5« ZšÖ•�Š­m�iƒèy;{ÒÕ®üÄë-ÑP4 4?•ƒA[ØÃ¦$±NXl2»·ÇF5²›le¯™U�nU¤O"©Ê> Ú°þm¬QA§:aàÒÔ6iµku«kg ÛšÒõ³ÝéyöZ°¾næ¯�MÙ`�Üa64±ÅEäqŸ˜ÜäNﺞÍ+�æp`£ç^Á)ߦjV³éáʦ0 Z…ß ¤D½=ú�e&ƒÛ©—TY q‰ Ìi+Ék\üâVBÆ3΂Ìpc¼HNràq�ñc 3ªÁCZ@‘|d$/DÀÿ.ðXœàó,&CîŽC"& WxD>*W4LW¯ÄÃ’ñdDܤ›X¡(ÆÜŠ3Òâ»8Æ3–q�«sc3äXÇZè±��üc!'mSE^@’ `à ø MžÊ“¬`{1XÐC²²á$œe;XøJþòMì’1¡Ì’9³zÒLâÃ$Ån–œã.©¼Ì±¾ëË>-Ø>öè¾ø¾ð=òëÀ†0;´ë·ÖÛ?ö‹½4˜½ ¨½Û³¿ûÛ=è=œè¿N ¼!¾â“ ÞA ä3å[4%çë è« Ü¼¼ ¼’ÍŠÎӊϽ \œBÁ*Á4€A¶3ATA�©¿ûÛÔBt¸ ÁΰÁÔÁL¾ÿ,‹Æ3‰lšÈó•é j‰ë› ´ÀµÀ@ Ü@*ô@+D¿´ÁFa?àBø£=ù›»/ĽÜCŒÁ'ù»{BCÁPCÌ#6TT¼ĉB™Cs©C4¹CKÊC ļ>dBîsBïƒBAı³�˜]^ì@aý±Œañ7(Fc¬ó{]œ¼ƒŒ‰éð( ´È n‰'S,—Z›Œ³!𘉰˜‰{á–äà7É—+8Gt|•qÄœÁ§°øŒ™à”c§Y‘ ¸G|ü}ÜG[¼E\\F^_`”£ù¾Ï€*=IÆelÆÇxFŽˆÆ$˜Fœ¨ÆaB’ÿ-HŸl”ŒmÄÃn”‰o”‰pÜ–uÔ€rttLÇ,)IniÇ{zGˆG3™G5©GèÁG|ìGòÃÅÈ^ü�_„‘`¬ „$ …„ †ÔE‡Tˆô‰¤H°HVÂH�Ü:-ÐÆ² š�\‚�\‚‘Ô€’ÙH#èÈUÜÊ®üʰ|s$ËXaÉmI˵lKÈxKˈ˖™Ë¨KӻˉÈ˽‘¾4HË̪LÔ Ì¥lʧdÌŠtÌ‹D’È´Jÿ¬D­ä o p´q<ËmKnz’Îd΢M°€G™�Ç[c' ØNî” ÛTÍCcMeÜE^|ÍÛˆM´`'ÚܨïTˆØhHÃ|HÄŒHÅœHÞŒJßœJàüɤL‘�ÊãÜ‚ä¼�åD rÔLé¦è4Pvlw¬Î˜¼Î™ÌN5áÎöO$Oל9ýKÄœH µ˜MÐ LÇ:�÷TÊødÊùtÊú„J©ü ÈäOáäȬl*ÈÑД‰mL è‘|QÐüðÌ mŒüìì3 mÒ œ ÕPãPòÔKå½J„UµE.:ÁÍÕͽÏ%Œ��þ¼Ñÿ¥‚ÍÏõQ’”δÄ)öˆúq“IÒÿB#4'uR&:Q)6*��€4O-ÜÒ.]ÏiÊÐ-Ì8L9HÌ XL‘Rð�ÑýTÓ�L6ÕQíÑíÍ#½õ"Ò¾ÈÓÙS$ù\ùÓ" Ô&T0-T|;ÔD½ÒÌRF%Ê­MB]ÈÀK�Tù¬Tú¼TûÌTSÝT4íÔ‹XSâÄQQ…Ó8-Uü<ÕÍHUèÌVí W%XõSY¥U µÕÿÂÕð,ÖéP~ûPô\‹Fõ�/ý˜Ú‹ÔÜlÑÝtÖm…Ö.HÓiýÔmlÓ7Õ€­ìAmmI•­o]UÖq“—áSЈÕÿsE×íT×ÃaWCuׯ€WÈ‘W­øÕ¿ Vö4œ|SdeQeuQf…ÑüäTòN“«–á ƒU…�SåVÍðÖ;׈}�‰}Õ>Y]ŒÍØDVŽ�*B«¿‘Á»�­YíÃð°‰éØÖ™ø’|ÔÇÒ¨¿ú#“ ([³]•€ H¼8¨ðϰ‰'�–‘ ¼‹»Í+RI޵0Ž|IŸB)”ÁÄ›¢Ÿ—‘ 8\Ä-&\yZÆUˆ¨­»©½»ªÕ1¡ÈÚšØZnéZÿøÚ[±e²5Û²EÛ´�µ5™¶½Q´€ÛY”[–¡Û»³Û8ÀÛ&Ñ[µà[ñÛ¿í�À>º’ ÿÂ…ÄEÜÆ-ÞÖx\ˆÜ˜Ü%´\ÀÜmÑ\Ðà\ÏÛÐ]ÒMÛÓý€Ô­ÖÕ­‰¸ýŒ¹�‹º½[QÉÛ¾»ÝžèÛÏÙ]Þ­ÁÅ'àMÃ^0^üuäU^æ½Zç…^ �ÞÏ ^„ø\Ð�V’Ò5Ý»`[¡p[ÖÍ@ÿ_(ßÙ=ßÚM_%À]âÐ]÷M‚Þõ¿ß…ž—ÑXêÉ_€ýªµˆZ«@¬å ­- ` àƒ0`2Ià±ø¸ííÞA‰à/¡` æ•ì°Ý ^ßÜý”\øõÝ›š_*1áFáV�Ö�®\¾\6Uî6Fà+n`ÿÔ}`Õ !žà×%ߨµ[#® $æà™HŸ&F‘î4ù%áT¡â*Æß+Îâ-Žá ˜ac™ðÚ{ÜGÆ)ãÆàá©ø¸qÊŽŽŒ¨_è‘Ý¥„ L†CKd�­Ôã[sb̈ß{’âøäA.ÞB–\¶Jþß/æÚFÞÜGÛ‚x ’¡Ñú@cs»äªÈäüØdÂ� O^QP>fQ†�n*e&¾5_Y�ÈfmÞÁy0šqåWfÜX^ÞY¶ÚZîâç½åÌÍåéÝåÎíågf‘¡Y¼ æ83æ¨@æ¾Pæ.`f»ýäÇe$ð½'¡æ¦A¹k®mÞfú…oNpgŽçÿþ=çDöâEÆå%pä€dxþey¦ç»°çÃg  MVNœf^ÙgÎçhžfãdçÏ@h4Ù—…Îfnn™‡Žh‰ÆUŠ.gÊEdE®aš¾awfyV‘®’v1“fcïMiXé–ié:†é�嵨Ê/±éÁéœÞi–é馽՟f× ÖbZæâ‹NçŒ^ç�ÖåŽæeðå¥nê§.€¨Æ}¶ ~öç8hh‚&噞kÐëÉë…&ë0kerÚ´®Ë‚Ð× Y,m€6&‰’àç/1CÛ¼þÿ Õ^m ãp[“Pi[™02YÊq"™¾)ù’‡V4ÿû•�byèÊn†¸l•… ÍîUÎö^´ˆmÙ¶Ñ&í�6íÛAí±XmÖ&>×î Øþ쪞m;¨í½í&ÉíÝöánŠ"nöÆ(Àì•Mî×fnÏNÐö�è–Úéž�Ó‘ÔÆn0hퟘoú&ï=ÚÛþ$Ü.h®8oÐHï‚[¦ö®p…0n�…Ïøž–ílÞðîï†îÑÖo`²î©ð×îçnwnoo/o×í·àmon¶E²ðöÆpc•TäæðÍöp·ïçí‡Üý¾ˆ‘MQqŸoñ^YòVóÎqôÞqõ¦pgo oÍcòÿCèð?òû�üfòÿ�'¿�(ð>óŠí^î¿ò/IðÆXð¿ipÄÆqÐñãqfsâ.óñòÇ�o6Orü^òämr‹˜sJ’œXm”ËóîFò=ŠCÈ8sY�'©Ž>šAôŠRôáft Gs5—tçq%—n`_ÿuMçˆMétÕ¾ó õ?pð&õ‰0õÇ@õrQuö`õ/?ô0W$YŸõ÷>îG'rå6ò\ÿ¾7¿ô^ÿu_vvœÈîÁCö=Wö>·fgWh·i_ j�p0ŸplÏö´¦õ3ïö4/ò5wÂ…_øqçs?wQÁ3ÿÓ/ÔwŽÀ¿±Áo} x}âˆý˜}ö¨}[¹ýgBÝç}Êö}Îþ€þâ7ÓèE~_ç•)úP¥»p:âªÐ:ò®¿ÍóÍW·ôÑSN{w¶ç~=ö íÞ;G¿AzéÄ£m|òÉ;Þ¼ó›E/ýìÔ7h}öñË?Ðöº¾¢ÿ|øo£N~ùZw>ôñàyëó AÜ÷>›Í¯� ¬Ÿ î‡?cé|—_ÚT@.�€\ßôø9°„šƒ ½gÁ¨`0qÜ Qˆ¾²/�"< M¨Ã¼ínw<ÒÈ‚(DB±ˆ78"“ Ä%:ÎN|"�ˆD$F-j¸"w¨Å-®…PBb‰8Å#.‘‰o‹"M0ÆT‘`XÌ"ã(G‡xñ‹;£ÇXF%61�P\cÁõÆ+α�†4H¿ˆGB¬q�I裥8Æ@J Q‡¼ä Æ06r��Œ$ )‰Kb²”ZÔdÙÉ2~Ò�¡¤$)M)KÊÿ"ra�r©K2ð²—­Lã+ËY3{µlÔ-u¹Ë^òò—h¬ZÔ¸‚a³š·;&An‰KeꀙÍ=ä0ÍùÓ¡Î1¨ø$*R iÔ„&µ©r\*F�*UBÕ,S½ª «ê ¬r5~Zí*X±÷Õ°’Usc-+ZÓªÖµ²µ­nÿ}+\ã*×¹Òµ®v½+^óª×½òµ¯~ý+`+ØÁ¶°†=,b«ØÅ2¶±Ž},d#+ÙÉR¶²–½,f3«ÙÍr¶³žýlZ ÚÁŠv´�-­iÿŠÚÔöuµ¬Ý«k_›×ØÊö®´­m]o‹Û¶j“P¥gwKÔŽvT›Út ~K�à ÷§Äå¨qo‰\å2·¹ í!ç´ ‚ír¹c*xÃ{‚ñ’÷æ=¯P­+Kìv@»ÜÝ®wÏ3ò–÷¼æM¯zKÉ^÷¾7¾²™/}O`ßû5¿ÅÜï-ß»]‘E Á0}üüø�–‹‚AÀ`7¦/…+\È c$Ãæ°ÿ‡?<Þ‹XŽ$¾ˆ‰õÅá‡2*/z­ÚâK²÷>þñ?� ä!ŸøÁ5fÊ�Là­îxÄØý1�¹9d"ËxÆó±ñ�sÌä&»øÉP~@�§|„"Ó˜0XV±–¹lÈ9ÌS&s®Œä,/YÍNîá—Á,e1ÃYÎHrší¼EuåYˆ±y×»@¢è1І6‹Ô”›Döá’Ž‘Ùa¯ºÔ„Ms¤ •ðªX,èµúˆö¢sµè»4úÑ�–t€)-KƒәƧ;íé=€ÚP¢uZJ åS+ ÕuX5£íWk Öô•uXhý[g:×›Þ5¯êû4Âþ1±�ÿ�le{àd0à�³É mHÛ+ÔÖ´µ±Ýë,ýºÛù¶�Ã�êq+ÛÜèÖWuÖÝn¼[VÖ‚;ÝɆ…3œ;Lµ7jðý}#šß�ö·cDð3Tº „*8®­�po2¼á â6ÄI}kpqLÈF¶¹1>•µ fã'HžÙ ³!„ O#gfÉî𨦜-·ÆËwàòUëO1?h›‹åèyŽÖ³¾óžàç½ :h&ƒz}!VÏwËσ즋îéþŠºÚj¾™uŸÊY×:̸îu^‚]ìd/{BêNìØ¬�ínç Ü w¬Ð}å_¾;Ö·Þ󽓡ï4û;à"øÿ´Ë¦ðM?|J¿ø«4>ÓW‡¼äCEyË3l�ȼÑ?qΞ醽è§>wŽW]ö?†|RŸ§Õ]쮇ýZ´iG¥{D Î'·SøR2¿T m,àf°ˆ‘¢ðh!r!Íèá*DîÀ:` úË úE!Ð!ÞRžm¢Ô‡ŠÄ#Bbé$�N"V"]âAd¢)’›¹}âJ„"úŒ¢\”â&¢"#6Ú*:¢ð¸"¾€" -{UŒ Œ‰)jˆ†˜[òˆ ŒË¸ø"FHc0 „£8š[1ªÁ1"Ï+*c2#->cÅxãRãmX#ò`£6Š? 7^<¾_}ˆã8žL9žcë¤ã2a;b4î£óÉ#ÐcëØã=æ# (ä)‚£?Â9£@BA®£A:D@!ù,:*†üÿH° Áƒ*\Ȱ¡Ã‡#JœH±bÂl3ZÛȪc„� Ɉ¼FrŸÉq(¨\Y­¥Ë[0ùÈ4@³fš›8±èܦ§O-@ƒ’z­œÑ£8’*¥Æ´)±§PW®4Aµj·«Xíغբׯ`ÊK¶ì׌9zùQ$™¡&÷¡'U¥Ë—1gÖ¤‰3çN�>J”äQ¤J“6u õiÝU­b½ª•«³˜3kÞ̹3E´7ZëÈŠmÛ‘%O¦¬{·%Ì[2ùìåÛ7Í_À�à &\ø°ÑÄŠSkì¸ndª“)[¾ì¹¹óçУ;�M4iÓÜÂUM—uë×±gÿ¨mûvnÝ» õ ‡ðáÄ7‘¼[e®ÒóëßÏ,uëk±¥]jr­&UkÕ€§×^äÑáàƒçí¦…z¾•ÓÞ{ÄSá|õÝ×U †(âˆý§Vi¦ xM\s=† ‚²ÍÖàƒF˜^oì‡!q×ár$)ä�œ™8Z€!¡¶"w.¶[x2ÖF£ƒ ¥Iád©å…ÂMãå—=Fö£eD–i晟� Š*É¢�,9ùdŒ J9e•¼]©å–:vù¥—aJ6™‡Ì¡i衈–¨æ‰Ø©øfwÊù¤x3Òˆç„W^³g–\.ö' ¾q˜¡‰–jê�F^—¢›LzwלtÚÿd§¥xfªé¦�6õé4�"7*�§+lAkl>È&kβ̞áì³nD+m=ÔV{ϵØB£í¶kâí·Žrçøävbî¹°:£îºìª;%—ÕÞ¦álcï½Aä«ï®ªãï¿•,0©Ã¬±Ç&‹,³Í>무ÓVK-¶Ùn«m·ßzn�ã�[î¹æ¦ÛîÈïÆKÒ¼›Þ‹¯¾ùòëÛ¿ 0Á#„p±Ë �ÀÎ<ßÀ°>ûœ³ÐËñÌó H' q´ì4íô PGí°³S[Ÿ7XÏ£u\wm±¶Ï„-6<ò”]6*h§ÍÏÚlÃáöÛyÄ7/¾S xç­Þc�ÝÿËÍ߀žN:0¯cøá‡ŽÍâ5KD´eFïì3ÐA#<ôÍ9Gž@ÒJ/íôÓQC=õU×suÖ[wÍõ×Ј=¶Ùg§�6Ûm¿í¶Üs×mwÞzÆw]~øà…#ޏâŒ7Ñã\i>¹°•[¾ó[iÎ9ÒK»ñyÓ¡‹>ué§{£õ<ª¯þµëa“ »ì³ÓÎ�í·ãN÷wvßÂ;Þ{ÿ¾RðÂÿMü¿Æ;Þ߇ å-sE‹Üó=œM��‹ÜõVÀ† Zp{ìèÞ FwŽz0|ã ּшšP}fc*ÜÇ�Çà.ó»‹„v5—Õ…uüëßÿüÀÄ 0ylõÿt¦À›Q®�—“^�6‚&:тܞ}AÅ*zЃ#Ì"êæ!B¬™ð„°“9ÆHÆo˜ñŒ.”ÖÈÆ~ª†pR íÕ?Á€=\ò D!B°yEDØ£—Dce.rN|"Ù€Á)V‘ŠWì ³ÂäLò‹%DaÙÈXÆ3š1�rCÛ¸Âñ1sÜà´ÁJ;¯‡{ì£B¢g‡ZÚÒyF\+wÉË]æ§�ÜÊ5—È&.’‘RìÞ#!ÉIN²‹$Ĥ&ÅÈIrxò“uy¡(GÉ7þ Ž�j ëú§ Œ¸�°ü›,b, ¸ó�¶´%8°—øÔÆ/+Çÿ°eų–£ËY?ÍQÌsM¨#És8S‹ÐÄd#¦YMk^”sãf7KùÆSªDœ_#§9ýwGæpë\H;ßéÎÚaž¹$ˆ=—Ï^î3hui@—3Ђ4¡]¨›ùÐFTša¬è5¿�QjÔ›_çJ@j±: o‡êÈ£Õ™Ò„¬”¥.Åàè 2SlÔ”—ýkN–ӎÎp�kO‹ùS Þ ËôEC‹jTKjQ¢­æR›ºÍQBÕKRý(SÆiÕsš4�ÜèªW‹ÅÒ–þS¬SË^YϺËþ•53kUV?u:µ¸ÊµŸ>]$Pz׼Þ8êËÉÁÿfS�Ü<ì4;ªn«±ŽÍêI¹*Yƒ|ž—ÝÞè4;SζRxŸÅLh6Z·–Ö´˜k"ëšÐÖ.óµ|•-a§Ô‹Þ6”Oåè7=ÚÛņ¸ÜÀªVQЍ!±²h#5ؽ2”�³ð­#F,â³ t üí/ì|k' ˆ°„AAá [˜ÂÏôk”!xxøÃⱈ+ÔžIêáÄ(& NˆÀâW´=ŸhWStØX«6FÇvœ(ûSøÕà~ 5ÿ8ÀÂpE |=ý&“È'Xðn°ã`oAX¾0(`[ ��ÃÄ £uª³j9×ÙwÆgže½g×÷Ï?²‚�àB?ØNô’}=]ƒÊÉʲ™måJ[šËžÌ$xml‡ÑÓâ¨P¹í!êQ—úÔD·R&~ît÷rÝ=œµ»åc[oEÞ¡ÿst½}}o|#ZÑ› ¿¹‡ìíIhàiö³Ñi{ƒá wG¶É,ñrW|Íàn³¸á¬êrwüÕêŽuÈÛÝçw›\CÝÌ3Èk{kƒœ½ °°'2P­ÏûØ·ù”%m…¶ïä[à•ödÞ¦ÕÃ]èñ—(v­‰�°kÞÆyTHFÄà`⬞‡«ÿöq©ëYÇ#7Ô]JZ‡mdæÒ ×ÁŽVøŽ]"eŸÚÖ…JE@˜þô]vÛ­ðvoŶõ¡{Ý×q÷¡ï�ï~Çà½=xöþ7IA¼¹[mg¨³ä�§µÕ ¹Ê[×ògwæ;¡y–]xø»¾)zè§œÞ'ÈëÿéQÏMÕ»]'p'*Âcï¶ÙÓ>è¶÷ßï‘{oì~Ô½—Ýï-|á?�ñ¼„|ìyUGr7ÓVÎP¢×=QЀ8}W�¸yØvž·}d×Of÷}Ÿ3Pâ7~€�zlw~X�~WÄs]6wí7{µ—wâp{S÷§fù—6û·qþG|èf|Ú €SG€fâ3 C] “€¶´�Q〈y8�ÖÇy»”cR8…Ÿ·?p…XØ}ϲu¸L ‚å7‚¬‡~®§~r‡²Ww-;"ƒØ"ƒ\x5ˆ67؈÷ÜÐxèà~"W€C"„Cˆ€ ˆ„P£„ �MxèqÇ7…ŽÿX… �…Y¨� È�NÓ…�ô…"He«×z„ðzá•i¨Ukh6m(¸gtº‡¼W„7F†'|ö€‡zȇTƒ�‹º8Aº¨‹C˜Ù³u„A»PŒÆ8ȘŒÅ°ŒÌÈŒj¦2Ðx/0óX‡“cd|Ægø…`¼æRU:¬M3.`PŽæØè2IðÄ6ž�b¶T~P�ö8qXñC°�üHñø�žPQG!  MÞ¢2:48 ùx¬¤½˜‹¼ø�¿¨rQ6ŒÙ4ÆhŒ èŒi�Ñ8�Â…8ÖD‘�;¶�ýÄk'à�ýT: ‡“4Ž>`Žç˜Ž6¹ŽZÿäˆï¸6ÿ8�×4øxúÈ�ûè��Õ4�és™Cã~Õhc ™9Ù‹ ~y‘–¶ ¹ŒÏè‘*’4’|D&¹(É0*É’ ã’=§pZ$“4YŽ6y“­1I:i<ð(�a´T@YnùDY”µq”HÉIJ) I) %Qô@ˆ©BFFB�½Ú;q8Á�ý�bÿæadf�öXµöP?·ÀFͶN…ð¾ðÛŒË82 ¹�³W¿ƒãˆà¢K¤k«g€º©»º­û-¯›E'$»´k»¸«-ºF¼ ¾› À+¼¹Q¼Æ‹¼±¼ÌËwÎû¼ó½˜4½ÆS½ìs½c¤½Û[nÝ»�ß �á ãK¾~`¾è«¾÷í Gð¿òK¿øë~ø›úË¿”UYÿkº\LÀKÀ캘»¥À¶{»Þ’»§¶»½û»©kÁ��ÁÄ{¼=�¼lÍës ‘$½›B½Gi½†½*,Ü{Þ+<àFâ+b4\Ã{Ãk´¾:±Ã5ÔÃï+¿ÅÄõÿ+Äø[Ä¡ LÆ¢9Œm– mðÄš Å&Q ³[Å ïÁ¦|Ê<Á—|ÉX Æ=€à ÆbLÆ,!náòšÆåÊÆ{"¯ˆ XqÏÜÎÓTüÓ ~Ü‹‘ÜŒààŠ á®QÒ]áZpáD™árºÝ§ÖÝËøÝžÞ‰4Þ…iâ¦=ÖϜ⠽âìÍßòÞUãZ2ãp×-�¿8žß:~×<OκBNäRqàG^ÏÆmØÊÿ-Áûüäás åž[»aåüˆåÇ©ånÆåÅàåŸ=â^=æ¤}âgnO*îD,Îæîýâð]ô"ç{ךPçõ{çüm×Ñóß|îã~䀎>‚¾„NÜH^Ø >ÔËÍè;áè�îÊTNéûhé‰é-¦éœæN$æ%êeŽÞhnÖjŽÖ-îæTçYâêZë²®�´>"\ñNË’H@T0ïpG°U´-Ì(6Ç)7onóq³;ð‚]»R®?»f³ÓÇ:MQ ÿ <Á÷.­»-ÊL�¸ƒÏFbǪÐÏ[®�UPò&/!òŠ BqøTVÅ`@AåÿZÕ&D6óí1»dˆQpç‰ÒîîôîNï Eïõ~ï:‘ïÚ²ïaÓïqóïRðŸðUlð­�ð ¿ð:Ñð_óðR?ñ¾[ñSrñÚ’ñÒ°ñ§Üñâp¬ä¡Qåš!$oò%�ò_½�B.Q-?SóZ ó3Ÿå˜tó8:ÏJ>/,@Ÿ_5ôZ ïônïøNEú¾Œü®ñO?î/õTñUO ¿ª¯õXÀõãõö™ ö4rInöhoÊjÏöµáö« ÷Ð(÷s¿uo÷èƒ÷½]Á÷~ÿ÷Ñø‚O9�»tøÁ’øBßDD�PFùI/ùKOùMoùyõSÿ¡ù˜/�¯eå:¢OúÄN šÿªÿ ¬�ñɬýyÀñåàñ�ÚöÜÄ:N¸_iRÐà3„ -dXÎáCl% X1ÀEŒZ4n8ðÊG�ÒDŽdÈ�ÀI”8T®×RÛK1eV¤YÓæMœ9uîÌ)À' æÌ� :B㤠,-p䨾¤B£ZÌj‘y´šà:ÀëW®aņýú•ÒY´ Ô®9r¬ yq¡béT×.U¼Ð¨í}K¶ìx�Ó!\x.TBx£-©U+#ÈŒŠwÈò¡Ž9l朗*1С[ŽWÅôé�3<˜aÉ…!JŒhcÿÆÔZ2§²­4Ø�P¦\©rôKm2gòdÞÜùs>¥ ´¨Q-I•2u:Wª/¼V‹am¼µëß¾cÿ@›v­ÚßÒÞÆ•7×î]Ï{©¥7±^ðàÂ; ‹Ä¨Z,šò‹l²Ê.Û�³Î< M4ÒJ;Í´Üt[�µ!\{ 6Ù¢­¶šn»(ÃÝzû(¾à†;©8ã\‚I9 ³ñF¥£Îº¢ŽJŠ©¦žŠjªª¬Šï­õøó«,pštï½#ǢϾºðÒO?%Ï+ë¿Àð°¡90Á<"“¬Ê.Ã,37ó š A«puêñùçRóUu_~wæ `º–õÊ,û³a/6�á_ÿ6b6�•°â —m6O�v㘪?© tDl1"yê¨;¹7Bâ–ºë^Ò–_Öû¹˜×ÅN»w? u^£�.ëçŸ�P|qTõ¥„_PÞœïÕ¤;±rÖ¦þqŸå–{aV2ˆÌzâ­'´˜YŒ� {CÖ:þ8Äe—Mû¢µÛêm�<�»n»G79÷6ž¹¾¯kw»¥àg�ýåÙ+Î?Yœñ¿R]U-É]­/`ËÆ߯n­Þw^©v8Ø4Mï¨M(V½ë‹«Èøõ=£%{Ú†h¯]�Û wºãÝGÐ<ºÝ-RÅ;^q²6;DP‚zÊÕ,xÁ7¹…+áà`«÷ÿ†�#$á�t«¤�+D ñR�jLè+¤! ¶3A¦p‘IU&|¸BV´/¬F[ÖC™t$1x*JœøDDq.xñF5:rdq[äâ5òÄH*k™Gò–Ñ,+o•J@ÝøÆ6šHŽp`¡A F�‚^º =£AÔ0 !IXBF…*d¡ ©CzE�¼á_rȈB¦‡?läYÄ‘QJ\¢ÌÀèÄ(`ŠT©¢7®,Fd‘\좿EUŽQ-eœÇÇ’Æ:­ÑŽ4‘ã0�¹<æq�ê£3(’°’�…<ä©H.ÿ¥°@"#9€IÚpV8Ìa&±ÉLpӑЀ¡ÿ‚D%2‘(§ £±@E+^12²¤å½¨0Ú“ŒfD[¢F“"ÅThCi’̤‚Í|¦|6XÃiаš×Ü�6ÕéIvÆ043 ç+Éi&s¢ó£DtgYà™DyŽ€ž©\%4ZùÊ}j±Ÿÿ h.±0Ð^ô— fBÊP‡:¢¶ÔP€ÄfÎ�`€¤  iÈjâ Oed× É‘J’ƒà2é_Ús–”6ɇéì$KCùÎQÆÓ”§¤)TðéJ}B†Ÿ;ejOçT_Š˜êfR kØ¥ÚAOO]aT§ Í‹ÒÐÿªW­&´*®n³­ŸüfÉzÅõœ•iÇZWúÉ–Žæ¥¥\×LíyWœêU§´ä).ÿºK‚>àt*j¹ûÛ¤&v7Œe…cÇ'–ªŽhËe.pYsdö´!ýæW>û«ÐžõMXâ ÕÊI¯‚´�o€jã S™m—©4À›`X�õ™Éó­¥bo‰JŸvZa,7ü»àؘÂÍ q�Ë´±$—6Ìm.¡+ÝÍR7¬e¹®c²Ûžíò¥»šü.[ÃëV‘|ż¤Œ©zñË^÷Â0¾‘™¯;êkbüÞ¼,‰ªÿrÀæq Ü7“`oQ°D¼\ç>83ÿ�0XA³ž kåÂhÉpÁ¼[ZðvµäýÊjK|_öF1Åð‹éëϾÚV—3Î-ClÌ[ÿ7&=¦óñÖ†¢3¶ÊÜ )“(¨#"É—…ð‡9;aëºè•Õm•ÃreÓ6”!†+‰Ó æ0�yÅ�iñ‹ï[OÓx¿\鯜'UgTßH:Ò�.ž�¬çü7,~N �ó6jã5‹Úc yó²r¼ãT‡y«@«s3\XçeÈc¡µ­Œë­.¹«Èi¯)¬è+ÃÃ~t±#mè�¶´ËÌþòÿ³ë‰bϼwÓŒè4šíkpPg»ÍÜ&õ�¿=gqgœ'Î-CÇ=ž¡0 ªxÉÊç„”ƒ›'ÈG˽¨(Ä|ºN&†áÖã•[­u­aCì¨â  “©|�AEÑÑBï’Ø �1g:xþô0Œ|Ø çà>¬¾Jœ; M"PõóÊÑ(9'ûÆáèñ�ç&äR‡FÉuò”cÜ9,w¹-a.sIOÈæ7ϹÎ3ÁsŸCèÎ:Ήnô³ �!JïpÓcuž³ýrÔ°ð_ª~õ¬§F \_¡×÷ö–ˆý%e'=N8Žö2€<Ìlw»càŽ•ï„îùxyR˜>óz×üæ[â’ßÿÿÞsƒàeð…ÌáQqô¯V#é[Zºã!uŠN]Ê–ÇÕ±®uγÂó”7yè“8öÒ‡¿"§G»êÙËz2iåõ±×Éìk�”Ûç=4{ל`è øàÿ<è¢ËÃÐáQôãK¼ä[¾òi¾¦{>Éîë?ê³¾ÌS�ìÛ>ÐÑÓñ»@òK»ÔX»èk»ô˃õ“»æp?»³=¼8š£¿§ù�û¾‚¾ýÃ.Ãû?Ä£Å[Æ36Çs:ÈKÀ¥©¼²¸<«{À׉@Üš‡¯ë> ü¾Ñ»ÀðËÀŽ3¿TB?þS¿ A9ØAäi9Ú+Aø;AzÓ»Ýó?û;%ü{Aý#<þó?D>ÿñR¾Åc¾Æs¾ìÀÉB’r@ì‹?í;Â$|;ïKðsB�“(L=µ[½fŠ×›“–(¬•ãÂ÷›> Ãù۽Ѹ• ¼á[ÃlC|CÄ9d:´Cª(« ¬>ÌÛÔ@­è Z#ÄÒcµËÊ�\!]ÜE^â%F´Âqȱ‹ó­¹“D/¤D0L>1¼¹Ñp g<‚MÌ?Á‹A  P´ÁŒÃœÃ¦‹ª¨BUÌÃVÔ¼­ãCXÌYô3Z$=[Ô*\ô’]äÅ^œ‡_Á–FSc¿ž0Fûº;(À½e\�f|Fh4Cì“4$>k¬Ál„\«ôÆfGÐjÀq„@ÿsôÃÏ‹EšÅu$»v¼ŸÔÈÅx$�y¤ÇßhÄ`ÄGH”=~\žJTÆKdÆ– È‚£3DÈiTC,> @lEm$Å,ˆ*yŠìIqBWüÇÎÓÈLGRúH�ô sIx,É“¬ÇÑÀG3ª-¬»~4A¨DÁÜSÁòªI‚ŒF4ÜI…4>7$¢Q t2J¤ô�¥ÄC±ÒCr4B6CÂ�DÇŽTG«Ì¸�t­ �’4ÉyôÊ{dI±ŒD²„Éd|Àü‹�|F·ÔÉNìÉ…ʆ|HÂËfJʽœ¾UôKŒ|E©t ªT¢ÃL5\s¶Ò&ƒ€_T6’ ‡ tŽ92ÿ.ÔÀ�x:ƒhH"+Ìthƒ6Pˆã |ˆNäÉ3>"¸Ni\7{ñЇ0JÈIJGÑñOd©k8Oôdõ\ÏD8xOøÌùœÏÙDµÚœ-¸ÍÊM~ÙMiXªDžÎÛÎ(Äã,äL0ådNç#è”΄ä?3±Nì|Kí\’îÈ—ðOñ,ÏAÏô\OõlOßiÉú¤³ûÄŽü!Ü,Ý,#.+ßdB lÅEĦJÐ!XPäjÐæÜÝŒèćé$“ ýÉë$‚ì”5-ÙÐÃèÐF� Ñ81Oµ=QÇC]QkÑ�ÐÏàÏ÷ðOÿUN݉½ˆÕ Òh"Ò}¢UÒ ­šÈ°P(ÅP)5œ‡p”WòP,ÍR• ›øR6ØAIS2 03Õ4US ªQprÓ&dŽ8 €9EÐ3´ÓÈR"5R=ER …K ýS'½P�ÌÐ)uC½"D-Ž,Õ„E}ˆ"7ˆÔÉœÔ2u°K{шÑ!˜Q”üOê»QAìÔ�ÓPýÑQÍFŠRg=Õ™9RHÒ%mUÈÔ(E°í€B…‘C½R\UÔ- ‘^%7`%Fa0Œp£˜*Š«ú>Y‹^i©‡ðÈ›Àˆ’#ÔóÑâ¬V¡¼Ö°ó3mÅn�VõÓp}Õ@�ÕÿA]�Zý•[]‰\Eªœ�#_�W}œW‡ª×6ºW¢È×}U‹~%¯5Ì€½ˆ˜YšýÔ‚¥S„¥K7«¸%$¥†ý4øùV‰eqTr�žÈXÇ~hZ§E¨�Z�Å �…W‘=5’.“}.™Á׫ZYPhYe{Ùª¤Z™¥Ù™µYÔÃYÒ…õÙ"ÝÖTE�ˆ­NŠW>CZ¥Õ ¦uÚ¦�Z©5‘h½��½Ú¬¥×‹°×®MÙ¯å~eu€Å´�Ù(¸\Ì%صÕ¶µÖFx3ZûÙçÔšº-³¢µØ£Õ’¯ØÛ<è[¿\¨�Ú˜%\«Ùà °­EÙPYÇeYÈuYÿÉ…YÊ­\ÌÅ\5±Œ›åÜãô\Ðeظuع…ØÏ´[|RiDŸøÀXtµUñÛ¿…]Ù}×U»Z¬½Ý¤ÊÝÅÝÝÆe�Ç �È-‡É™¨Ü(ÞË=ÞCH^jíÜ„ý\ž ÝçZÒ�^Ó½Û·ÄÞßÐÞâH×áð^~€]D_ùňµ]óý-Ü1yJ�|¥’ð�†„ l]–$’WŠàB.„®@Xa’¥ØÁÝð”#PÆ‹2JÝpx,”7èa¦2¸Tò¹Ö�K Ê“‰ëQœøpAŠß Žb³=” >Ó«òàŽá; Nn9fává€áÌ�aÿVL ‹&F9öá‡â(b7.˜°0bÊHâ�Xb#hbybá•bC*æ¾bðÉâšÛâ.þâ0·1&c3FãŽP㦊!~ã Šct˜c7øáõÂãÔ5>FbnQ@äâ ä²=dY¶Ò`E¶âBÂâýQÊGެHV¹I®ävá4cMfcNÎãeQ&å3å¼åŠTöã+håßpâ’ÔY¾Ý ^�*¶TF®Gá:)a`ã ¡§Kv¥ÿunºv’ÞdhÐçevˆ¦g:N |FCŽ‹i^åÞè‘hÃ%hY6è[ç¨+qÞå†$úe-ctÎ u&fvngg„çd–g�–c�¶g‘~æ|Vf“îgÊ@ P@†`òÕf—žW˜Ö”Eži{Š•îeœæâ‡–äž^j0ªh¦»è¡Öè’†ã£å¤v惃fOægx8b©¦_úµê«þâ¬ææZöæ˜6Všk†ëÒéòåi‰öiŠj‹êwvk§†ërøhl¨gºâ¦>åTÞk¾F[¿þë�ìÃÝjü4ì¯Vš°&gu0瘘ä<úáOs"ø)fÊÎhdÞèÿËþä¸næ{fj’þm¼ÖkmÒ†]ÓYÔžTÕvQÖö)ÄæeØ–m íÚžè‡Ý 2.ãÝ&jß6êÌFêÍióìâm¨ÑVî(mÓ~î(Žî®>l×Nìë†èÙãÚ®ãÛŽøùî@`ëÊîí·îò–ëóVêô¾ãÏŽfTnï÷VnùþkúŽâ  ROí0 ¨°D{óŠqØ«m ßz®çë Š\ 9È�œêyR"X¡šÚ?È   ,dp‰8øñ !!rñp©°Ìp%Ç‘ Šgƒÿ,qbÐLGñwƒ�³ç—R·+ýk‹±ÈqÿqØq9òq Ï�!'ò"/†#w×%¯sJir xò(ו—É/¯+¯Ü,×òïröúò÷óëó{*s@â 4Wó‘Y�w€ s2ˆs9w‘j±sO·<×ó¤ñ)÷ó*/‹Ÿ-ú%pzš¨>‚œàPôg…WÇtÇÂ57”J¿ô7×tp™OúütbgŽP� u)§r+WõÊeõSrõ ‚uØ�uF‡A3‹H×õIïu7Çt`wa—Ïb/w�8v;Hv¤ ufGõ@G[h#i· j/ k§u2ŸÆlÇñ\G¹]§ô6O LÏô8öq7w„· tW÷ `wSoöYÚ¢ÿUÿîV—ò¼t�à蟑ñkwô[7�m÷÷I?_‡ó"7xaOx•§ˆ…‡reçóRÇLDôÙ"ðx"R¿ø²ÑÆŸáx|ot}t�ïwtøw’ÿö7gN¥oƒhz§÷lXy•où=Ÿ‹v1·yŠ�v‹?MÉxêÙx1ÿylú�/ú‘7”’ò¥gN§úƒ—z„§ú—·ú‡w÷š×z®x˜×yþÁÁ°ÿŸ¯õ}Çõ4çölY’ø¶gú·_¨—û¹çpdwùu_ö»Çú¼×û@àû¹ðûm#Àž{Â7{¢7zÅ_�InüLJü¸—üb§ûˇù«'ñ¬çüÎçú¾÷zÿŒ‡ �|ÒÏw·(~?|‘OüÔ7”ÕoûÖ�|Ø/wÅåê�à<ñ~õ0>TÐ&mBQÏ¢]›<ýøP5c>¹&A’%Y”ç�àçþè_mê×hë·ì×þâ~¹ñþuÿ½j*h°Â„C2Œæða¸ˆÉQ¬ˆ ÆŒ7b àñ#Ç�"G’,iò$Ê”*W²léò%L‘ fš«9b„–œZ ð„Š•‚ Ð†:s&í¨4J•€TT=¦RíÙ“Ö¬€¶rêµ°b4X0¡B† B”±¢Å•AƬk÷.Þ¼z÷òÅ83AMs7uîìù3¨¯E‘ÿ&]j¢éÓ¨T«Z…’U+×­_‡æé왬@³gÑ cú4[‡nßÂ%w±/ìØ²gÓ®óoàÁ:­JÔ(RÇ��F•:¹GeË— eÞÚè9tÏŸA‹ÖDºôiÓ©£­·à;ø×¶Ç“/oþnkdŽÎÊ�¤—Ýš«t»Š“é¯À(l§ bP,²åšëå éÚ±.»¸û.ñʻݒØ{/=ùê[¿ý^Kâ½÷Ž30ÁÜ<Ò\ýõWœû0㦻»í¾ë®¼ó¦VoÀÛÛo¿& ÷XÇ|pÄ)«¼2W¼ÿîÅg̽{Ü1ÈüŠÌaÉ&�c07, =ô±.¿ó3Ó¼±Í7;=ÀÎôõl2ÐD[}5 FWŒ´Ò5ÿ÷ôÓQ«Ùñ6e›]5Öi«¡Ö_Ü5Ó_ƒ}³ØL‘mvÙh¯½7ßæ ò7àH§18áa~8Çsw\7Éã]vß‘Knà€á…nøvŠ{̸Ç�o39é¥ïUùß—×”ùà›sžšç‹8rè�›~;î/¡>ˆêæ°ž†ëatû½Œ—s<ò¢ç¾<ó&íÞûïÁoÇØQŠ�üñÊ7¿=÷=¯zô®OO½õ³ ‡}ö¶w¿>û}ñËÿû-õÛO½4&Øÿ�¶Z6Ü>™÷¾šÈo~¬³ßý¨§?Ðt|`#Àš£€ñ£o�¿’¥�t CØ= Z� Dà4 -}„"|áòHhÁ&�1 [ÃÞN†¤aýR(�¨…à!'×°†ñ™B£Ø°~0‰VäÛ¶»|p±‹OŒ"§XD^±ŒXËâ\¶ØE.~Œb\�Í(G¢¡ñ#j\c¥˜0*BpŽ~TY=rG/Þ ŒaÜã«øÇE>,�$ iÈ7‚'ŽŒ¼$&3©ÉMr²“žü$(C)ÊQ’²”¦<%*S©ÊU²²•®|%,c)ËYÒ²ÿ–¶¼%.s©Ë]ò²—¾ü%0ƒ)Ìa³˜Æ<&2“©Ìe2³™Î|&4£)ÍiR³šÖ¼&6³©Ímr³›Þü&8Ã)Îq’³œæ<':Ó)›†ínwFÔ’:EÉÎvVî�0Šg(çIÏ¿ÙsAø¥>÷ÙOðüó“¥ç@¿SPO´� ]ÀB5)€‰64½è!2ªQxF“@ÃÊ Ò‘^£Í(G;ÊÈ�†t¤"-©EOŠÒ{ªt¥uNsêÒ—ÂT¦‡PZMm*€œêt§0 „O•¦½ Zñ£DÅéNËpÔ¤Îl©L `ÞꆛpuGýXÃ*V°Ò¡¬fÅZÓú G^ÕFYÿ}jWo’œ±Òõf=kZѺÖ@¶µFo%j\G0׺Šõ®eÍ«^ÄÖ¾Îè¯9 ì` KVÃ" {­#c›0pYCi‘•¬aéPY�¶´åYlf/ûÎz¶2’ khG[ZÒž–¯©½,xX;³Ï6¶ˆ�-ieÔÞ=É-¸ZkºZ¡¹ÎÕ—¾d;[áÖ†¸Å5Ïq¿£ÛŒñöÎ}.té!ÝÒR—6Ö½.y²»€íÊ+9„ÉÉw›^ñþ¸åÝK¦Î‹Þáz¹ÂRnOÞ«…øZa¾Ý®î»l0¸ÁAx0„3… S¸[¾úß~ÍÛ_í&w·•0� ¼+X% v0ÿ„,a OØÂÀp†aãÀlÐ8�J«¼ `€ð8%/=´å³qt§F¶’ë¡ä¿pDKâ2’Òt,e$çev˜ØÄ6“çeÆ5¾1Zs¼ãÿX¾ù²ÏFfäj ÙJ®“7âdPAyfSÖq•_†åti9\Æ‹—i f,ˆ¹Ç>¶ �Ñl259ÉKÞ²œaôä"EùÎy®ØžWÐç?ß%Ð6¶Žã¥cC—¹ÀgÞÕ�ÍfGÃÒ™3Ÿêœ1Có89¡ýݦ9]OºÐdF´™ƒ¼+�©ºÍoŽó«% ª;à>´Ž€­ ‹k-ëzרñ§CÍ�Qÿº€‰vÇŠÿÍjdgÖXb¶³ií»N{aÕŽ ¯AfQ�™ÇòÓè|‡Llá¬ÙØ�ö3F´ä©Ÿœè>γ×mÖß±£áïâ»[omsÛÞñÃwxõn~7ÚÍÿ.7Œ^pƒß9݆VxYîð†C<â+™ø¼·]ïC³ãÐÕxÀÄíñVïÔÈI>e“÷åtPùÊ[îò”ÀœÐô&õÅ3šoŸíÛ1ý·«n� |2 ¯Ì­Y·r–sqé*iº¯-^s©gœê·zÇ��õ�}ä]§Ê³­öÌ��J7»IÐþônÛ\_8¿—ÎåÞs­s½ä§µÞ¥-ö±ÿðqà‰,rÿV¡ó¿#Ü5B/úÖ�Ãck^ó9R¯ú7¿9óØàlП-à O‹•íÏ›ì†�NÔò—G€ë7ßù#|~p¢}wLúj¨^õ~Ê<ìG.û÷Ò~Z·oNî�»{Þû>#˜‡~Ý9ïùâ?ôÉïØò™ßüs<ÿÄÑ/øô SýY]?3ÙŸíö?Ú}Œ|ßýá~ñ¥Aù]ÃùLúiUû5g=[üéÄüAJw€Nàý•VþõÞþõŸþßø}Þà½àS% æ� ÒÚì�\íEàJ 1¼ Þƒ Îà Àþ€–àÖý’_ù� ½ˆ Q‘àë™à öX Ü ®F ºÿ ¾à Ò ïÙ`Ÿ]ê‹èLwxƒ~á.„¡" ¨0XZ ßð!�éKÐu ¶àBaÞC Þ`ÿmÁea¾láÀtáz¡Žá–!6œ!�›áùŒ2aÆ!1Ì!N¡Zaî`Áé!=ð!‘­Æb î.Hƒ"&¢©Ý#6¢D4!@¢$Öan &æañiaèq¡'~b(Šâ ’¢¢Õ!"â ®a¾ +¶â#Æa,Râ,^áÈi"'úáöâ(†G0bÁ0¢âÔ™L2F„+ÂâÊb÷ÝaøÙâçáâ5è¢[|¢7Xã/bc! ã!rcÛy ã7†#3Ž£3ªD@!ù,:*züÿH° Áƒ*\Ȱ¡Ã‡#JœèP€Å‹æ2jtàà„ÇìBŠÔG²d·“(½©\Ù§¥Ë?0cÊ›I³�Mw83éôÀ3‚ÏŸü‚ -E´èÊ£HÏ)]­©SP£6šJ štXÓqã–­+7tèÖ‰Kv¬¶³Óª]˶­Û·p ^Ĩ1#Ç� E†,iåI¤Þ\¾Œ “fÍ›9wöüéSèТD^ÊÔiÓ¨R©NµšU+W¯`ËŠ{V[ÜÓ¨S«^­z®Åºv;~Ô»—¯>¿‘ nI¸°ay6Ûát§3OŒ;æ9²ä£”•Z¾Œ‡æÍW³níšíkØÑeK³ÿO¾¼yò®À6ww6mÛ·qÞݧ÷ŸßÀWŒ<ùræÍ=]tåh`uÖ]Ç™vŸuxd‰wÞ„VháBé­×žG´±nÝÌ·›}ø7\qÇ%ÁҴ袀+EwŽ�Vw]# bµhßAHZ)ä�¬eÛ†yéõ¡|º�Ø[‰ú¡¸c,ºØ"Œ*ÉHc�Þ˜£gÜyç£Y@iæ™hJdd]Hv¸¤_+�"'}$þ\pŧb•Vbé�–[v©`v:6˜Íƒà•&ašŒ6ê¨@kn$‡ïÙ& œ p¢é¦uv§Myê$Ψ¤Žcê©V^‰%~[–ƒ 3°ÆÿúåV´Š ¡¢e>ªë®F^nZú¦›rú¤�Ÿ†š ©¥žjjªÒøÉj ÕÅ*+¡žÕŠèh¸šÆkšØ„+î¸á~W>è¦kǺìvˆä"ðÆ+ã¥r«©øæ‹à§í(Ëì¨Î>›*`Ç7-�Ô$¬°µ°ÎZ«­‰âjîjTl±A[LîÆØtàñÇ?”qÅéªËîºîNzB¼òFGo¦öæ«ouüúûoÀã@KpÁl Â 3ì°¶=r+qȨ�Æ#sLîÇ #Í�Ò%£{2Ê´½Ëò"ó[oÌ2ë±o²¡þ+Î:#ÅsÏ¿µ t ;34­ÛŠÖ­Ô ¥7ÈÞ|»ÿá÷ßUç³Âà„Cíq·sÓ-Œ7Ž@‘®)Í7ß Tnùå•O¾7œw.Èç «¨¢¤—:耤. Œ B;Àë°GÜ>´×n6‚Õä®ûJñ’áûïø}#üð.Úc¼Œ:$Oë6Ì7¯ÎófµÀôxcèšæƒü xÕ„n8â‰?ìxã�Ï%¹æ˜§Ÿö�{~º ¢'Wºéï§Èêѵž*ì±C5{í´»]ut·;•ôîw¾ Þð„W¼ãE'y:X^ó˜÷©¨Pne”lŒÜȰ§M¬’•®l%,é8ËZÞ’‡Kñ¡‹€8€?2˜Pæ!‹™ÿH'>‘‘TŒ ¯ÍÑlQƒÔ¬¦kÎÀІvˆ“�<£7E©FR àjv(g9Ï©Êt¶Ò ©1g˜ô¤4LJ²�õ‘ü dÜ£;?Øtk‹@…NwJR %R”âRâ@ÔÄ5,E+K3hÉ„$= uèCõRN‰N4�ŠZck\ƒQ�j“£)ð¨B*R&ª hMëIQú>•æÆo£†Ky ÓOÉ”a4Í�Mý€Ó�òt&>PƒÚÈs5FeR!´T¦"Ô©�ZhTÏ0UªjÓªçVçÒU¯¦’£b%+HGšœ´ªu­ H)RV ×·Íõ‡@Œ)gŠ”šÿÞtk~ÕiOGõÓ“¶°‡Mì6 žÆ2²�êd++’ª‚òªµÒljÒÓYÏš´­HËÓ¢µ ˜‡xÇëÖ©$®¯u8ÖË^Ù�¶G±-_q›ÛÝŠ£·ÝøíP‹ú°£Ö�,Æmj±—�x²”e.;œÛ͇YUº¡ZÕ\]Ï‚5´¢5&6Ìaïb¼ã%ïjߊÞë°÷Ä(æW=VÌbø®D¾}­/`y+Xßv¿ˆí¯bÿ;–Osƒ6p�¬à_ö¹ÑE2E³º —ŒÂW³.G.œÝ 3‘Ãö.ˆC<�ò®¤ÄšA±˜Á¡b¯ØÅ*�1}ýj_üêWÿ)ÁÕñpy,?öLØ#ãöÌg2–“ €´XqjÌHv«3XA*Riu±ˆ¤‡ŒD¦ ^<hA{Ô˜bÈ´¦×&VðBãÓ ÖçQ@„„R›:lz ‡ªW=œáä!-É=fMkqy ȵ®=Áë^óë‰ßˆâAl]w«‚‹¢ÁâØ;›)Ï"äsŸEøçJ³aÐ[+ô�èe£ƒÑS“k ½\IOÚÚ×¾45½ižuµ 5Ë‹SŸ:l«fu«ÝñêX“„ÖµÆÍ­u½ë^óú×O6nˆcã ÙY$‹·›Í(hwOÚ{ö³6Ñ�m–i{‚ÜÁ½4G�[„‘ÿÖˤOÀqu#�Ý™æ´G=ohˆz%¤¶7P�oUï›ß¹õ·>>k[s™à¹6øÁ?l…û…áWÄ-X–‰;¶âšÓ3Æ5ŽÊ–§“ÐL44®�Ž‘o¥Ñy4ÊË­òs[[¬˜†¹ÌÓIóxß\%9·7Ï{þó~ƒTÖD7zˆ‘¥{á t:J žëcC\4V?nš,N8Œo§Õ®tLj@±+ŠìfçÚ¢öî¥\$+÷º+q s1ÌÝ•à="é}�ïß|ß·ß x€ ~¼„7<âñëtƃÀñȆü²)>ù¬S[›˜ß¸µ= öÎo{ìÝ^6ÉÅ=Â!XªmÇ ÿº©¿µÖ¿¾•±à¼GìÛ‹¦çäè{ÐÿþïÀ üèH>Ó®ønùÉ&‘'`Cr|c`RæÑ‡JÚåaôñ;iåy¥z˦4ܧßÇv¨7iX¶aäÇ2æÇ3À$X‚²W@G1Ñ`jò‡ †ƒðAt÷"Vp†wxŸb?öÓþWl�÷p�WuËwufb€Î×=å„SGЄNØ€Þõ€awE×P…VH�Šf�&×}ƒ“� ¦4Ô�ð�ñÒzÀ6‚%H‚'˜;€¡‚îWiH‚/ƒ†0ƒDG7˜t¼‡áÀ/<˜: BÆg„ˆS§|ŠÆ|D‚„“£uÒÿÆ„NØ„Ú%VRh}d…W˜}Y82ÜwäU†¸yðb†g¸@|¸††”‚Óa{¨Æ‡s(ƒ¶Aƒxè]8ȇ~ø‡�¸ƒXˆ†8„W„’·ˆAyƒcy�‰“èQ•ø;ö�‰Uˆ À¦…iwrÝc$$ŠXFŠ‹ð§ˆŠqˆ bfäXŽn¨s¯‡&°Žì¸Ste�òX‹¦u‹áXÚ%ˆ@¾ˆ‚ ÿ¡ˆXŒIXy—ŒO(Z”¸ÆôŒÐ(�O¤4ðaf+¶1¥G8Øh8ÚÈaÜè�ß(<©XãXŽäxŽz6|ÈŽí¨Sïhò8�»‘‡…·‡÷ˆùÿ¸�¼Ø�ÿ�ÕñðëA�§Áˆ|ãˆ|¦�’È�Ìè�L‘˜(‘ D‘¶a‘õ€‘Ö¨‘‘�ï#†¹!)’7%i’(yo2³’,iî(‹|“ñH�ie�iˆ 9)ZüØp¹Ö“>@”|1”œÍ–BÜ&rIÍcRИŽI�™a0™”I¯Æ/?g•¿"‘KH¹gÖ-¸"†îe;fs3s#~rk=К®ùjBˆ4p~Ñ¥°dÖ�›ºùsü�×0ÑÁp w™Ÿršÿò[¿Ek¡•¨Q˜ãs˜^‘˜Š¹ Œé˜�™’I™“i™¹…™û¦™„Å™Wÿä™Ñ†q¡)š¥AšvLÆI*7r#¿¬éš­ ›Õ!›³Yƒ¸a›¸©›¹É›Ÿâ›ÀIÂIlÄy'íI*ÈIXÊ™ÌyÎé8ÐÙÒ©˜Õi�Ø ™Ú¹�»q &ò�¹™¸Ñ™2ô™pžè© êy'÷” âðž×ŸH1ŸôiŸ˜�Ÿ³ "üùMgáŸÿ¹o½ �ºj.* T jJ˜Ž…Yª]ú˜º¡aÀ�~Å/ÿØ5G‘�$Ú>&Š¢g¡ü¢ìÉ,ki7"2z4êšübx8*¢~IKöÃ'<µÐ§~:¤JñjGÚfã¦Kjj &±ðg›û­{¯A¥±óбk« «t"+«Ý@²´j²(*û®ñj< °¶lûjðg6|(³ÈI³qa³è‰³H§³RÀ³¡â³­æ€z°w’°K±°G+ZI hK«(Mû´JÇ/QÛSË’à:XW;®«µ$P¶6²D7²ŸV²XŹíp¶¹ lÛ¶¹õ¶ÿ·V»¤t v+šxKpzË·yâ·Ã¸‚‘ºk‹©…¨©*q—d•¸lPKÚÕ¸Þµ='µÓa±š!·X«¹›Ëµw⹺Рº¥Aº¦««Gÿá» à¶=·q(·É9kQ³ß“¢gQ»ºv»¢Õ³¹õs¼ëâ+f„«†ËƒH s膼¢¥¼¦Å¼ùæ¼–½T!½˜›µšKºØKkÚ˽gá½O´²¨ë»ä›o曆èË ê›ì 5îû¾“³:‹»Å¡»8q¿-‘¿(¶¿çпöó¿ìÀ8”¼>긹Í+¹ÏKµÑûºÆ3½l½ÁÁ³6Ác;ºHlß ¯H!¾¼j\‚̤!llÑ8âÂ¥ÑÕNÊlá‚áX²á>Na­p·Ö-ÙlÿqÞsKtI€=À¶¦.>ß1>YaDãaã»­ßöüÛ?í߀-Ø@î,‚2ä¹ÃZF~äŒ�äöÂä©á.ÿ*áÇ\ÝgJŽÝ[}åÜÍÙw‚[.l]Ž+_Þa¾Ä3KæÞdæYŽæO¤æòýâmUo>˜j!ç;ÍÛ=mç�åzžoŽ7Bäæu‚>è(¦ä†n%ˆž ¨F{Ý0å>þè—�Ý0‚å•þ—þ{âåå¤ æË!æé pó¯Ìsæò�æ-~êl¾b¶ê“Ê°Êø=篬ãÀÍãÂýì?nëAŽëþçE®½NèÅì›Í^IZìì‡È.ïÊŽÙâìÁaé+æt™®(›Þé%þéÚN.ܾ Þî,¹æµ�ê eî£Ϫ,Ϻýêtëî~çðþßòض¼ç§ÒçTÿ¡ë€±ï¿^èoÕä'ðacì¿ð3qðÌžð“îíÑ~!Fíd}'»D·íšñ¥îôâ0NînþApÞ�ó1:�Fü�›i%âÌÆ[‡7Ûwç ÄÐön/fàõ r?÷°–°3¬?öAQö±¿%³¯µ?{H�ûm÷¨Ï$` Á ¿-×Ða9ˆH$J£X±ÚEŒÞ¼uãØ­ÁG�àDŽ”WÒ$,úTê»wïÜËsez›WSÁM“&Ûí4YÆçÏ–AïÍÔ¨ÃèQ~I•æ,¹³�I+Q¥Ú£ZÕª½{+´nÍÖÕ+7°a·�%ëÉìY"iÕ²cÛ¶ß[¸Wåbz/À]¼ôîåÛ×ï_À~ îPØ«6ÄaƒE¬ÍÚc”X”:¥¼ÓáCˆ™‰zkÔÙsС1f$JÌôipŒT3ÇTÞ@‚*dxY\ÿf‰Hd}QcÇn›G’dŠr%K—07לwS�k§=ú¬;”èÑ£�µ[ƒÎ³¤Ô©s«fݪUð`ôdËž5«vm[¶pãŠ_oÞÀùõëG_¸ÃáÄ «1í"›¬2§l»-3ˆ6Ž£ÐDëm³ÞªImµÖ˜ºfC ’-¡úFAÜ$ÚÍ„ ëH¸á2Ìɸ•Z‚)&¢˜s®»§\+©º»qæG ·{ G¨À³‚>ªª»ç<ôšt²É|¢”¾øäëÉ$í»/€ýºôr¯þ ëª12#2”D°,ÇÁ#-E¢*¼P5Mâ°ÃÝ@±Írr;‘NàXÎ5U’ÿQ¹m‰©èt”‡Ç� RH"¿3K%™|òÓÁ¤œ’J+¯äTËû¾T•?ÂÄÌ†ÌÆÌD¬À4“ZÓ2ÛÜ|“¨åÌ£Â>‚ÖÎÕXsmÏ =<DÌMÐÝ$¬FEŽ6óŒ¸SŠ1¹—–sT²tªÌµmïéÑÒ…´f©¦ÆÕÔŠzâ¯Ó¾@µQ£¤’�Rå*O«-ærU‚™ô@Xeu MÉl½UÁêàŽ9æ °øba‡ííNc5DVÙÙ˜uöYÝ¢�Ó·�V$êZ‘ÕVQniœÉÆ›Âm—2ra6·RtÕeW‹„WÞ¹èåë^PóÍgßR•þw�·,xj0[ýÿoÌäæLk txMˆë’¸#ŠkºãŒû°³Åc?î“ÙF~öDi© nåΰ=éeäfô¶¹šÇg¦Ê=·g!úÝxë™·:O‘FOi¦­túߨS¥zê0¯~5k¹öšŸHs¢çtÔ#æõÁ²ç9Ûâ´ÕÞ˜m�÷Ù¸€ewÞI.Y¶ºS®ïFô.)Ѿ�ù[›�v7'Ãy¶Ôç¤/]ªÆ¯+rÉñÍwðÃO`|ò///sü6'¸s„µflV†Õt õÔÅ^}â²_/ öµ­�ÏÁ�w½#ÝN6-áÝm&,ËÓñø¶¨n5 pàÜÍJg’è]Π?¬çÿy`�hr1ZÕº7¹ï…|ä+_¾ž†¾»¨¯`ìÚ6Ü·5øu­V¤¡Ièw:ÕͤG­Óÿf翜 ë·ËÝwç;þ e…"žñä�<ÊL&4£à6>˜#èéìpÓK\õ,B:®h�«× Q(*®�… 0ßV`80zi{äãaeÃŨ+2‘q�‚~H�ê�°.�kÜùÈ0DR’Úù™õÜáŽË@$ᨈ4Nsš Ê„£,–j6yÊpLC•µ`eG0â™Fà D(lY!²®&‚ॺθ“KºuÐ æÎT6“x$“’füåN"S.ú4ÎRËãæVÍ©ÿõ±�� ‰ò‡‰¼JuüãŸGBR’‘\¦!å”Kf²›ìä'MJ�Œ’¥d*7©Êi°²®¼,eIËÓÙ¸ÜÌwÙKL9¯2Áf1´™dÆ£�9¹Õ3uÍxMSsØ$iIõ¨M?&,�Bú&8+#Nú‘Ó*æùéÏT®²•y¥gÊ”ZÞr uèUî<™+ 纫‘n@—Ú�¦væ©Ù¥‡BJUï ¼ž í%+úÕ‹µêUm;ÐÚZñH¾òeñæè[W­‰%8Ú­8œ³_ßú·0^©q kÉä.¨ÍM°(IùX¦DöÁÿŽ%v}¨Ý 74æD‡ÉÓ£7£•ìh{Õšâ�®¸Åc^Õ‹»rCc�Ƹ²ñMpŒ%¥—ÇŠI­n ,äÙÈÔhQå¡dêBغvrI¢º]çNyÃV>di1šÑdryM'v/˜Ù*f2gz?f¶­ûÒ¼f65䯽…s¾äØwÀA^n'õœÏQö¹Á’­.e¯‹Ð g¶»Õð¢ÅÛѦ.˧…t<$� Jy.*©¦��N£9‡„|'e2jFú6Î5�sXê dyÁ¯Ö§¬“<ÝÉV׿.†yMeF�sØ)¶±ËÚå—¡xÙanö³ýÝ—h{zÚ3®vÿ�±�½R‹êÔêIõ�‘î<“;Ö´Ë  Ó}ëËæÑ»¶êw}½¦`qÞÞ¨÷±+“ì÷öûß+xŒ®æ‚³ùà}϶‹ê x«¬6°«%ÎgŠ›ÄâµVwÆÙ�èwA!GäÈK~ïI{9ån]9‹†¬g½Û`A×½j=„]ìÇQ‰oÉ®¿ BíkÐp¯*v×3˜HíÑØ8Â;ä}q9Q¨B7x]¸FD �ÑKzij ¨Ïä`|ãsà È^‹1Bå-/"�$†à|çeZ•ÆQ½ê™¾zÖ±¾unxýë1o‡ØÇNv³“=íkW{Ûûö°Ç]îî ûÈ{ÿ„w½?Ï$}·åß x¦ Þ–’?<âߢÆ;^"�ç„ä7cùËcþšÿHç=_¹„¶£wvéM�zÕwì®×ÃÙcœÙÓÞöêÁ½t/÷ÞŸW&¿ß]Þ°÷á#>ãk2äË åæ{Äó„çŽèc¼Ç‹¼Â»>ì3íÛ>îó>Îû<ª?<"?ÒÛÓÃ:2(A4LÁô×Èök?²‹#„kê ÚS;4A·ã%±;‘ÜAªéð ýY",Bàc€q â…”%È�”<%Z@¨B+ì3Xꌬ¾ÂÓ/ü ´@íã¾Ð@C˜Á8ò@,¿-)Âÿ"ÌÁLAL?ßqAö 4T¡ä‹D8$9DÁúóA¸ B7\„#<'tÂ@4€&”%(\…(€šBijB+ì$ŠÈÂFØÂ EQüB0¬Àê C3ÌÃðQÃ5 ÁûHÄEøÃG\Á:„›ÄCU¤ALëCY ÄA|f1Äé@D7\ÄÝhDYzÄH|B¸9@KT%LdM¬BN”OEQ ERôÂ0<Å ÔÀ\VlÅ1 XìE9ô:4XÇZd±“\TÅ=Ü‹µû tLÁ_  `Ü$… Â2 F#쿼cDd|Ä«OœDÌ{ÆiˆÆ³˜F¨Ækœ>ÈËFmÜÆÿn¬ 2ŒÇ<œGr”/sLÄ{DAudG’±C=€Ç- G�€zô‰‘4€|\–BäG[òG€$Bc” dăä%„ÌB…†T¢ž„H‰ÌBlÌÆmÔ‚ŒŠ�\É\lÉ�Œ­�tØ,I4hGyÇ(áH4lÉ—,ƒ˜œÉ�‘SêÇC|XÜɃèÉŸ„ „¥¡\ˆ¢D–£œÆ¤„¥¥EŒ4E�ä>°œAª¬J¸ºÊ7„ÃYìºuÜÊ“´Å°SÉû`É]T;{TL_äÁ°#Ä} µF¶LD·4¸ÌL¹ü‘„lFí»Ë=ÉKMÜKÏèË‹$ŨMÛ¬¥L,LÃ4© øMà%Óˆ3¥’45ÀhÉ8•ÓÞ¤Ó°S+ÀÓ‹ÑÓåS¸±QÕQ$T_5TDUÔE ÕQÒH•ÔI•‚JµÔ*ÍT,åTOÕ#Ó\%Ui1Õ²AÓºPÓUåÕtÕ9UQÎcQ!ÍS½UÇ”ˆ>ýÓ@½AõUR,W‹É©0 >êsÔƒ€ÔH¥ý×e�€G\BMÝÔ-åÒ?$ÖÐUR5ÓlEÕmUÕ¿`Õñ×ÿp­Óq½Szµ[½*\e]ToÅ x%T`�×D½{ÅWÈÓWƒà×&ýW€]Ö�%¾‚…V„…C… †%S‡¥˜} n�XoµXW…UY¥UŽ=W�MW­V?ÝUAíÕ’Á“5€�]Y–uY€Y&•Y Øší»›=X÷HØiU¨µÖŸeŽ Ý’¡õ ŠýV£­J¤ÍØYÝØèXuÚu•Zw½ >âÑG,Ü@ÌÚœbYNˆÐPÒqxܘ[JØ@\Š(ÛNM ´… jYk-Õ‹˜£Ò-]Þ܋ӭ[ú¼[C ×”­U¦íÛã„ZvõÖÁAÃÍ]¬}ÝÐZ|e\ÿÐp\ÈýZÉ}Ò)[…º\MÅY"øCý©�žõ• ÝÒ5]å‹ÔU]Ãd]×uÑØ„�‘�m×ŠÕ ¼¸]ÓÓ]ÃEÜuR\àÍá‡È•ÙÉE^[RÞg5[ç}è]Û†í ê­^ÈÞìÕÞ�ä^�åݽýÞðMˆñµÝ=ZT"UßÂe_Ir_$ ÞG}\ù%^ú5^)µ_PÀßaÞý=› ©_‘‹³ àê%àë5àí×ÖM`ïÝS¿¥]À-_8ß–` ~D Ž$ S ÞWžß­ßÊ%>Þ †ÃçMáÑx¿•paëU9¹�a>`î^sÅáÙõܨÙ© >’àÿ9âÃå]ߥ¾÷�_%öW&–CË¥ÌU‹¾*®b,iá9àæâ&ä.Áñùן˜\{u瀖!±kR¿.34+ÐØdNîOþdPåp¤«R¨ >bÒ|\Ó Ÿµ; E•�$@˜eZˆO:±3TÝe^æ@{د>daÞ�Dö×EáhdGVHÞ I;Jî KÖÀ=¶NîdQÎfO&e^2e#FeÀUÎ:VöWW†åz•eZže[> \;]æey®Íêæa¾ç‚)f8fe•Reväf–�gÖƒhæ‹iö¾j.€kÞdmÖfno.Vžgÿ¬+g8ç/Œå0Xgv~†[Þ�\þÑyžçz6d|>iUÑg~žÒ~dÁÒ�.è½8èÎKè…ö€†Î懎èÆ�èqXeðiåWÎètÞhŽngÓxg=0TéÚ|!“Fi©Ö•ö FΩefæ—ŽäIfÒJ®)3´é…ÎiQÞi[:eøõi ¡FçÞUçuFjbPj¦Ž#A–A¨Öâ©Þk/©ê2¸êuÊê€>ˆ˜öjikj–â×¹i²e³´>FŠÆ‹Æh/Ôh@‰ZöhwixþQ¼ë8ÊëVåkÓ ¿XIº*ç€×.Xƒ €c ‚¯>'!Vì³Q"QþÞÖéÿ#(å³þæ´~ËÉ–AËÖý‰ŒÍþhÙimÆk̉êÓ6íÔ^ÖÕæ¥Ö~mØ–ícÅðïK½íÄd%ê3ÞþßnÈnÉþirŽ£ãNnÍîhæ>ç†îê•îó¡îêÞëë®Ôì„í†Ø6ïŽÔðï*%o4odAïÞ.ëßîæà–hâ†ïŠ–ï¡¾ì×áh@�kºm»ŽîÑžn½þo€géHbí›pmïîÙ^pðï6.o#9ïIïõ¶ðöÆðTÖpÊæp·¾qÏ^jW!ÑV!Òæá_ñ÷ç×îçî‚Mð&µqlÀq9üCß Wo gïÿÈVëøV¡ùþð£ælÓ¨Æü.ñý>ñþNñ)?í*Oæ+'ð,Ÿñ-¯qsDÕqðàñáðñ3ò4ÏðµŸ6?›$‡sb�óÏ~n:/]þ¶#ÿÎó{jcö 9�ƒ<-Á"õfáçpø£K}$¥µ˜d•%'<ÿó¿4PAøÓT?‘Ùõdaö(vcW’mõte�-PßgQ'õZ5u"Eu®]uXiuGzõˆõY_ˆZß�[Ï»\—I^âu9ñõcõ‹`va7öcGö X�eŸw“jöŸõR'ƒSîTnƒ°v2Áö#ÐvnGZ—%[÷q¿*srƒ˜mu·HÿvowwOx�wzÏøj²÷gÏ÷}oï~ß €o �'ødíöoøvÙwXør¿Ñ^ß ˆ×�‰gƒŠ·ø‹Ï �ßùÍáø2À÷h×÷iç÷jÏ£?ú’×Ûm?yƒ÷v„w…?Arßu˜?w™Owý�Á›/éû�wžÿúUñy çXiŸTï$U?z¤¯RWWú‚ß“ƒÇ�„¿u—§úRˆyÙ(Ãέ¯x®Ç ¯{Áß±‡v²z³çw´÷wµ7z{Mè·Odœ{\—z†¯z‡7½§í¬�£›�òüÁ/ý¿(|�z�_|‘üLˆ|ܾ˜É¿ÐʇzºÇü—¿{«ÏûÿÕØûÀØM¸EqÀ7}â÷ Ôú�ßž>Ç|ØÏAý™ýkèIËwÜ·{¼?ˆ™ç{ þ;þâ8þÃO~´N{çÏ)17’CB*êß�¦¬û†_~íÇzî/Ñ®þ» }ñ,hð „ 2lèpÐ ËP”#§Æd6Îéêã³�yF’4aÒd¸L*W†iér#L2VfÒ¤góf¸œ:qðìIí'P-B‡Æ4`@ÒRJŸ‘ h�¨RB¬:(Ö¬+¶rͪÕ!ذbÇ’-kö,Ú´ !J¤A±ŒÅŒ9z)²iž“(W²tÙ2æFš5oÚÔ¹³'ϧ?‡ÿ…i© ¥¥˜6ULMêÔ…V!zÅʵkçjG“.mú4ê´¸¾õàú5L²Ñù¬îÜ'ðþäûw„àÂ�/NØæ¸äÊõš$æüy´èù¦Ÿ¨n=ö쌅vëîýøðR“/oþ<úôbWomýÚuìÙµCæÖm’÷€ßÀ…/nü¸rË1÷tÒQg]uÙi·�wß…ÞxêI8!…ZÈ{+¸÷^|Јmõá¶[oú}Â_þq=&Çœ :]4Óåƒ`‚ ¦°� v÷ „ 9$‘E’–ᆰm$›‡óÝ&"‰ù™ˆb*® ‹0ÊH �6&ð%˜:îÈÿ �@Þ¡‘iª¹&›HRô|KÊ"}PÞW¢~TZÉ"~øi)c—Ó�¦Ž<úØÍfW±¹(£�JèfpzÐá‡!Úi~&žˆâžÇõÉÛŸšÏ _Ši¨�‰¢é(«­ºjV†\Ù1«’1}ø!�öé¥i9½úú °Á–Ó§„úœ�^–zêv‰ªú*´ÑJ‹P¬[ÍjG­0ÝJ[®#ÂÈœ¯¿ ì°á{¬sÉ ZªíºûÙVÎn¶ê´õÚÛhµ+\›íFÛÒm#ß‚n9ã’;ì¹ʨ.©ìºÛ.¼+Èk½÷Z|ñ�ùî§­Û,°^lp¹ÅŠØH=)«Ìp© < ÿ1¼WU1Æ5ÛŒžÆ´r¬­ÇÑé ²ÈSò§'«¼²º-¿,@Ä2sv3ÔQ——3¶;÷Ûs4? 4É-âÑ)³ìðÃM;M³Ôi«­–m»-¦˜É Š4uÛ}2ŒÅâ•ÇÉÞøý·™k >x«n¿ ·‚sd÷Ý—F‰ßÞ}ÿíw¢„[~yš†·�xâŠ3^7ÞÌé�—ä“WŽ9ê©OØYœg§8ÝŸ‡®×èM•þ÷éªë¾;j¬·,¦¤}?üì�󹈓S¾ïÍ;¯Zg¿ëüðÂgŸÈ×§¼7ªfõ<øá/äû²ÓÃY½ð4Ò˜÷§ÚçÆ½÷X‰??ý‘?(ð磯ÿ~tìg�—™œv•ïÕ¯€Ï»¡D½êñ/þƒ�$@R|4•ùÞƒ¾>4°ü ÷ì!ÂÐió©Ï}ò³Ÿþü'@*Ð�T!8(B±¡Ð…ô™MèBš�‰Rô¡m¨0-Š€ˆJ”¢Õ(FG¹€‘’´&=©5RªR°´¥Úx)LUªR’’4¤‡¤éHOŠR™Z£¥.…éKyj œ.À¦$ªNM*TŸ²¨Aå)Q�êG¤&u©LõKK„U©Ö‘ª:*Ví┫]ÅiR;V±ú…¬4ÿ5k‰Ú‘¹ÎÁ(v5[ÛÊÓmðµ¦p£\éZ×»â5¯-‘ Føº ¿þõŠ�¥+a kXÄ@±ŒmlÓJ‚ÍrV°ƒ½«a‹XËŽ³(Ô,g7ëÙȆ6 ”%mQM›Ù¤¦Vµ‚emh_Û×ÒÊV|¬Cpƒk¥·¸Tâ‘•ø¢~0·¹ca�WOÊÑéR¤½MÏoƒ Üá—¸ÇÝNr•Û\ç®§3Ñ5)uÓ»Pë^÷<ÙÕ.w»û]Æ„—/ãeîs֤͋ªW½ìmïÔ:£Ýíª¨»ÞErU¤ÜLÜ—ùõÊy;ÐßôþÀ©a�`f2¸TºˆC\ß•4øÁY‰ðÿ„«kQ ›ÃÞp‡?b�x¹÷51VPœbŽV˜Å¦ÉJp3lw(2ž±‹ÆQ®3t!….N=Ë$&¥¸Ç>>V‚übÀw(��ÌŒAœä%ß·É=(Ò¬æÚ’@ÊSæ@d§kå+«ÈÀ2‘{àå/ "Ì×󰘬P† TÍk®­›§g¯˜Î§±3"ðÌå" …Ï}3  ƒž˜9!…64Øœh&E6²ŠU¬£�å;o9&]®4Ÿýœéà ¦Óù´¡E-Ø7ùÔw=5_§›j´@ZÒ®¦´,-k•kÓ8°õAp}èÔŽZ6¾þ5°…ÝÞ\ŠeÞþvd)ÿ+d?— ]İL¢4 j ¬–°1¦¼ù³a`/vÛ˜$Ë·ÁMXqg˜ÜÃ27º7£nP·û®ïŽw¼ç ìØö–ÛaÉ··Ã�Øq‡¹Ü #PÀ­2pCÜ®G8•~j†ËÖá`�ø$.ŠÏØâzÙRÆ«²q5wÜ(¹¼Co’›ÖäA¹Ê3Âò»ü$0WLº-ºîšàæ8ŽÈ-kïXžèûžx¿+þï‹?'æ™yš™îô§ç¹}�:WÒbõ»òÛ Üx»¿ cnнîI(ò®w¦[¤ïrxzÈ'Mܳ_W+[9âïÅk]KŽü9"/yîI^ò4y;7Ö¡ùÿÍs^ó~®;èCïE!ë}ï·%¬ß-Ò`u°¾õ�_Gë[ß]Â7Ü3‡O<âÏx;<ò•?åù·¿þõŸ=òGŸáÒç�ï©_}ìÕñúè«cçh¿=îuÏøÞ;þ÷ÀWž÷‡ŸùâsþøÈ½òÃ|,x–îêåýØO?úÖ/¼íW€ûÜoq÷¼ç¾÷_å‰ù•_˜�Ÿèmé1ŸdHÆûÁßóÝõÕ_ìÝ_íeÈþ��ö5þžZÞL`^nžù! ¤M¬_*ź_üÍŸëuõY lÙHâÑÝUǬ˜ª xÌPwLÎ< ! Õv9$!%,¡4ÿ¡²F¡Yš¿À‚^á¡pÏ‚}Ãv¡æ±^D˜ "æàö`ÊüàáßaòÔr^’ÃR‚>aBáòY^¡f¡òÀzá‚!´aÖžA>ÑšƒÞvƒºá<aô½ÞÖá6aêáQá¶øáú÷"!¢:„a{%â"âH#>b$N¢Z"ý!¡2á&v"ìá—ùË¡âä˜â)’Ÿ!Ú*NÇ :@žÀ+¦!$®¡$¶!%Òb Êá-ReE–¥Y÷ü¢�l‰0cý©¢iU+*£Ú:¢3Æ¢4Š<Š5²&^c6ÿÖ6òY7z£w€#s ¢8Ê`*¢Y™#2’!:2¢:¢a=¨¡±¡ß a<ŠAüQßfb.á=Þ•¥Qâ<ìã/~�?ê@äæ#6ô–AæC2.c36ä3>d4FäÊ‘ØfKkµ«¹©D“Y)œòÑ7¢pE¤«n° K¬±È*{Yª[®ŠU«Ñ":­jܦǑ"üÇÀg«­£ý*ÄÑ 7ì0ÃEzÄf¸¸½'¯ç¦îºÁºêcÎÅÛwb•LÉ DØË «ßíÈoÂêM°Àl0¶ÛÂ|ÐÂ÷ñ ã*®®ä*in¦èn\»ƒ rŸ)ý9²t&‹…²ÊøŽ¦¯Ë: ÛB¶ r³þ­böÙ=!¢¶·>š™Y=W!÷Ü5Ìfφä­7›ôÿí7!€Φ_~6ÀáÖgÂáŒ7Î8‰²D.9(”W~ÕUŠ“FZQœtnP{ñ!úÅ“”>‰â¡²¢ú_w]fë …=vÙg›�öÚ°cèöÛqÏ-wݰY»Ùzïm¥ßøà„‡b¸ãŒ+=ô�Kyå–_nIæšG¹ç ë%:¤›Ž:¨ª³Âúy®¿Î¾B²ßL{í·#Âv�»§Ö»ïÀ ?|ñyãò  ¼åY©yÎkÉô'½>N8Ö»ö@¡½íõª{ßãÄç~ºÑõÆt§«OêV—»ö1ä~‰ŸÁæ‡6ž¨Í~%œPþÊÒ³=½G7Ã[ ៰€Ì#Üóÿ¦×@ zÖ› (@X:îi.ƒüOÆW¾&Š}$|Ÿ Õ°É?,´� q§EÝém™ o¨—‚Q9>, !ØÄÄI zEt`,öÈÇÊB‰uTœ IH(†oŠÏ׊ô­ÏB[t òÅ7%‡õ›¤ Ïø65R‰�{q£%âÃÒ‘‰wt\ÈÇ>F�L$!Ù¹ZF±ƒäû ù®ØÈ,B2’'ì"A*9JL"ç…0’™ÁÌfz²1  åðFIÊšÒJu4"ë£Í´r�“S"åYŸYÒ²–|uiEÐd„ê&0ÙRÂkF†šP0æb4)ÿ¡kݬ™Î|ÌÙ(ÊQ¢³s;D‚BšMm®rrüf, Ѐ¦ŽŸÈ¨FÍ)ˆƒZA�‰\É"_òN,ƳŒóÜY=HLKê³'üô×DÆPf>ó� ,¨%Ê 9.”¡LìæC#úMŠZ4+ÕhF9Ê&�æR‘»tçLàùÈ ¥4!“´§QðÉ!Å=þ4XMqSF3:}#O}úS$4ÔˆC- D�zÔ¤*•©VrjC(ÕGPUž&ä2Õ63€iµ(þáiW‘óUòøNn4­iY¥˜ÓiRs­l«[ƒªÍÀF$"!j+éjQ»nÔœMeÎ:¡ÚÎ’öò¤¿¼*;ØÂÿ*â°QŠbÛãUÀŽç±Uˆ,@'{V´ZÖ eëOßê@϶´!­+ÿH¹£ºÂ´KEm^URKŒ´¯E©2KˆFÛŽ-h‘)IIÞÃÓ!¸÷½(,"Êã[ŒpÄžø ›x ¼ñ�Eï)…€ÌÓuzÝ‹DÉ>‰;ØxV фҋ szR Á ÀõŠÏ¿|¸õüªá�5ìLµšdy {^ôE½fN{ßëÞø–¾âuÍDð›_(ì÷ ý1€™3`oÅÀn\‚ìsØF‰ñnSá^\ØqÕ†¼C#Ò¿"vÜTKü‡WKÅo3ïÍ\üb³÷ÿ 4®ñ1oü­Ø¾å¾,El�ŒÎ ûwȺ)²€ \º$+¹{L„“¹À6Oø$U¾rã²ÜŠ-C¢ËRqˆC4bbÌÌ)&ošY,¿OêÆWx3:ã<Ó˜F¾8¶ó�vœçÜR“ϵôó‘`Az†fÜ’ÅÂàECXÊðJ¤·‚á¨�ùÉzó²¦Ãܸ1kÙÄ;³¨S£æšº¸{ái] X×ÙªpÁsñ¶ºg+ñ·nšô^]Š_ûpæD±�|ìTó…Êf6–�}í?@;oÒ1µèil³NÛ(]ñÌf÷mpç@ÜL$7¹Õktß™ÖëÖs~qÝ9]‹NÞzÿ¡·½ï�ï�¨"O޲¿§¬ì€c¢ÙŽx6£‹—p0sZÌ$.8¨mµí²ØŸÏAå0B�»šãçFq\Ô­·7†äœ8P‚5¾‰®ÏÛ×G.t’Ÿ’à°¡8æŽþ÷P¸"iÒ«àÛ¡SÇGm©X»Ò—ú¬fúÏšZ§g­tD1n§—{¾Q_M~þþ@8þñlâŽÖ»Çu¯ë˜ÏüÊüTxþófÚ#<ó¨œí7Ç·WÞŽ÷š ôËtÿùìôÖ}ïn3OÙÀSnð…:�é™c´,žñ�‡¼•$o�­“»ë›ØKæ5v`�Ý)Ÿ½m}éF“>Ð`g»ÿ°Wÿvà½~Ú²§}ÃËœí4q¸ºg&ï“.xèÿÕƒÍÙYÂvüQî0ùŽç\—À|šá|®}Ò7}°ðkˆz©7�—}¨6Ü×oàWd8~‘ÀzæWq9€@uw÷ií‡&ï÷Xñwógqõ7÷wxÈD[È\hÄüGøô(€(hxy ȀΕ�‡�ÙG�Ææ}Èvzâ§zX~uóz ˜~"X{$øpî7ð×wµ‚àÖ‚Iñ‚§ _2øB4ø66hýgI:˜|<(“§9•}B8}DèYF�Ø'�JÈoLXzNØvä·~C…Í‚Ž0‚y'$Tÿç}FáC’8@X‡"•H¡€TQe¯¢#”\l2Vl‚F=£ ¦xŠùáeªVKƒ'€÷6=G#¸0‹´ÈL!`—³Ëâ¦áyÈD¦ød61º!:¸('�ó®%#>”X|b7 vwð0ã%¸5‰ÚX•ˆ—øT™x]›¸5ŸøX¡XS£È;sЍHª(cϯØM±˜ ´H‹½–‹˜°‹ŒÐ‹¨ð‹Œ;7ŒBQŒ|pŒ¾‘ŒN±Œ1ÒŒÊÁSÐh}ÒØ=Ôh�Žr‰Û(‰Ý¸ßH8šØNœØ2åè;çPé¨?ëÈŽª�ŠÈ�è4xó¨Mõˆ÷8‹ùÿxº8/ý¾øBÀ¨ ¸ÄØA¹$ É IÙiÑ8�µW�s�‘�éCÙé!ÉW#ù %97'ÙLï‘C¥È’.Yz0ÉŠò8“¤qÐU ©~úÈ�þ�!�Ýgyy” Ä8ÊhmÌ8@ΓP)‘�*TÙ0V ;”•Y‰u$Ò•)ñ•Àщ%ƒj„ù�²¹—´Ù—I�yž I˜½t‡‰<‰é–Ãɘ@G,ǹ=2 º–%ÁœÈÃS§B$}|„‰šÙ$œ)¨–•Øy6xÓanÖ–�#“÷6x’¦�¦a'¬¹]v‰žx¹žz |©7ñ9Ÿºy I¹”>ÄS¶¸¯X‘U‰!: JY¹C6z£uÔ ]÷ à¡11¡”P¡y¡f<˜¦^«Ø¡ol *p‡Ö‰$Jž&êš(ªž§ð“PçžCY”&˜2jŸJé›D4VBšªDÊDFº H ’ƒ –…*«OÊ9¤¨<·¡Þ)œà©M5°¬Ìš¥(¢`Ñ¥ Už¦GŸ– ©yð±Y¦Ÿz¦·™¦Öº›|ئø#¨ŠNªÊªŽéª«Ü ¬ÈC«{j«¶è§…¨± ¨Òù«êe¡Â:<ÄmÆnÈŠÝĬÍ©Z ­§ ­"A­G‰­ÚÚ©ÜÚ¢y󢤊Œlº”çZKézo: ™Y­Õ/ÁÕãÕ‹Ö­Ï}óÒ5Ó3íP¤9(SA× ÂÓt] V wÃDMÉ }ŸÍË&€½ ÄW5”À}¹²”ØŽÉÀ ÜÁ}#<šF#¹�ÜÊÒ’mp”ýÕõuÙbÝ&i\¼šm¿}ªÖ¼™ =(¢ÿí\¤Ý ¦}£Ý=ªMn¬�Ð \Ô| Û€+Û€]ÛÒqÛU£ÛCÃÛÍãÛÆÜÂ]Ä]ܼpÜ ¢ÜË�ÎÍýÜÐ]|ª;Ýd�Ùf½ÙhÝÙpõÙ¤ÚÚ3Ú9*ãm‹å­9çíjé-É íÚFíÞGß-ߢAß&cßóÅù,¬ÇßýMÿ]ÜŽžÜÌÇQÑÕ”mÙqqƒ‹ Ê{Á!Ä–Q☡4E@ PåRå &*zѹK¨ V5ª ºÁF{$ÖJgS9~Ah[JbÑ££ 7¹a�OuQ"im飿$»Ý9¸—ó• ýyv¢w á`¶肎j7‰  SÿN uTGBÞ#Dnäz�äÍ£ä•ÁäOá䉞èU^,WÎYî«[n2ø;�`*bn6džf®�hN jÎæîÁ]o’ƒ!çªCç>jw¾ yÞ«{îy}î€.è�Nè7yè‰ÎèÑ�&�NÎGÞI®©–éR¾é­°X>Ä ŽÛ£þŠ¥Þ §¾ © «…­þêyÓæ¸ä•´®¿ð„ë7±ë½B¿Ž ÁÞÃNìÆ~�È>åÊ®à�ÒìÕýì¸íé™ÓÎÕníTÞ=VžÛÌÝÎå=žá>îå~î©9iÞ£°Þ!²îîƒZëA7çt>ï/™x®ö~Ÿ|þ$~ÿžû>è0Vèÿ.å'½ìhBð‡$é„Cé ßÞM®4š¦éÏéïéܾ™$òí÷–ñ|4æ”Sæawæ^ññòz•™ï~¶ñžòº¾ò-Ï*/O®1ß3�f’ðöpÏ}9å;/ð�âóf•@oõ ¿ðN~ôSŽíÚÎôïôÂõ_~…a>õ¨^õª~õ¬žõ®òë~E¹Zp–¶Î ò>ölÉò¼îò…Li¿öÑö÷q¿hsåuoÇ‹rŠa“+@±÷)ÁX < ø×Þ=ï1ñW³Oñ©)õ{Dõ À÷Ä)-“¿õ•/—ŸH™oò¬×ùvNö¡oö£?¥ÿŸªÿöÜÇ’/7¯ïqµrŠ;Dû?±Ã�à€¸…µû –èùñû„üZN"Î8tTðÑÁV­b-ŒµÊ!(ˆ¡$b¢8iÒÀ‘4žâH‰Ò(�£ �S’ÌI29rða)1”+˜'™ iaBœ!C.âyŧJ 9ví²TÔRL™Œ”|„Êi¨L¥ZÕêÕ©’´n…ÔÕ«*°aŒ%ëÕ+Y²XÕ®eÛÖíÕ°#å*YW P(y;íåKÑ/¦<�ÔIÐaľ/fÙ˜-È‘yN^T%Ì.�ʬiB#S¦2eb$=ШÑÒ1MȰáÈ+^$¼±ãÿÇ�rëZ^ÙR"LWœkÞÄÙJ'ÈÉ>¯ðz©E¥Œ˜:Eµ�Ô·k·r5 )¬X´ºC �=ûyôèãÎ¥k÷®Ê¼Pøöý XpàÚ†^ÌØ1[�2žxÌ͊ަÏ@{D4‹J+bB O+*5ƒnrÍ¡U Å%¿"Ì�£S<ÒI·’xkÌ%à´é‘â:n”ä~²¬9£ž›$ºéžŠ*½«¶Ój¼ïÀ*o¼ò€TrI¸Àb¯=»ðÒk¾Nê³ï¾üöã¯?_þPÀ ¬Ì²´ÄÅAƒ�6Œ(¬ÐB+UcM!†8ôÄÙ0*ŒDs#)EËVüí¹ÎˆÃéD­ÿq¹‰Ê1¸¤–:ˆ:ëÌ[RHIˆ,òÈî’dòS%כ˽÷rˆ�Ê*ë»?� ÓR.»üÌ0 403‰6³¨³4CƒPB7‹°Ð’83„‘Î…ìŒ-”ÙÌȶq ÅR�ô%B‡;¶¸DíÉÆ p,JG'õñ:P1Õô;NÍòTxÛoQÿ+å^|/Ñ— ÕŒÝã_€V·»°x1x$+¶"¯ ÊÌUA1Š.ºÒ +,Œ3ªŽ{ÑQÛGH”eäø\zåd}/)í O©âe˜V8¾ø€â˨”I“ŽeŽ6ñYazƒ‚b(G�ÊÖ©ØÒx›vú鵿ý–Ñ ¼Äÿ7ß}ê×ß�,ø`Cdf(‡CÑÕY�&Vªb‹#an—Ž=†tWš˜™ä¼LF9kŒxææ˜e^˜f(lÞ g¾Ó¶»çŸ/¢�»¦¤�ZjÌ3‡ZêE”«×±«ïÍYë­™Øk° æá™ 'W³!F{µaÛâ·ãþ¸n¿G–¥d‰N~eô¾C&ð—œfÃ;A\e‰?ÅçM€žÚ²¡Åm‘n¤9Rú_¦5üó8÷h&TIÒœ @UbÍLfsž¤sD7C NqÎÏ”0”¡*Ñ9uFé�ý‹£,9RÇ;rr�»ä%>KL江Œ«^Š�Ʋ‘Ì|¤B} $†Êå¦Õd61TQ�x£.¤ßëλ4În�!ÝÍHsXÒ9Îr€ÔæJíÂ˸T 0¤L—XÓb3 RæN :ŃþT®é êH†z’kbÓ¨¤ñdR/ÊÂp2u£åDã9?:ª*\p#©Nÿ§ÕZruÿ¢ðj]À*V²ò¬ »)|rº G:s®£•WW(©Ö‡âõš=ªE¶T26•O�áa[-•l¬± Úá;SÚÕz²ôž¾|©>c:Ñ™N�‰�5Õg¹Ú¸’VºVñ“FQò¹Æ K0 c +¼›P�G1v�¡P†Â¢çèO#1jÅÔ´˜Û¢ëJy¨‰Lqß²mov-£)1Æ X&ðGËÕ§ ÆžE¬Eƒ¼¦ODXÂÖ™n…¯R]…]}ŽÑn`¸{ï²¼Ÿ¯/ÈÛ¨] wnê�{Ýû¶ÓPä>õåÈ}M‘ßô’†¿Ê¥Zÿ`¸Àè<0u,\;¸Áÿ–p„)la(à ÓpÕþÓá<|ø!1“J|âŦxP+&M]lAš7Æó¥ñ)lŒc2§“¿=fâ��,äXRFÅ‘¿ÊK%/BMv2T¢ å)[¡Ê@É«D·;Çî~w,ðúr]ÊK46?®ÒÒ‹µæ«Í¾ø…�~Y9g:+È^UôLH#fÁD t-˜Üä'zº‰^´J�ÍGÿ/Ò"žtx»3^K£8ÓjlUÛ^åéÅ‚Z0m~s©s,ç–ÑÙÇ sôª^Ý£>ËÉ´ô­'lh]�Ö+¼> PêòëMÛA[–4BéjÚ‘ »$—>ï˜5ÝìH�èÙh¦ÿÑÄ%ßP3bÇÕ~ª©uÌß')¯ÛX"òžc-ˆY Öæ.tÒ­î®°;%*y÷j³Ù™9r9<”Æ·!ô-~‹[qG^I <¾2ž¶RNêÑ8ÀŒ@vqÁM¼è«,r‚Åýç>nB3ú¸t×=­RV¹ä=9ʇý./·üå1_öìödóN<ç—v`¢óó]èCwÅÒk‡t™)�UL·¸Ó¡:ÕUBðƒ÷Òš¨^õ]cÝºí¶ ¼S†òÿ©-,7ËØ•íof?Ëb7·äÚÛN_Q×è¢{Ý÷^;mKØÞ®8¬ýxƒ žðÿ1üqŸx‘d�ñAq¼¾ ÿÿõ•»ò&Nv˜ËÎbΧùà:³¾Õ»öÙ>îë;ïƒ=^ ¿ñ ?ó;?¹J¿Æ3¹Mj?z#¶Ék ù �JÛ·Ë›¹Ó¨C;Ì«AÈC=¼Šñ€@°BÒ"„1B(@B‡PBæk³'d‹ò˜B*´BÀÁB)É‹-,Š)3hñˆ0¼1Ä-ø*šK´¡€½4<�5dCZpCŒ€Cµ™C:´Ã:Ì+xùC@œ+A´B4ÄU@Ä+QÄaÄ(tDE€ÄHœ&pÑÂR0CLE0 1ä 2\;P¬ˆe @5l0TLEUVœW”CXŒÅkšÅà«Å@¼"Ü·#4D^d·sÂ_\‹FFjÒEI„�ø¨DùêÂj¼�M¬„Nä óšF~EkºSdÃmäF©�"QZ4G‰l‹[ÌEv¼¦ÿ%l¾&<…E”Ç`tÄz4D²$dTFƒôGgäDhôÄ�4Éš{¾RÄŒ„lÃ…ìÆèxȈœH�¼ŠŠTÇB¼ÈLÊÈÿ{GŽŒÇøûÈ) I$ÉcÌÇd´Dj<Éf‹g\„hüD—¸ƒÀ™„Œ…›T œ,Ç�,KªðŠ[d eùÙ˜/�$ëèH« ‹'!¥ä�?§ÌJÍãJøÇ€|‚8>=i™¨A!Õ¨ø+ÿ”@‰:xS8u�…èÐç,…Žñ ¶i™v Š?%ÎSÔB5TZQP{“T]�THøRŸ°ÔÞÓû+33½ŽN ¼[S^ UQÕ:�ÓX0U|IULXUŽhÕJxU ˆÕÌäZ-ÔCÅÕ]×ò‘ÌJ%"1%SÂ(ÖcEVöøÔe Ug}ÖRÅž:¥Vk=lÕV•àV¢üVBmvÉMr-X>4שÖkq¸uÕÌvUxí£Uã„y…VÿiEUŽÁSLÔS¼Ñl]'?µ�U8oÔBXð Qƒ]Ù³DX4SXLeØVa×c…XÊ«‰­ØzÕËSµÓŒUÕ�eÕŽíUWYXÙUùW“ X«W–}Z,rY0E×KÖLõBšE ¼+ϼ("”ÈYgµX{íYj5,h9É~ÍõÑY]Z@Y#!X¨%W/]Í—¥Ú`U×™uØðØZÊTÖøÚU#Ã=Üy»XŸí…fa“³MÛîXÛ¶%Ù·­U¹…Hº­Û]½Ûs-€tÖ2õ[­}WÁa ¯=‰‰=\ÄuÅ-ÛˆyÜzS[£ÝV¤M¸@…ÛËÍIÍ•TÎMX½]Øÿkë[x,ÀÍÑ®%"Â2Õ5Üyc/§\ÜÆ­�–�\³€@ÞÇ>(P¥µÜ¦ÕÒÝ]»•Ú_ýݘ ÞŒ(Vo*^ÓE^Ô-ÜåmÞy^×uÜM¥^¯€@RÁ^íu[€�ÛîX•_]íݼõܪåÛóÕÌô%Ý¢™Ó%ƒÔ}_qÞ{ýÙ.|Ýú�ÝîÀ_÷ÐßÜÞ“ýß”ÝRæRÞ 0å8¥ÞÈ$ÿñ fô/›e f�ØÐ)‰j#m )[”Û± ±µP�­<Þ¨µÖÝÞݰ†!LÅÇraª³&œ^µf±V‰¶`9"(¡ `ªb­ b˨µ$Nãÿr%ÚJ@aŸPá'nah�aˆ•áP¥áÐÑb:ÓaˆàáÎØ1Ý%cI0ã @c5>dòX7¾8¶Z(F“¦b+¸,+¾ãU[=î1>?ãkÍ\äÁ{HD.å·XbNhb+ca¬b�HÞ°¢dš¹b Ãäe,Œ-Î�.fÜŠèaþ dƒbÁ#eS.fµ@eUÞ"VŽâ9ö™Xn©JnÓ‰µeQÄå=æâ>öb_æX1ž Qæ"1fq¶ d~c'vd9~åg.š‰`Õ¥æMÓˆ›ò+ùb·’<® L!æqçrfäs^fHžbX^ç^jg÷}ç_¹eyF-]†ˆzÞf|þ^ÿµØçpîgVd&6çUF/fVgƒ+ÂqçÃ…g€+Œy†èú°çîAÛ÷£h¬°èïÀèŒfãEnd�æ)¦©�i„VÞå5ilèý{hPˆè?戉ÎUª�é° iqþgœöè�æé�~’6\¡~•”>ê•–è—fê¬~†êR–ꀦj�næ‚6h¬Nè’^hŒàj‡¦ç¯Nj—öÀ|nj²¾h³6f#•ø <…V›·ŒÉ˜nA”‰=lÖ"�oÔ„W9TRѹø*ŠWùkÎþ”Àl÷(ì¡8ìÄv�ÅÆ˜ÆþƒÇƳ�šìʦ•ËÖ¹aélÚ†—Ï0ÂÎ ÃÆ³Ò�ÿÓ΄Ô^m!kío|m0‰m¶³�Ú^îK’®mòÒíÑæíUQìÓîUk5âvÅò°l÷ÀlæoÏvnÁÆíЖî] mÖÃˆßÆn ÓntšlZ,kñ®ïæÎ”ç6ïèΞô¦nŠcïën쉅ïU’o‚¥oûNp ŠÜó¦õþï�øí6" ¯pÇ¥˜Ã Øðùökÿpô�ÝýŽ�_:~R› ¯p ¿p�Ép9Üð èð™qÏ'D÷oOo_ñõÆpFÐp?p¯q$ÇŠ>„½ù´!�ŽWq—×—ñ§Nr-?Øêerµ 'oñ‰‰r r1'òÿ7òßr6€%¼&¯�'W 2r?ó/òFð6osÞ˜Ò[ÈÆV›òÒhµOBÓ>_t&ùs[± A'ôB¿sBt�PtFÏtôptÊô)•ôIß»5²tJÀtM?õ{3 OgQPõ�"uSGuYw‹ñ ¿HGÅPßñJ_•DÁYÿu^õØÁ»u6ÌuQ¯!X÷u`_v.çÍaÿt\7ö�jWf¯ö¨é[‡v6\ÔE�ò¼¢vk÷ª¨õð#öÈàvEõökwqwr—½XITtW÷Lb÷v·öw¼x—;t‡…¸áGuÔo?Ö{wwl¿}º~ÿ÷^øFøN-xÿ‰âe1!?Ä”‰ßxŽïx�ÿx�y‘y’/y“?y”Oy•_y–oy—y˜�y™Ÿyš¯y›¿yœÏy�ßyžïyŸÿy z¡z¢/z£?z¤Oz¥_z¦oz§z¨�z©Ÿzª¯z«¿z¬Ïz­ßz®ïz¯Çz{ÿú{±¯o²/ûð>{´_nµ_{Ún{·çl¸�{³ž{º§i»¿û~Î{½ßò€q¯BÀßð¾ç¿|ÁüÂWch|Ç×C=ôÉŸ|›•D¸|Ìw|Ç_|ƒÕüƇü<œ|Ê]ÄüÌ÷|Î/XÏÐÑ—|å)}ÓG„ÕO}r]ýÖ}/à ÿ]ÔÅÚ·ý]]ýC~âŸÏÞ7Äß~I~â~ã?~I~åçRæoþç‡þUíßüé�Ôê/þ/ ìwíîïþý~ç ÿìßþÆG³l}åiþõgËpÿò?ù,hð „ "ä𡕈Q¬å"Æ7®êèñcÇ0"�dhò$Ê”*W²léò%̘2gÒ\ù¢Äˆ-b¼¸‘#È "Ã�Pó(Ò¤J—2mêôiÁQRQc5ãÏ=/rêêõk×#bÇþ)k6Ú´ Ó¦-êö-ܸoÙ¢…j÷.Þ¼ziJEu‘U1Xn…ö0§±dÍÿ–¥`-]¹’'u¼÷2æÌšïöýxðÆÂˆÁ*˸1]Èl)³Žky3ìØ²gŸì\õªÏ¬¢G{-}äôŸ× ·.^95íäÊ—g¶ 7”¬Z·òî]úöì§80™ðâángnþ<úšÎ?ç&L½zâëÙ±—?Ø}òw«âÇÏEžþ?€.äÜ_…I'H(¸ # :8v¬H¨ÖB÷µEù‰±_xAÕ' ˆ!žG Uf…à‚ :Ø „§HÈ …ÃÑå�5bxˆ†’!ÔP"‰ø#�Ë‘¸ˆ‰?¡˜"+²á‹1r7c�4Þ˜#‡<ö$–Yj6d‘F ˜a"™ÿ¤’-6Y×BU¨¹f”RbHå~VµæšZÚyçR\n¥á—a‚9¦’Œ˜9!š9F§šmz1e~:Ê)¢Uà9)¥1éÙŸ`ùù'’� c¡Ѝ¢Œ~ç(H=BŠh¥­ºj$±Êj­à…ÚV�èºë¦¤ ð+°y;¬#ÅK ²É:æ­ÍrcÑJ;-µÒòq-¶ª†YxûØ«áV*묵êw«F…íÊë¦À;¬°Æ›,²ËÒå,­ÐV»ï´Øf›ß¶Ý~+.Áx’k³¶’�kOëêÚ«»¿Â¯¼ŽÐ[¯½iáû,†üz\€¿×j«ªÀ€[0ÊA IÂç.œÿn®CñÄyTlñÅkŒ¯¾W2#÷XòÉ) âÊ-oˆn‡aò4ÔK=@Í7äØ_]±5×>ï[Øa-ôPD}¶€I›»ôËMƒuÔS»[uÅWÓ•5U\wí5µa‹2Ù"™�6áÌ©rx¹†h¸‘xNÃ�‰ÜsO\Öxë½µ×x/â7ØcLrYÞš\8éÉ®Jâ‹kÔøÛ�Gþ.¼”ßmùå™ãÍyžpè—þ;l§§žãá9÷ëO³g}ù¶g�»î�ñþ‡èE¿½^Â#¼v`Å“q|ܯßäP}k}µškŽû'ñËßâõÙs÷ˆ¯ÿ8ñ«ß:ò"¦‰ð|ƒH¾ÖW;j¹ïvœ“ßü ÔŠ Rppø»àS¼Ç2ðYE|ä{šÔXÀó!ÐY Ô[ûøøAð-¢`{7: Ò�)’¸a%rè«Hë#× ]!ÄK\Â]&8"ñˆX01‘�è Ø,‰FZ‚O¯Æ$5$"qEÚk(F¥ÜP9¬ÄÅÐC�ü0ˆC,"°¸xD%6щˆ‚¢·¤H+*ò0ZW¬ÎÌ^'Gxq>`ÜÃY“2ž1�kìHC!DWшr¤cŸˆG=‚�jôã‰°Ø®ä ²�Ù9¤"SFêð6Ÿ,€ùDI¾Ñÿ’\Ä$ƒ‚Ç pÒ“V % G)H9š;¨T%2YÂJ4ºò‘«ˆä$+ÇK.±‰A J/#REP ,Dü&“±R>È�aL&:Q²LGF+–³Œf80H\Æâš ɦ¶Y€?zœÒ§-»XÎSž3�UÈ:›ÙN6ÊÒ�”Œg•HO{~Ä€9‰Hµ6ò¯ˆ¢£þŒ'@åIÌ�³ =iAúœWºÓ¡ÿ© $:QŠvDCµBF5²Ñ®tT i@�XÌS¥FˆJõÙRZ>Ô–2­f.iº ›^4§9Ø)'zúS þŠœK"("�zÔ¤ö– }g-§S™ÖQªSWÍÏM­ŠU­ú“«]éWKV±¢”¬,=«K!:G¶ZSªT͉\©ÂQ�Ö5y�ÃÄG‡ZT¾ԯ΄fZïºV‰¶Õ°p­*µ4ªXž2œâ|ldIJT“ž$ !ù,:*tüÿH° Áƒ*\È0€Ã‡HœHQ¢ª‹jÜȱ#‡ CŠiP䆓(©\™¨¥K(0cΙI“’Í›�rêÌóg¯Ÿ@ú©¨QH“ÒYÊ”&Í!P£êÔ騪UZX³ÛÊ”ׯF�2K“Ùeh�©Íè±­Û· I¬HWF¶póêU8²¯ß’!Q¦\©Òå˘0�μ‰s꣞>�þJ4짤J™.U<'ªTÇV¯fÅʵëW¯–?‘-{6íÚ‹{cËŽ2b]ŠwaÏÞ�ׯïÚM Þ@¸°áDˆ+flÓñcÈy$O¦¬ 5f¤š7+ö Õy誣I—ÿ.vµåÕcÍbB»L-0¼¼ã÷Nð6îÜòósüÍ?`�ÃWÜqÈ%Çs”8]tÒQW�e×ù�œq7„wß…GËxä•—zŒ¨Çž{ðég¢FrÕgŸEø�èâýõ£C’aã�&g§ôè#ˆ F"ä�ß9bÝur–†¡iÈay |ˆžˆ®½§Û‹X”â@+²xW–YÆèÛŒÔx£�9¨˜�?¢×“+pIäwGb–¤bK‚–axOzxÞ”­µ÷š*`:ЖÑeÅ¢Œzáè£0*›˜Øpg¢yœŽ<²y �<Á銜BYgfš)i“¢�ÖçiFÿ"{ìåF¨¤`ŠtÈ®¼È(£¶âj"¥}=úhšˆeJ�ž4ëì,ÐFëé§n†'©E*£í¶Ætëí„ÑF›Z2ä–»í¶P¢¢îºáBëOÌÄ+/­h+,–ºòº«¯¿Zaï½ñ;’±Ž"“²Ì:Ûl»³L *d¤F’í¹Êxûmv �[.¹+“îºêf\PòÎKï¿ïFÁ^è»ïqýúÛbÊ%`óÍ,Çìò!1‹Ä²Á0)˙ ·ëpµcû]Çw rÈíj¼qǃ,ò'$—Ì ½Ë Lsl+¼3¿¿Ú ÉÙh­ÐÍ8¬³Ë1³üó¦É ­Ñž0|ôjA*ÿÓM?�ÊÕFmÌ1ÅU³õÈðj͵×jç¶±cÃܯÙhŸ9BlÛœs¿;Ç-·±@Ca·SxëíéÃ=E<ñ¹M#8áEž Õå;8Ö�—üøÌ›$R—Ì] 6$¯¼Ž94ï¼-ÐGÿËôÔKpç séÌ;ß¼Žzÿ}r‚”o>‚ÓNñì·ï>ûv,]/zÔoÿ´Î£ÿþµôï?‡JŸ§ö·?®¹G ^CBB<ãÅDyËKŽør=éQozÖ»ö´×/îIP|:êž÷8c¾ó1G€lZßûV?ŠÍÏ~÷óTþx ÿýo<Da�hx ª�T mÿ@Ò@‚y´�ŸWA[\ƒ×ëåAÄL0„¡bJX>ôéð*\¡ûZx®ÂPøs mØ?rç‹§à¡�D!ò…�]r L’¨Ä,2±‚OüEq…½˜ÅìŠXŒ " … ’�‹^ÔaÅ¿ðÈO:gD£ ÕHC6ÖÂ�ž�£éuÀÚñ#x\Q厷ȘÔá•°l¢Ÿ8HI²_Kœàø¬BF6R|C#§EI÷ÅŽŒÛ2# Ó8•5²Q ÐŒ¦)¦IMQÒpŽu<¥ðúB¼U*²—ˆ�e,›ÈZf %ŸûU.u¹N_îˆ3wæ0ÙTÌöÓ’.Ää§ÿ;gÚ0šÒ¤æ4QøŠ‚Ž’V¥4§…³ºìÌ›0i%LÄùJYrâ¢ÕÃ:݆K?ê2íô%<ã©0õ‘ DÅTÏ=GÓ± fr]>ŠÝ%fÊ¿gT ¨ ú ò”=@̦6ÂP–=ÔeGœàE—Ê ŠÖ!§¦XjF%µQcÅl�ý¥÷Ü9RÔÉ3…'EOJÍ;®µT|\L{$SšêOp�ëMqšÓž‚§+ü)Z‚jÊ¡n³L'1êQ{Õ’oz�©u*T¥ E vîªegdÝéH’:ˤrB)%UÚ4³Rl‚i]ë)œ3ÓKì/®r½)Tí꣼¨|õ«¥»ÁÿöIb›JÑÅb´±Âº¥:#›UÎìv�Á,©§"¦Y1rÖb\›+h¹(ZÒºõ¨…ë\WûFO¹ö° ªlÿZÕGÝöe¬Ô-b›SÆ 2Šlƒ,/?Ú¼NØ÷¾ÆE,r-Û,Ì©¹+|®·¢{Óé–°ºŽ)íi³»Ýºv—žïÓë2øªPm>¤¼Ž:/n Qõ2•½uo…³$\FaU|÷ůbŽÙä^v¹a]ÍX1QVzI­ÔU—�¬kÚ·2Xµ¥w#üڽƶPÄ+Ž"lË«Ó7M™ Þ¦5‰*[Ù=¼È2]¶@�ŒÎX:šÐnYAæ2#(5x›PÖÌf¸ùÿÍΑ•­¼ÂÒJXxv�{ŽÅaÄLè&FqŽ•E•]]¤Ø¾a^Š )a!ñ�'Y±„¤£§9a%¹8LÞ•“éå9LÙSs®2–µ\./Ägs§˜[f33ÍDS3›×üf8;FΡ®óLïŒgìñùx2YŽMÄ‚žAéÐÊJ4ÝèH<:‘ž4ô*�«K&Ó‡ØôG;ýi6…z£æÅ–‰Õ凰LÕÙs«Yqfˤ9;³¦u­9çbçú}v.ò2ð, _¬ÏÁv  ‹‚ëI:»ÉNS˜]G“¥'Ѷ¥!q/k¯ÛÚÖ%·¿ê£o‡{Ü”*·CÎíËU3uÝìÿ~õŸVs€–»<Þ}˜7½omï9ëú¼îwç~Í)a3šà5?8jîgEwqØ wöÃ!�IK|Ú·t—”Òù>Y|WX‘<®–,‹»Ôä>uHHÎÈüž|ÝÌz\þòxÇâíp¯÷j¾}óœûÛ G xM�®š á™R6Ã?áð±@¼éÒ¶µ%eq•TݰW÷^Ö�µõPì!»—S-Ò³í1VûXØÞr˜Ã=î4Ÿû½Ý—oð¢…ßwÏ»rÎ÷‚ =®D�ÉÂ�þsÂ+ÝðL§…Ó'^ñŠì,÷Þ*q·­¯z‚*ß±²¼.OS+Äx²GÌR9“‰î{ß9iýÿèIoúÓÇÂ9Nw:Ýñ½k}Ã~çÿ>^§i"%ÕN0G>Ò:pß?;âÄ'uq|�7Yjâ‘—\Ð\ ^§( ã2ˆrØpɱ}Šá}ßçá'~¤w°‚"h~ççé'ißV$­ÇïÇ6Cñb£•CbLÙ” ²~îC¢ÂC,ƒŽ3¡“«±?z6(A ÊÂZ="~Yq dY–P2“_5'Mi+ÄCüÆo&²’*a^.Y 0™2ÉE4é6‰“7‰•R '=¹|’—@YB‰uKQ”ås”ýÕ#:±”kiO¹z혮@•c•s˜c¡•[i+^™)`I-j7–eI–g©—iY*ް–mICo‰gq),Ù2u™|‡—yi>{9}é—žÉi˜�”.3”‹yQF)H™B2™” Py™c1•4T•"‰'§˜•ú³•Vÿr£y&¥)–X‘šªYh©\`äš°ù>n9›µy›èe—ô5’½ù›:œ9ù�˜9˜VÇ|¢Ê©/ÌIŒ)Žé ;¦”Ó9™¹0¡z�샙ši,œ9œ ©g¢y_ù`mršé©ž«YBݦ–M›4›ÂPŸsÙ’†¡›ù8½é›D#wdá—7 >ú£õ'*Ã0¤DzœÊÊ+ º  ú � ™kI¡º‰+„¡Û¹™™R£�¹rJ"¹AÊ2AN…ž´ðm'Š£î©¢LYOìã¢0ºd2zO¦ŸyÉŸ9"VJ@Üy&ZZ]Ê•¦Y*>c*zYa¦ìÉši Ÿ+ʦnªr §¸9£Zå=°D§jõ4vú ¢!{ê£Xù§Cº-}¸›‚Z KEX‰à<1‰¨ � Ôù¨�z‚xÓ\û#/•z©ßÙîQ+›Z+q#bJQ‘XpVv¦å“¢¦º¦lšüæò±ªt骺«[”c ã::¸š«»Ê«¾J£ºt�Á:¬èe¬¼É ‰ê �¹¬Íú¨›­bÅ>Ó/ÕꋦHŽH“­õ²­Ñ­6ò­â®57®£Š¢­)1¯yªõ¤®y¦íj›1Úªrê±²*8öšzdÿ‘¯{º¯Ú¯¯úQ+¨ë’«Ï™¬Š*�Ì*¡ ­D#­úC­XJÖj±Ï†±]£±Á±Rë©àz…âZeä*æj²ñ™²X±®,î§/)³üå 4k³ ¹ :K¤<«¥?{¤AëC»{k´»¨PÚ”ÎÚ°Mû°±Ì0±ZT±¹ty`µAZë±°²ö÷mVÖm˜Ue[L*+ 쪶.˪÷é¯9 ¯Îç,q;É8˧TK¼: <{']5ÁÚœœ@¬kt�«¬Œ r¸L«0N{ P«¡K± tU«Úª –«Þʵëµ!˹“à¹0ÿF¶My»,t¶+ -kŸ¹Ù³ÍúúH4¯«±;»ºú�·›»Ù±»€Ø»}ÛÁ»lÈJ¼Cr¼K›~+cû´µS¹À7¹Ô›±ÖË­Øû¼°Úµøµœ ¾`%¾LI¾ï3º¥"±Œ’[…I!3á ûX³Ôɦp»P ¹ÚÂŒú‘pât?ÊÂðû4§‚0§»sp°Nª„¡Ö1eéJ…• žjQ PL ‹0ÅT,sX©J=TW7™2!1ÔÉ�;8¥UZ¶S�•6zQÂ*qÂ}– 4ÁÃÏç“ Ãå;4¼§6¼ƒ4¨Ã>*Ç®ëÃrAœ¿q,¸E\ˆGÿL1IâcÅ߉ÅN ÔcØ£,U`\ÇïÓ�d\Æ—pÆ—˜Æ@èl¬nœ^)|È”aÃÎñÂvPÈ©rÈÄkÄs†Äd©ÄâÄÄ×5ÉQ|V>pÅf‘ÅÓãÉ�ÊÙ!ʤ‚ËîcÊŒ€Ê©l8h|Mh¡Æó&¼((<´´Ü 5ûäœË !¼ì£¾ŒÃ®àÇ€ÈÍ"8 !È<Dœ°�ÀÌVæÌ·Í°$Í=&ÉO\͆qÍ‚�Í™¼Í›ÜÉñÉ]Î95Ê¡Ë> "è¬Ê]ÈÊ)ù¯Ë¿Úirÿ|ÏùœËü\ÃÍ"�-Ðí EÂ:<‘ÐÍ7ĈÌÐ]e-ѯDÑJÉ–ì=\Äѵ›mÑœÜÍ!ýÍ#­â,'7=)�+m8™s6Æî 1-Ïo¬˜*lÔµ¼Ót|ÒvœÓzL×7܆÷ÐÁüÇÃL4A�4=AÔqmÔˬÈÍÌÈÏ ‚0 ÉÓ|Ñ•lÍ8f>TíÀ!rÕîÒ!ÒgÊ%=Τì>c½e½1g iÝέÜvòeXó·ÂB±.÷Êa ÃxÝËzÍÇn˜Ã ñ Œß!Ôy`ØN±Ð‹ÊÌ<Õ1œR>‘]Õç<ÙÀÕ–-Õ%”ÙÒËêÿ� �­ÕŸÍÕ¡MÒeÒ(Û>§MZà ÁðÞð½Ú¶Ú{Û0ÛÉWÛr�Ûr«Û¥­Ï½íÏ¿ýËÁí×–ð£ÅÝÐÇMØCoBÌÜ heÏM1Ñ-Ó­Ù‘LÍ•�Ñ—�ÍÚüÝáý ÞÌ6àìÕ£ Öÿ�ÒÐÁS<ÕÞðßg=ßg]ß4"Û5_ú=ü »è±ÛéºË:=Ç{�Š.Ð >ØÏVØnȶ�ØýXe~.:âTN½ÉØÍáÚ�Ù®!>â7SâLñÕ…‹®¦½â,þ .þâÁ ß|Eßk\ã÷}ã´]Ô¶­;.¿=>™ƒÎwœý ÿÌ×¢bäOÃ*U�ÜÿsË}ÔÍ­Ø<ÅCSNQ1NÙ,£Ñ0é¤òÝfÑå[Í6"!ÚE‚a½ gŽæZ£ækãm>ãoN[ø­U9~Ûê’Û÷K1|Â@ž×BÜ}Mèõª'¡�èá¡èÊ|´Æýä“ðè4éâ¤érRé× Å—~ÉóíCÂéà­ž=Ø#UîâU$xæ~î+dêgžæ/ÎæAåæïŒ±NÏŠ¡ãµÞß·~.¹®Ëxä<-èÂ}à>zä žäÁ—ÆÞäÈ®àÊÎìäì°„íB"í”\íÞ#s Úîéã ê!!îãžSå~îæžîfÎâìã™#ã™Û—çV°Œ0ÿñfE«8³0$�ó:/*¢Ò10!ßÖ1E}>b’y ¢bΡó:ÿm ²BVF¡\AÅhZô�Ê”´PPͰõÍWŒbÁ 5{öŽ w*¹y'û=/X˜´×{eÿÀß"G[(Ñ‹Þ%5"[©ê†ÂP2�E4�¬6�óLO<'>o@¿Èç2ô6aõφôp¢ôŽQøàôÐõU&õ[Aõ媨cžõ¯Àõ]W_¿µ»DËü�äh¯?jOНêøno«’÷ïíò a÷΃÷ìŒP[™2~ïÖá�¸ƒ/$–ø®�ø³¶ø‹Ýø‡Mô=bô’ï ”?–�ù�¡ù“ÿÀùÅàùb úWo¢Oú^¿(`pcÿö°h-i=kO°mh´÷ú&÷êø(>¼Ç[VÐ 0„ ,dØÐáCˆ%2 PÑâŒV4&âÅãÇ�D "©À$*”³TFbIÀåKW1e*£Y³ÏMœ>tî\ÔÓgÍštèÌ!:‡ÒÑSIY2bÊ(ÏSLQe:¢úÈêÕ—/'måúÔkžaÅrÍU¶ØYŸ$yb›ôËH&äÊ¥õêU3¼ÍtíÕh… ™�s|,jRJTV›:õs -È^$sLäQp¡E�ýÔYqS¯v_ VzbD‹©U«bÝZÒkØ�dÏ6hðôÿmܹª€qC_Ê …‹ä Ö0b•³àfu)Sæ/èÑqæÜ©ÓçO Ê2=JÉíRÐP¥Æ¤êè*Væ\»~+6,Y³h{ªeëé;˹tíæÕËWãßË#ê8”>cê+Ç‚ÌɼŠË¶#ª»Î>1�±ª³îºE²Ón(î�R*’żР“©ª:ïæPo+öÚs¾\Î*&-’ê»/®üêº+¯½té @ÁœƒÀÄI²1W‹l2#$rBÎzÓ¤Zši~M}ZÕ¨ùôŠjƒuÕ5a…³Þºk^}µØ±ËÆKc´Sûã•1tVdhIž–îjóT[?õæ–o™ÿñæÁ‹ß­ðt!õYqA·´hþðBºS¥õmÚòº¡�åV îÜó\@ï%ëOFx׈{�øôŠƒÕoÌÕÏæØõŸd;ö�ß–ÖäS³§¤Â»¹ fÝê›ðb8ã%pg=K\»÷®ÆÉ+z͘žŽª·¯ë8ÍÓÜÀ¼ÿ+ð…tä3ß$tå5‰��}b»üšÁºùyì~ÍzV´âfÜé×â“÷¦›¾ù�P5#^Ë%$&±Aû“„òD:¨E-C+Ú%¬xÅ y‡³eúU‡:H±>W±˜\Ü–*…Ð&7Éb®B•+�ï,œ #'ºÃA¦¸‡´Xc|ö)ÊH4Д&aEK$Ò=ùKë0FHÖaŒV)£ –”—„Àƈ›ääC’¨Ä%–¬‰PJ AEy]‹�ƒŽ`¸%â‹a4ÝwƤ|}lc�¬G\™0>u´£ö�´µì±�ôˆ) Cȕᑊdd#-I0ÿNò•¼$^2ùšN†““ŸDb(EùRF1�¨Ä”*­˜ÅÜ,p#™¥ÙbËüàR—žãe‘ÜøKGÄQ˜»"æW…LeÒ'Ì„‚3MMd†eš‰¬¦#é€MIÞ“’îëf3¾) q†Ôxä€9äDRš’�pqç%ੳ-ƲžµÜh>ϸO]õOÿ|06Ð9ÖÑ ™Ë£XªŒ…2Ó¡ƒÔS4Ï8ÑE.¢‘ó{$6µÉͨ`!šiWqFR“º¥PTiÛéΗÞFž]¤§©ÀhOOàs.úd�ÊFú²§ æ ‹QPc.F�|¼«•Èg65¢€jE©zQ«jtÿ›ͪ7· N¯fVQ` åIÓYÖ祭¬ÄW»N³²t´µ‰Ù+“çEÕµµ& ëWBø©Ù¾‘¯?½­P‹PÂ"õ& 5%ù®²XâNÕrsèD'’+Y¬2ײÎÅlt Œšé’“2'¤)Y4èE¯ˆ®„%jgÊÚšÎõµæzóJ[ŸrMŽuon�YÔ°5© ÑŒ¥h_I󊌪~�ÛßÿÆ5ÃréèGüã‡X„¤ kƒ¬KPÂÿ^…ÙšÚ˼•¦“µ©{pZïT¯!&nñ¸[£ÆwÅjbžZ`,\±ä׸'èróÓãË‚Ès€Eºà�öRòÚcŸi1Á ›Ö»\o”W«ÂñâR4¢¹E£�åÍð”Ë#öòAQœL1ÏW8-žC}êsfüΘšÅµh›¼Üæ>—ζsg‰œgì†S~Þ# ™Láï¶ÕÐâÝ1yϸh»8úÑ@ >ò‰ìû í+îË=¬ó¼ð?Ñ#?Ò3¿è:½ÔáþÑŒö{¿BŠ¿·#¹Ù+­ú³¿Û›' ,¾ýS/~ã»ÿû»á»¹,¼<< KÀÅ›ƒÆ{¾ S:é“À¬¡@æÀ<õмA˜B*ô>Ï»—ñ†òAÍ"Aõ3AA8ö�¿I�¿D9Û[¹Ä;лÿÄ´<º)¾ã ÂäÂ\PÀæ3ÇKBÈ[ÂÉ›@'| (ä )¤Â)´B­ÃÂÔÂäÂÌòÂ’9»L;µÃ,Ã,9é²?5D'¡`C7”¹¾ >ì‰BË¿:d–Å ¡¬Ó! [�•¢ÄA$€BÜŠCDDEÌ:Fäp�Ä.D¿œ›Jd½µËD3ìÄ4̵5ܽ¼ë½½ƒC¿»ŽT ÅÁ#@Vœ¶pÅ¢ƒE€Z¯Y\Œ¢±æHtLÇ*ˆ�ØE*—{¹p Faô*I,2Žk?÷KÆ•�½ÚàÄÓ�Ád«gÔ¿hä¿i¾fÀE¸F:ÔÆ Á%o4pÜ+qdÿƒ)GX‰’tTGö`G�pÇ)„ÇxÔ‘y$”z´GbüBc ÃŽãǦðGƒÈ‰à s2§Oôˆü»Áp$Å8ô ‡üAä[8±˜ÈŠì¿ql �\ ŽìÈd(“2I‚Ø>[@Ä‘$”’4ɓܔ§{d9;! dÄÄ~dÁØsÁ S Ã1œ› ¥œl9hlCit„*QH† ÊlÂm$ʰ0J<¡„XD#Œ¤Ey1Ǭpʧ„J]�J‘’ÌÊ_ØJ®ìÊNúJJtɱt 2\F‡à�µt”¶\¢·ÜɃÄÁº,Å…<ņÔ5U„ÈØ‘HðyÅ¿ Ì\Lr,Ì�á¡^Ô²Þ&‰ìE`îÚ^"r ðí¯–`òÅRóm=z³ ¦IVøýàLa ü-aDa'^a.%>`ÚJàz™a&úÞÆá& &+ ÆTn b8E?ô[Úÿ0â#F⦠&~b9v¥(~2¦bAxá+ŽaîuPï]—î„&Z£…›JJ_[_šDcŒSc6Fâxãü5á9¾d¢Íµ&šC¦íåcöcæb€`ñ%ä­àó%cEÎ GNH6bI¦ä8Æd\ÎdBÓ5ÁÐ3”0˜Ðx»ñT†zâ ·ø¸(äü3� ž ‡ˆåYþ`Iž ÍelVá'ë_F`naŽ›^Ù;f‘Hæ)e fÆFNpfV6hvi¶SS‰d$¶æ1ÅælF™2•nþf¼1&çM+gsFgXUçT.>wnŸçŒç†˜çË ÿ{a|¶ }ÞgäéçËøgX æØè"sÕ¢0g@è¢Yg†c‡ˆfˆX6§~aã0½hýÍhLÖfw �æ��ç‘–N3i”æ³…®£†† Czé…ˆéPê—Jˆj©®éè¹fœžc�æež6·_þhpþiQ"è÷% ¢Fç”>j:Jj–Xêè‰fG–iS‘ê©vQ›¶ä«vâ‹À£�¥HJƒ!]Xì1ÓIR28ê+ê3$!I'H:Âó0$fˆlf@ˆ&†’rÞ{Ù–m¡Ç»Öç¼Þ€½V­¾Ö�¿~ÙÀ†…Á>Rv.±¡ú’˜œ’Å&¥ÆnÀ«€lɦls±êÎÞm�õ�ÿÐ6´Ñ¦¼ÒÖÚÓNít2ìÉCì×V�؆¢ÙæÃ'±íÈÆírÑmÞîìÏþíwÃ&¿†ÀlM«Áücm¨qí�ƒíì`l0rìڞɞì½nùV ŠðmŽåkHênì³âo o€Kn³ÞÅNoÙ^oÚ¶ é†ïÊžog”úÖëûíü&mï6mð6,ñ^íw:å>oæ6pçFpè~l÷¾íø~p‡p•×5ûˆ §<¶Ã¥Ó>m<åðbòpt6˜Š^LðGXpê^q"‡â-rq´�q0²›;£lX“¢ÃpL1©lî'ú¾£“Ê÷ò"ÿò€TKGArŽQò:`rÿ4 ‹'‡…(ïäÖNçkŠ+ñ,÷¼-É.Oq0ßóÚ;rò|q�ˆqˆâÆ578Sšòd^J9É0ýqS H�t.GñçsK7NE sd�AW,BrC$DWfÝb © Ó*HuUÿ¾H—t<§tK�u3õóCtN_rÝ™q'õf;tOtÜ\ŒSwQU_uÏkuHŸôéÖsYov†ðÔ!¾õH*ª1$?¸vl§¾¡±<æh©zyåXFÝNÐlrßëvvtßàËŒú>ªyÎçÔvxáö¬ðöMyåÛ(÷rOw~?�howÏ{wxÏy·z {ÿGšÌw}×ì~xˆ�hÿŸqw‚øü0˜m’(Ixé„SˆÿøÁ‘øu¡xW±ø¹0ƒyÎ�gQy—‘—’/“— ”‡•ïv–ßÔ—ïùE‰ù™yª¨y¸ùÅÈù¬xïÈ6ˆÉôy§ï ¡w¢7ú¦@ú—Pzf`úá|z¯Ç�¨‰©¯z«g¬w ­çzUøz¶{GþLEúïó<²·ú³'€´/ˆ¦o{¾‡é·ÿL¹Ÿû¬«{£Nc8|ÄÏûeØû¾çûX†ûÀ|S ü›7|Ä?|ÅgüÆß|Xvd1ø|ÐWcñ�4¤–bÌ{_xÎ_ýýЧçËýÒŸ’Ó÷ÍÔ÷xÖÏýÛpýÿÏ}™}õ¨}vüvÕ×}ãŸQ‹ðýê~®þv¼ýã�þ>ï íÙ?Ów'ÔWxÜ—~é§Îê´þßÇ~Ú×~Ûç~ïO�ýlßÿå'õxÓ7•Jõ¯ä�ðð7•Ñw^ùa `ð „ 2lèð!Ĉ'R¬hñ"ÆŒ7rì˜0È�F’Ìaò¤�”*m±lIðå@�2gÒ¬ió&Μ:;†Ir$¯ B[- æÎ¤J—2mêô©Äž ´(V[G_Bíêõ+ذbH @uƒÕ«Y‰n%8ö-ܸrçfTe÷®¤¼zéòíë÷/àÀ‚.lø0âÄŠÿ3nìø1äÈ’'S®lù2æÌš7sîìù3èТG“.mú4êÔªW³níú5ìØ²gÓ®mû6îܺwóîíû7ðà‡/nü8òäÊ—3oîü9ôèÒ§S¯ný:öìÚ·sïîý;øðâÇ“/oþ<úôê׳oïþýö²eЯ_>|ùRëÛ—Šÿ½~=ñGß}ÿµ`H P �ë!’‚ 6˜ÞƒDèß„êUxaOj(•!ŠÈaHR¢ˆ!’’‰â�åŒ1¦b"5Ú(a‹Ý½#Œ3Za£�<˜#x;òè#�5 é‘ÓÍ7à’I&•UZIåI'°å^M.÷$Q&yÿ%™PdiÒ–téer`Ö'&�e^yfi®ÉæqeÁi£œ}šy¦�yáÙ¦T{Öè§œt*É Èé)¤”ˆ–©(—‚6j\HŠhjè”’Î hš[^Š)Hš*©§Ÿfê–iñ2êo™n 阩VIi¨®Âꛬ§Ò'¢‚;ìÅ˪ºîÊ[¯¨^Y´ÑK¬±Å"«¬Fnøà²Œ5û+ŸÏF í´ÂVk-«Øf¤í‚ÜvKXñÊË)�ã’[.%ùê‹ ¿ýFò/ÀÇC�$Ê+¯‚¦šºä’ ;l*Žï†up¼ôžioå ¢ï¾ýò pÀT0‚'�°Ã ùðÃKüÿ•Ég‰±ÆçëñÇ G"0ÁSŒ²Â*óȲÃ.¿ÜUÌàÖX¯½5ÛŒ3*:ï,²@$h2Ð )iË=1Å‘^9Ùecü ÚiKÍÛmKÍóÈ>|Ýu“q7Þ¶VÙu‡_ƒ}°ØV–m¶½i«­sÛnë wÕrË[·Ýxß­7•|—è7X&^åàdŸmø'k'ÎÀ¯˜Î¸0Vëg2ätK>9åÇx9æ^i^«à�n¸è‰—~:Õ©;o뇼Nåf9;‹µÛ6îœë^8è½+‰é¯ ®º|¬·~|òt2€óL)ˆdôTv>Ô ‡Žøè¿k<÷œ>åâÃHÿ{ù;�?ãæÔ×¹öU~¾ûWö¶W(¥%â~¯ ß™Æ×?¥ü/E„ÂúÈ;^/�ô[ �¤ä@ÉApyûkÞu2/ÕÍFY¢0f3Jœ¢†6#&¡Ã^¢‡>\ƒ“³øHRL’¨DS0±‰Nd¢J*!Å_Pñ.)¬É ½ÐÂ¥�†2´™ o8ºòЇ= ¢_BÄñböRâŸ(Ç(N±Šv¹"M²¸ÅD¼�åªÃ ÃXC’Q‡f<#—1DªQGŒ“(Ç9¦DŠ• â/¬ˆG™è‘n.좧H›Y�m…œ0R©ÊD.c�)JÞ¹†€±Hr`ÿ’O¤ã%í¨ŠMr²b,ô$MÃ?ΰ”9,¤*W™HWŠ–çše$méD\bR“¼äH'ñIa†rX£ä˜1O™ÌT²’™!rfµ  Gi6‘šº¼fG²¹Í S”ú²¡1¦ÏcŒw¹‹9­€Nc©3Žìtg&ïÏ�È3˜ô즰¾‰O²mŸëç?íPI­/–{HC*5©!Ôš ÅHCùJbæk¢ áEù9ÎŒªb£ˆêè3íR‘Žd%UèIQêK-S¥Üd) k˜O‹b4£6õN«%ÈSì¤=õi%ë˜Ð]U¨ ˆÑûøÅ¤žBj´8+ZcÚÔ>µJ‹ÿx+\£j¬©VõWØO¹ÚU‹¤T¬öº§Ru†Ö´2u¦Ne$¯׸v.–t­ê]ÿ•×½^¤>¦Q¸ªQay¢³6iâò Z´*£´Å8mÃRö«[¹±�x-+b+[¨S´¶ÍÃr«ÛÝžÕÆH&M) Ëj ³‡²ÒfÑYO|ö¡íYK«ŒÓ†Ö¥ƒìV‹¥Ö¾¶²�-Îj{[Üî¶¼½ý­*ƒ+\‡WÆí”f5¶Üæ>7¤5íi¯ Ãì†ð¸Ê;I´ºûÝØÒ–¢Œ/yË«Ûó7£ëe/}.K#ÿR)¹ó­!hÛfÛûN7¿úåoŒ2{D¸À/ÿ‚Ì[Zø¶Áÿ|pCÚûÞ+Yسv®†¡K éRW¿>¦œX;3h‘ø»&S¬âÜ28½†ñBd…EµjÓ«ÄúhÝ4( ¯`õˆ›§¬Y$hÓnZËö�Û·Óâ ·4é³»x}é�x²¯ß¿€ÿª¤X±æ �;r”)rdàÇ(U¦”ÉæK™4 ã̹S§ÏŸ]ÿ 4÷(�ºI›J]]¨‘ë×X›nå,XӦ͞M‹ösÏ·påE�7ï^’�“+_þ0%ቆ#ö¢x±Ë”̳”<™2KË—[fÿ®¹ùfgϾC‹&j)jÕ¬£¾†{¶Võ¶¿â>ª»,ïÞ¾çV\ÓÌE\qÏèå _Ú5è `ƒ=ÝyWTgcØ=¨w#y÷x˜¥]yePèê�Vš{uÁUyÌçZlYÙ‡_~ûãHœ(à!X‚ €†H&©P„„Mx^PFyÆ”T6Æ ’r‘‡!�(žˆš•gbz¡©ØÞiï#c#0®I£}}Üh[Ž;þ磀A7$‚ ^‰åŸH2YXMF)%•SZ‰ }i¹%—ƒ€—@ˆ#�(æy'¦È^8¦¡Æ”š2¶)ã›6Ö†ã~uòv'pyÒµgq}.ÿÊè¬Ù :……Z¢‰fHkdZÊ$ǰÄjaì±#$«ìx�8ægêÍ%¤§Ÿ®)ê|¤Î­´œ¢Úßà†»ê[ܺº‘*ýªî†Î=‡ë“ºòz†¢G®Û�£H¡ï¾Ä{¬±Ê,ð³>ÜÓ¶ÒR›¨ó]KVp"¼"n0†+n€–{`qéÚë±_¶ ðngºîÊ+½/„ï¾üö+Ç¿ ,³ÁPÐ,±žÔ6emnÖWjWåÒù­ÅGŒë–ƯâÕqÊL77Ò�#ïT²¼(7}�JVd­5Ëúºü2Ì2ÏŒ©oÎaöÙ7›ë©Î¡ò,#pÇqhAïwöÙD�1pH/ÿ¥Ï߀/mµ½‚ 4�PG}ÅÔ'ûª®J’F!ùäZo͵×0köÀcVÅç ßm6¤—Þ÷Ú ¿æ°kqÇ=ÚhãÄ.{ݸ‰>GÞ'^£ûîåJãûï€îøà�Àá‰GÍ8¢U¯ 9x“S^¹\K�9Ø›+K3è¡‹^ºéÜ*\mÛº­Ù:ܯ%ûìÜæh;î¾íÎ;·¿¼>…2¾íFÃÿtƒ=ÉI­dPªƒÈ�:Pf °×s “ÑèD%ãƒ7h€z0 aÉ"@Âæ-}‚@ƒ W¸&Ô´°.8ˆ¡ gCø}ÆvßÈ¡ ×�ú0@ bPÿè@Ä–�@­2�×d�&ÐOú ÿúGp€,`ˆÀ2Ð� „ ŸSÁé\Ð7Ü =øÁ‚p„FŒÀ Ó·BÊÈ…w„! ÷hCŸàP‡1ä¡{D!…ˆtˆc�(œp(ÑLt¢¡EÁLQ"ϱâÿ°˜År±d^T Ã(°®k‚eDÌ?“F5²±ƒn|£®9Ç×ÕQ…/\J.•²G>íDüÆe4HB2C,bY ¢<2’öx¢¬*iÉK`‚š¤'Ý ÅOê*”u%ÄxJ2¶äp' ®Ô¸ÆWÆ2 p4b-G“#ñ%e—IÙcöÉÿÏ>ö$˜ÃœO1£qLdR™Fdæ\ž)£&Fs’Ó¤f£¬yÍLj2 Íh7u‚À†RœäT*Ï9�t¢q�ì|¥ÞO …õ´'> O~îÓŸPh ‰YÌ‚&3‘ËdäB—ØPIº�’5 E+ê¿‹f£]\GÁ ÒRŽ‘0©ÔˆIY‰RWº3–-%á<‡SñÍ´¦6Å©Nq ÈAúô @M¨P�IÔù8TšõJêþ¬I!E>£-ÀN@ØÂ‚“HÊ…bM)Òçüh«[µ;ù Òwöà²Q*aPÂ%»=–Uak*èFKZ›îs«XHíúb·Ç5åãµ° â‰Èÿ.0‰�¬ë9v»M½>_Ó³B_ãø×4v°…%,�›,ÅŽ‚±¿šàc!›Nɦô«n¼l2KÂÍ‚«³4ü,µB{LÒ–Ö´¨Uíj[+#ØÆˆ³¥m\oÛÈÜê–·œô­ÜᱸÇÕIr•ûæŽÀ¹Ð¥•tDÝêŠn²•�¥v¹ï¼3¯§È[HóŽÖ´mH/V;öÎǽ¯•­å;_â6·¯Ùí9z«ßjFD‹ý=�_ÿà+ XËEPb{UŠL²¶³®«Âä&OJš gYÞýØs¢‡b“ØÄ¯Aq>T\ÛÖÅõµoŒñ‹Å;DÿR‡Ãñôü[Bw¹É rq†ü\FmàÏ€î‘#›ä»©Éˆ†Å“ å?L¹ÄUÆ j`t?}ˆÖÃ]6ijG¼^ÖãÓ 3™ÍLBú6Ó‘jv�Œiìæ…Ày:r®�Ihgâ¹°zÆ Ÿœ$@zzƒ6i¡ � D;³Pî®”¿Kå [¹.”¾ß¥Í›étnúËžõ§E ßË÷Ìux1C±êü¶º ̲Hp½V2uJ¥pò3ÁìšJC*R’Ê·eðåë?·Ý¾±]~1–±Ì”H¿Ã…ÂáĶ0âáGÍé’⌊[\%[g+78ñà �µÖ|¥êÍ/8ÿhQS|(³ü%5Ý+X·ËÎÕw¿2Þ.›7 ×doHéûçô’L¿7ðo]St/¸Xfj_$|áöiøZ ñºtÜâOIÆC¹q vüã!/`pI%“ën.)_ÊUX.0—Kæ2ïÍÉns6â¼_:Ÿ!Ïïwo ë›ßý.º¡Ž~·¤+�éö}:..uª?\âá« Ö+Žqk¼«�ü¹îrhˆxX>ñ„£ÿ…¥wß羕…Ó1~\h¦õ…J'†ÃB†ì×'è •††—ã2kmèo/XsqhZøtøHvøHŠg;;¸‡Ô‡Š%„DÈuºRˆ| }Å¡ˆŒh~éc�j“ˆTQd‰ˆ�‰™bœXpž(yP¯QŠå‘†þò/lÈn8r0øŠ6‹³¨Dµ¨D·(:¹K˜„Kq€ 8ZƒØ€ò¨DbŒÕˆÉ…(‰MÑŒUIШÒˆ@yC�é†õã;³‡Dµ7P¦È2×ó/ŵŠD׊tgŽü„Žu±âÓÒð¶ˆ�¨‹ $?ºƒôø‡æUP]ÇÌ´1xÁ�ÿä�¯£ŒÜèr…Äs�‘�%³�›Ø�J÷�%ù ÇL,y måCÙ2j3ÅÅX™•1Ž WŽÃ"‡¥“Ž&yÒB’&):(9„*ÉOY.¨mŸ¶e%N“¥Pܲ�çsŒPàˆ¤·ŒXA$v˜‚©_BéD©+FiSÕ8JÉ”MÉHO•=4•]ƒŠVùWY©•Á•V‡_ ‹3’5huÜb– w’i¹–mÉ-o —ryLtÉNv)-xÙ:zÉ—�è—W˜‚˜/·• Zƒ×7xúr7(4pñ“V>T\³9-Jñ;ÞT'¢]Ú•7,&3ZôˆT27aSÿ� •#>�èI 2Ôt¯qîé\ÎDáÂb…žø@biB îyb6¤Õº@ïä *�IñH>Äbr±¸GWÖžî)Ä3&œYCœP`tÇy6É™«#Í™ÏùWщ3Óé;Õy�ØÙÚ)_ÜY@ÞIDàYâùˆ¹9^æÙö©ž1Äž®±Ÿð©Xò .ô‰Qö‰Ÿ¥·Ÿý)ÿ  4 =Q Š¢ ªD *_ ú yeº¤Ú œ*\WPsPj6j!Ú#Z¢Ou¢j“ÔÉQ]è-ê¢D³�Ó�nñ�ºžü4žRèB; =ëÿ™j� ¤CZ¤Gp¤i�¤«•ŸLŠbþ9ZÚKª@ : ÚC j*¶Ñ¥^zO`z:8œ1œgJwiº¦sЦ`#" mÎÙCÐ9Wùh§*Чƒç{ú¢´£Ñ3£tP£7*-‡Z�`Øš­ç™žŒú£Ž ©ð)©”j©ëƒ©î٤𤞥 :¥¢Z¥ujªXŠªZªªš­êª�¦,1¦›I«^`«hj�º SÞâ«f§Âj¢ÄZªw*UÉê…éìˆä¬“­ÒZ¨8Jžã•­ÚÊ£Ü: � c¯:¤£ ®òUŸè©¤~™©îµ© ЩŸêF¡Z£ÿZª§ ©Ú§aúª±j5³Z¦Ê¡R€œé#4[  ÊD÷°å·—Û§0ú§2¨4 %ÇB¨ûd¨f屨º­øà£8¤ûz&‹²´¥²÷y©Kz®šê¤œ ¥u ¥P@¥¤j¥òjYJ[[ >+S@+¦²J¦µš¡·Zœ®W°CQ:J»´#jDâ5å"C)Z?ÿç{û:KD+9˵Æâµm¶ %¶Fp"Ì$;ãöï»ñyLü„HÅN²Ó“XáC°e�Ú©xë£:ªbI#�;¸f%#þš¸f:°jz´ú¸¤¹;¹eQ¹.ó”˜k¬šÿ«pœ«“£ñ¹t 3Å5ºе6ª±Ô¶b˺Œäºu»²K¤´»O¶ûW¸;ºÛ}Ñлñ»š–Öp"Ãk 9´ÀßÐt4B$=ûlùŠeÊ[qÌ{¸ÿJ´‹»¡ÆI½lj½p€½¾ª½yÀ½ýâ½1”¹Š7¾Èè¹VÛ¬“¾Z­ƒÚ¾_»±ÕªKª+¿HD¿�$#±û³[HµKD·J¹;…,ÀAÀ`ÀœÀ œCì“Á’6Á<ËûÍû¼«¸Ò븂¹+¹Àª&L,(¼}�)¾P\(´Œ 2|‚j(¦‹º¿¾Ñº±óº®ÄCDELGìEIÿü)»ÛCL<N ž‘À`0Å l_u\4‚¼J� žüÉkÒŃðÅ+°¸J°¼« ,¿º0²ÆÃÒÆ*Œƒ¸%rœ>tlÅÅqÇy%{ŒÃðë±¼&„Œ¿D¬¿FÌ¿Hì¿J¼rŽüZ¾KÀ’ü”lÉUü—²É¬kòÉ \ÁÎpÁB‹¸a½§<½H[Æ×{ÆÙ›Æ”‹ ^#Ëà»Âq<=s,™Œ¼¼µzlç Ì©ëÇŸÈã È�pÌ'›¿m°¿OÕ¿ãð¿ÐÀÒ<ÀÔœ–Q<¼ØŒÉºŒÜœÅ_:àìÉ¡lÁ^<8¤u6äÈÁ†²góci‘¯È‡|ùÿyñpÓµ@óC-¾ÓC ðÓ €B¥#C ËÓyÓH}ÓöQ\›¶ih—Â¥§ ý.ŵ/2ž0âC æˆdº²/›vrj B‰aÀæKbðÐÖn­Å&#Y0×tMÉœT)m6+]2.m60�2=ÓTWÓM�Ô9­@;í)= @Ôé3Ô1TÔ^ª”ñ°ÔÕÔ©õÔÕzR}SàR2Vã‰Zýi\m^^Ý@`m(b�Zdý*f ”a¾ïäÖo ×Ö*×t=×v�–x=Z*Ý•,%}=��-Ø�'�Ä`Ø¥ÓPhÔ> ÔBM:DÍ´­JÙ–ýT˜�šÿ�Ÿ�ÝáÚúrÕKÚ=´Õ]=„_Öú2ÖYÖŸvÖÎH´K¶ÝÖ¸�Ûó±Û¼�Àw-Qy={­+Å}ÜÉ­Ü„ÝÜ8ý܈ÝŠ- ÓýÓÕ ×�ùªÝ³ÁÔ˜ýÝQ­S}ä-æ]¬PÚõpÚ¤•Ú°ÚØ'ð�£ò]ô]��8žã,VÛù½ß!ýþ�[–zM3àÞÒ:ñÒÓ­Š|™ðäP¾àÎ�ÐýˆÒÍØÔýØÖÙØ=ÙG½ÝÕÝî—á=ÞîMâ¢}Þu�â*ˆì­Úg㥊±�Ö ‘ã:._îÍ2bC.Û)cäÂÍ×Iî×KÿØMîxPåÌ=åUηÆ:áŽý:��’}e¾ÞÔc®»eþÙg^â¥Êæëm íÍÚïíÚñ Ûó-èxŽã;Žß=Þç[ü€îaDî1€f;îö¶ÓqW¶§�þäù™­‰œØ¨±Ø�Í#ªÅ›®¥5×Ölß;¿£ ¡.⣞æ&nê¨ýæ-ç¬.ã®Nã°ë³îFù ¶>ùèv>8½.:¿îÁ~ˆ¨äÄ^ìÇŽ­ÉáË.áXþÓÎNCpí}0íYSí�6C™«í îÙÜ®êh> £½æémÚ§žê/.ç|Kç¯>ïë°î!ÔîpmÀñ®ë‚¾.õ~7÷ÿ~ùnâûîßýÞèÿnoåNéñÐþåŽQÔ®^íÙ.ñ!>â¤Î·à¾ââîâe·êXðÚ›÷ u^ßaò(B*¯Å,o<òÎõ¼þg¾ƒÀ.:Â^üޢŞ ò0÷tÈÎÌu ìuÁì@ôמáDÏéFßðHÿìØî;ï Mßí¯æKõnŽêpnñ ¯"�î$o&¯ œßù,¥+Ÿú¢ecOòeoã)óg3ó5_ª«ñöØ÷t_÷Mq÷ýà>?ð@ÿ†ÏK¿÷�/íƒooøK¯í‹oñO¯�¿,NõÐÚWßêY¿õ¨ßõ±ÞùžV ÿ/ú¡àþ\ú”túyE<ªo6¬Ïö‡øú8÷Å>ûso÷�÷z¿|oð¼ÿûK8PР4„ ãõaÈ0ÍC+±LWq Á‚ }m䨯ã�DŽ”RrÚÉk×­ gÐ`4˜õdºYP³¦5œt)²¤”‰XRª\é²à3¤2ëù д)¨Q¥BÅPÕª6¬YÃlåÚSä'°aÁ�%‹ÓìY³N�N`Ó¦Ú§låN…`î]¼Qƒìå[Çï_¯þ &àÁ-[6PÜøäÉÉÂcŽæóhn¤OŸSÝzìÙmç®»¢ ðá¡Ã ž/6ôé·­g¯Óý{÷“ë®5_ß>Ûº÷ïcÞû°W 3ìÄc̱Æ"“ ­á*ã/ˆÍ@òì³×HKMµF.T­5×^‹M¶j³­$ܼãÍ·Þ‚®AãŽK¹åš3j¼è¦“κë²ÃŽ»î¼ O¼ñÊÓO?·jBàH$ñ›Ï®!›Ä+?'ñzÐ?¿ p° 4Ê@ÅLPÁ&k�„#älÂ^Í‹0Ìp479dMÍe‘¶Ûón7£PLQÅ|Æl±¸a‹9xœÿÏÆqœCÇyÚÛ§•.R\šŽ+óûœZat²§®Új¬³öí/®÷õÚ_ÊÃö¹ô„ÏN»á�Ù–8ënâñ4¿¿™4ºÉQÄò6œ°Ÿü<årª÷mpÂÏ1�ÚPެ±„çòŸK½ëÄŽ\›Ø…¶¼hÐÙZºÓøA�t©Mw÷ìóï]ݯÖeãuèhÁf—¿ÚYív÷È�îxç»xnâ#žQNs¼�%oy ržÞ WÿéM¯z帞˲§=Ãuï{àù¾a>—Ý+}�‹\ö>nÔOsnᜟv¿Ю]ûC] U×Öµn€6\‡Ø„¸.ÛÝ®�l{àïN<áU°c¦Á`€@£‘§[Xÿìõ?})ñuLt"¦@)®Í�Yƒ OFÁѯ‹„ùâÅHÆÁDnÓsG{ƒ=µÑ#+$K Ë“óͰ`ëc¢÷ØÇqý�M]I5"ÒˆCd—hÃF¦«lQLÛÛV±J^q‚Y̤¹(äÿMŒb,(ÿ Ê“‘Ò”-3aöTé½7¶2ޝŒF,íHC Õò}Äeçt)ª@þr�Á”×0ý‡D*ÒkŒ< 2§ÆLµALwÞ¨b¥yIj^D“ØÌ 6=ÉV°wÅ¢žÃ»˜5F[ß¿l¨Žô¤Gÿ¦“ÝeSjzSWå´§U}¼‚ÊÀ¡öF±ëC*ìlèT~AuR5UwjU´ ugö¸W_µÚUë€5¬kEÊÊ;µ®õJm}k\åÚ‡ºÚušxÕk^mûÜwüµ$‚ìr ËœÃf-±Eelä[@ÈF”%o”hjSéàT§›õigõñÙÙþÓ£�\i xZt<5ªS�g%À0ÙfÕ¶¸­Žn¿*Vá‘UNÀ .Øê¥âjâ¸ÈM.{³æ:º}•®¨Ø ‹Ã°0A,ÌÛ] }·}á�ly]—Àsÿ0p&¼8sˆÁÁ}0‚"<á CA|âË0,6Ìaé~˜!q4J|Ž­±¦]±xÇûb8ç弘•€fÙ{c™ y^ò¥/ÐìËD gCÈüM˜ ÚøÚKÉÎðª�ŸŒ³(·fÊ qAW 7Ë[^—¿ì×0˜ÌØ%±vMÌ]5{—ͱc±dãüj¹ÌyÆu®qOñ\=Óö�¢Ýq}{¼êØzЭíïkÝ‹Õ$˜Ñ¹u4oìÛg­Á.„/m\¹nšÓ8óô§£jêŽÙ­Øv›ê{r­F¬Ý-Y»A½ì-2PóŒh:îZÇqà17|ìü¦Vµû%6ÿ;ØËÌÙîYÑ·]¶£v Q(C›¼»—ZBë8f›×Î4…“»mœ•ÕÛïà�˜ýæ7D!ê4÷27×|ßu/ÕÕïvw¼ç}g÷âx˜DíµŸ ó<È_-¡I|'ûKf¶“­{³(SÜ^gÆ«£ñ‹Ós­pou#roó.K'‡[Ê™³r{µü}/gµÌÛMóšÇ½ò¦1½o�k>÷<+Ư~>äu}aÈÎw7¸ÚðF;â�–¸Ô»Aõ>X}X#ǹþñg]N#û€È~2³ÃíÝP»åØN¹¥²îq·ìÜonãœß;ÑÝà9¿}íou7Uè‚&:à ÿ¾Y„'¼¶ ·“ütqD]ê�—<å¯Ì�îuÏë‘fÍs¯±c¡}éQœ•,õ3_=œm^wœù½²ÏqŸ÷þs@ïžèE/¸à�p]žøÖzø£¡ÞøåK«‹ŒŒkŒ�“�­ƒ¾èkƒé“¸Ö°¾ëë†,!%”3»î;µs3=U:¡¿·+?ó“;:³3ØS?�+¼Úë·ðÓ=¿6v±¿#KºÂ;¼âë?g‹¸q�´Äƒüƒ,„DŒìƒdÀÌ£>€Àë›Àé©À”»@4C5 L7?·{3|1ÕA䩜r{Ã5=;!(ÕÚ@¦²¡M©)6LÿÖ:8d¯œŠ:Œ‚{Ã쉟± 0èÃO¥”!A$1¤ÇóŠŸÈEÔ"ƒ8�çHŒD=˜DJä’<`LÌD¡¤èÄg˜ñ¡@¸q!ªS”Hg„Fiô¨Â«¸�ìÈjÚ¢FxŽ‘Ç“LÉç8ÇOšrIŒ�I™œIÜóšºÉWËIÛÉž\¿c|ÊsøÇ€?)J� Š 8ÊšJJb\ÈclÈ<ŒJ˜Ê‰Ü¨g´HŒÌJ�ì‰D\Ä®lDÓKoËq‰?¯!%r³¶œIΉK¹„E¨âB»¬EŸÌË� J€ÔE�äÅ¡̉ L`4aeR(ž'ý2KdIœ9T+]ÔGµ'H¥¬/ýÂe²ÔŸÄTùôyL½NMSý Ua$ÕReJÄL›T�SˆœSª¬SWMPàÚÈŸèÓ?ýÈ@¥PoƒI]½^EËz_%?ûÖa�ÔUOP=(d•Í5bÑe-˜f]ªgÌO•V8¤ÖQ5U†ÌV4[ÕnmU-RX­LYWÿZµUAý4uš)ÕPÝ{׉×ÔRG­×É ¤”ªõä)8d­ ¾]+3À\ñ�‚Í"2žBX6ПýY®ŠZZ¢]¨­r â— ø<œq!‹‰��ª­Ú°‹ÐÃ4L{®.K¯ýZ&b¢,5Y²u”-L•ÝÉ�jY©zÙÙë ™E7šÅM¡¹Ùœ-¶žâÙŸÚ­Z¢Z£Õ*¤}¥�¦½§Íµy™©­Z«½ÚOÈZ­Õ®Í°¯Û°- ±-[ε�³íÍ•]Û3pÙ<ƒYÚs†¸å†÷㆚µÛžÒÙ�ÒÛ½Õ‚ �ˆ¿\Ý9ÚÆHÚ}YZ²kZÿòyÚÅ�Zøp\ª…ÜÈ5»É¥\ÛêÚËM‡ÌÕ\Fí\êõÜ”5‡Ð=¶5· ­Ô]]�¥R¿ÁÙ×ÅÛ�EØ[©],¸ÝZÜw\Ë)\,8Üñ ^ŵÆ-^ãE^ÉÕÚç  ç…Þè˜M©^†šëÍÞííÞ�C]ö˜Ù¢ _ ß»-´ÍâÙôí[Û½]÷…_£‘_úM\„ZohÜý…ÜþÅ´Éàç`.’Žáúø\ÖRàÑmÛÒ}[^f]¥:T ._ Î[ôEõeßÞ]Âí]Ãý]ĵßÞÖ_Çå_å�Ün�váu(`þâ¹ á´¥7í½aîÍaï}`ÿ¹�à_¸!_žbÖ: 6b ÆAÈã¢Í]Ûò?þàÖ!™ÏƒIáÍ?÷À!+N¹åÍb® àõ  Mñb0žäQI`µ-cÒÅ5Ó…[5V]¬˜[uâ7®à9¶š:žõÍcAØc¶y.?ö@æA&;B¾ß{9äñd"FæGŽHŽd· da1ÆÞK^`4nàïýd6e7>8Þ)9–*:.bT¾cUfå‰qå?.ššå“«å(6d�ðP]F ¾ÜGn`æažäb¶áLŽâZfmeQ†fR¦f¤s˜ ƒ ÈfÜmå>îfnøæ‘äv,ä[.ç\¶¡]ÞÎYgÿ®ig›xgx¶d2FfMÖa{ÆçgΘh>�i6„j˜h=ZáfXöæ@NhZ^h[¶\vËs>‹šh_fg‹^Œãx>f3f`Üámèa †Æ Žãu)åÁ»�”ž�®…–.è—>è˜Æ…&E†¶i‡ÆiˆFçÖái ùe‹j0î¥^b-Öb¸v¥P h¨k»ÆÏ1�Üà>Óˆ¸¦Àl;l† Ê2kAÅ^ìÖ�ÐçØžŸPå”Ð –`‰Óp˜öœëzØ®àŠ©œJymѮ았µ>mz:XmÖ6^9ÐëŠ(¿f”ÀlÂìÀ@lGYlÆf ÿdž‰ ‹ì<žìܨ¸ì†™?¶àì΃ÏîCÑmÒ6mÔ®îÕSmÖ^m׆m>ñÊÙ¶‘ÚìÛÆm¯ÐmámÅnl@�Ðà. ɾÝ0nä¾åž æîìçƒèmÒê¶n‡5ìÎîí>‰Ü�m˜ùëðo;Èí KlôVoseïãnA î﨔ù®o©¸oÏ~îý–‡þþï/qðÖ6^îFðs€k×Î2O.k! Éö–‚÷Žo 7 ‡áð¨ðð­Èïß7q#—)×n7ðØ®Î¯°¯«�?×ÏñâÞñFèq¢[nÃinçñý&ré8rÿ4GòÉn%wܯÎÓ˜¶(O®)§+ëXl�´ñ wïá†ï-ÿ‘ ÿò¼ !/sNsD×¥$§ƒŸ†‡sÓ�sã…q¯(¾êÀóÌ\ïçÈò>×q@çñät¼ ôçþi NtTסEoôG÷Ê8o°9¯«À°ô9ÀtêôÊMßsïô?�@8ó õÏ6õT/vÐYõ%wô&wõH‡õI—òJ·t[/W=—+ Çðq�oP§oQ¿‹r3b7vqÿdws&ïn }õàŠuºšuiWì<Çr]×ò ÿô.u`ôÖ÷Ÿw•r¯Ú7göF�tÇ¥ôž õioR\îyçõz÷õÿm÷ñ¹øvñ ÷Ïxý¨•ÍȲº Ò°Dbas:è0kùǬV1ÇØ——Z1ß™ŸyÒè²AÐxœ/?Ž× �§+� ‘¿’7yGAù2Tù-á’–yøˆù™—ùšÏ°›Ïyªw·�‰ž‡‚Ÿ¿ˆ ‘¡—®“7z¤w K\ú=€ùæ~z¨ ›¯z·‡;3Éú­K#0úú¿ {”{ƒ(ûÆpù³oú´Wû¨o®©{Ä�³¸ïù¹ˆº·{bÀûŸ°$¨|Ëçû‚ðûB|´ïlµßÒØ”ÃO|Ò'¯Å÷øÆÇ�Ç·{É/ Ê·üÊÇüÄPú¿gú÷pú§ý"ýÿÒï}]² «ø‹¬ïSru|Å€üÈgs¢Çد|nš}|ÀçÜŸùÉ}ßÏþß~ þž'~Z] ä7Ëå·ŽæG‚ç·DéwyÎq³Ï¿þÝ×~ù×!îï~¿~ð§ûã‡|ò)Î)h „2l¸0Ĉ{&RD`ñ"¶Œ7qìhí#È"G`ò$Ê”*W²léò%̘2gÒ¬ió&Μ:wÂÄàóg� P†%êé(RJ#kêôԨѦR-dõjB…·F”HqâEŒÇŽr¤È’<ײmëö-ܸrçšü ThÑ¢H“.…èôiT¨T«^µšáÖ­€ÿ3þ 6,²’±™ýˆ6-ÝÌš7sîìù­]ŸAëäջדRLÿ ,xp´Â†'vȸ±cÈ‘'—­|y�Úχ/n|ío,Ê—iîœôèð¦S¯Ý°öì]!n5áýûö<�?nþ<úôêévhïÞùóèЩW·nßþwðÛÇ—_ïÿ?€þçÞ{ð!ß|ôÁsƒ‰åç]xü …Zxa\¶gà�fò!ˆ ŠÈЃ&DXyb¸"‹-º˜’†pˆ  †8¢ˆ%:¶‡„/úø#�ëÅ8£‡6f‚cŽîØc�M:ù¤fCH£‘G"É ŽŽ¥˜"”]zùeN1JFÿ¥‘Ÿ˜yæ•Ý)©å–*‚ù&œqž$&YdÚx&ši6”åWmº)' �6IçXøzh•xš©gCq8úèŽ~ :)¥.ªÑ¡ˆ–©¨‚ Þ¨¡> )›[Vz*ª^šQ¦†&Ê©‚ †*ê¨qDÚfª¹êúßo•YðÁš2,±§yÒé8É*ëë®Í:û£¯Á Kì°ÆvúÛ³Ùjëb´Òr@mµ§]{Ù¶åš+àoÞ~ ®±~b{.¼ñš÷[Œ¿éæ.¹òê»ogôjh/dø¢Å/ÁÇå/�‡%ðH;ü°N»§ðE ‹1ÆÇ$q{[dñ‹<2Jwà1 “¼²Æ&£¬ÿ2Ë1;ìòe÷¶ù®Ì9ë¼3Ï=ûü3ÐA =4ÑE}4ÒI+½4ÓM;ý4ÔQK=5ÕU[}5ÖYk½5×]{ý5Øa‹=6Ùe›}6Úi«½6Ûm»ý6ÜqË=7ÝuÛ}7Þyë½7ß}ûý7à� >8á…~8â‰+¾8ã�;þx¹~29å X~9æ™_ùÕ’S>¹æ¡gι՞.:ê �^µé•§úêT·úëšÇ>õìƒÔnûíQç~ðÁk1<ñ#¿yïPG±<ó ¼ðÄoüÈ'ï4óÍ;/ôÀK?ýñ–_Ÿô 囟ýòÛsßý÷ZPoýø?ûiþùè«ßýí¿oÿùç“Ç¿óüè·ôEá~ìûÞþпàüOc~ÒÕW€ R°¼ ‡  Á Ï ÔŒ¤ø¥f.‚Û£`/hÁ nPƒü`fB(Â.‘s&t '¨Â¨….ž½B\Í�†m‚ úJ“Ãì°,lá …C"ñI5¼•˜Ã&>‘ƒ@„!]dXÅ&]ÑrYÌ˹ØCFqˆ¦£“ʘ€3%�;ìâ¯D.ÉEŒpü‘ñ§E ¢�†Ä£¢ÈǸøñ�/ d÷IACr�Pü¢ —F:²E~2 ôJCÉQV>®y†"ûÃH*ž„“�4ŽŸ‚DPOÿ”¤å)O™Ê?ÕDsnø%0ƒùK®À•¯$N,eéZÏ–·4d.]³ËœøR˜Ö$¦1�)œÒ ›ÞT_Â)Nƒ�³œ²)Ä)·’� °“—¹#¦7½I@êQOö¼'=ǹljÓ-ÜŒ' À)Îp–³ s8g‰Ô‰vA•x§Jƒyæ³4ù¬^æøÙO¶ü3ž¨AÍ)›„:d�ì|(J J?‰R”žͧæ4ºQž,P‚9(AË™íl‡¤ 1iPÚÊ6-�˜r8*R# Ô¥.ñ¥ôŒ)+g—šžð¦8-èN±Ÿ2¨&q“J͇Ԥ.U©MEcÓ ÖµÊTª6ÿIUqhU�ê4«[}�B‘ÀЯuKEàX�ZV³æP’\+[£êÖµÀur³¬* CJά6â®ùÙ C÷Êׇ’Ç| ,hå0ØœµŽiEl˜§ÉÅ2–<”{¬\#+ÒÂPÖ²ßÁlfƒºÙ™¯ ¾ýmh;ÚÒe‰¨MíòVËZŽ:Öƒ6•-9ÏYÛžâÕ!¹Õ-_y[¾ß7¸d-+q‡b\ÔªÖ¡Ëeî `;�%Tºv¥n~Ê!ßù^7¥œ @o¹[ï~—©…E+ �[^^ž—¦Í]&d)Ø^ÙL·+%š/}s›’-å—»üì`à …ñ"vÀöç�Ÿ«àÙ^¥Áy0ÿ„ËQß”jwúÝï…‡û_Ó˜¼É5ï‡qB,¦O ¥ÊþP…!3Fz ’ °•ÔY).‡Í¶¤9ez´KÄi$+YuùÐêkkŽYÌãúøÇArŠ|ä$/Y)M~r”S4eeZy®ãÔ²A¹ìÃ/+6Ì/Ù±{üc(œ™È‹1r’•ì&Î;bæ¨\gbÏyöV—ùüF?ËÐs´™…lh@ šÍ‹v³‘©gO_N}2¦ôU-]N=·PÓÊåtK<­½A:͇^3’ÛŒƒ&«úÑRΜ«3œÃ60»Ù–¦,eYC [ã×,Ñ5¨KÓk5'ZØÄVæªÿ ¹dƒwÙÍfö³¡½SiS›ÀÖ^ ¶ÉÌkQûšÔÀVtC­‡b/ Ò P¯@^íœs£»œÒV÷ºYÓîwÃ$Þ™7š¹mê|£zßà6¶œ-p)¼9oÃ9Žpìˆ|§`æ´ÃˬmzK<اvª/ÞïcÿÛ¹Ûëø>rÖŒœä<ÏêÉýœrˆ�ºÔ.§8Ì-.Ë‹Öpã8×¹lJŽp©c‡V¿:Ãÿ,î@Ë;Ôÿu·_þí¥çÓš—sº² 0p‚ïü/=oÕqu¬g=×[ÿt×Wþu{‡écâEÍ®q›;ïél�úÏG÷¹[½î/ÙäwMâa b¬ƒÿ0p K\" ˆT –fÁ…q ‰Ĉճ>5©¹³iǯò�üP(où‚` öÙ|ç?ŸÃУoô,=‰­‚ú…”ˆõ­w=`/û[ÓÞ$¶Ç=tùÅd¾6Àç¼ðQHüì¿È�.≑úü8õÐ�¾}bˆÙW%×Ïvö/Xùí¢û‰ù¾ç…ßõ èéå…é]Åò @óµßûIßüQ_õÝ_ÞåŸíïqŸïi^#t^ ` þ”ßùDÛ­ßw´#D`üM_µÕŸ>ÜäéßîÍAïýÞŸÀ` "àñ)`òB> ó½Ÿë%†üÑù_ýY_äáŸöm`ÿu ÷í øõàöþhXA%ÚÑ­u° ”¡2! º› FáN!r ‚àÇ�ÆhlaæÐZâ›N‡”¡œ¡:¥áªÄ ªö€¾aÆaçÍ!Ö�v{᪉ PÇš¡RH f�æbQ¸az \$JâÞ!t¡ l\¢C|‡& ¾Þ N` ²Ì]¹„"Ò`îÙ ÿùßV $Òá$BO%¢_aÀâžxÇ,ÂG-vâ-~bÌìbŸŒ/Þž #£C#*Fb2Ï2ºb3‚!&F£sL#üYG*W@!ù,*±üÿH° Áƒ*\Ȱ¡C‚"JÌF±"·‹·iܸ¡£G; C²I²¤É�n¨Tù°¥Kƒ bÊ”(q…Í›4rêÜ™Ó�ÏŸA‚ ݸ#F+H“¢ZÊ´�Ó§û¢JýCµj´«XóhÝJ�Ú»¯ïæ‰Û­¬ÙghÓjZËVªTrpãê™K׬ÙjxóŽÛË—iš¿!ë ¾G¸°½Ãˆ ÿô²±ãÇ�#¤±¢E£Üˆjôø1$H“ K¢\ÉR²i‚2gR¾‰“§ëŸ@…Õ¼ 3·¤J™.} Õí¾ªV±^ÝÊÕ+XoÈ“Û-›V-Ûµ¾÷Å•KwîònyóºÛÎÝ/`�‚ëÿ6Œø°bŸŒO«_Ïþ!å–)ڦ͹£çÏ¡C�&Ý^rê˜ï±f“k¯Áæ†l³ifnHé¶oíDU G\]�õNrÊ-×ZÏAçÛtpUgÝrÙáÅ]wKý•F`ƒ�wOyæ¶X8æØÞ{ñe3Ÿfb)d~DŠRJü騨 ( klD)¥‹.ö`å•´ )ä\vé *Fè_|™`æ™bhÜW"w݇τ4tÖÙ¦7בHΊÛy÷"x‚Ñ(¨=繑ž’ˆ&Ú�ñýH”–A)é~+)Ú“N²¦Å¦œJ9%•i\y%¤– ©]zé 8¬¶™{�ÿ‰æ…׿›Êé[�vÞºœž|ºã'Œõ Jc¡‡Zªì²“QÖ££�*i‘”–ƬB˜®& §�zʨ¡ŠÚC©¦Bš*—_¶ê꘰Êjfšµ²é«]pêê¯tÞ™'‰Á h±Æ&f#z×l)£–A«‘´ÓJŠd¥#”-MTl1·›zû-¨âŽK.§žûAºêŠój»î»æ†óž•+„sâ«ï¯üòé¯á,ð=7Fì3Ž_fT–�6ì0iüÜ#mX4í´Åc¬1¸ ²¹ç’¬îÉdºk‚ÊÎl8d—m¯TøB#¶YÀÚÜâw8ª3¡úóÝì-fDkÿit‘[kðÒš9ý4Ô`¬ÅÔ‹kuÈY¯Z2×e¦LëÊk—U¶Ù0ï*sËeµ½âÍ9Ï�,Þ¨›öžáM³âúë¬cÁ°‘÷ÝZàI/‹Íî¼NTìˆ'.µ·T;þ1ä©–¬¼8°6?Ž×`ÛÊáu›“}vTigÞ�è,¢â"±sÓÍ3Á©—ï# þú±¿;볓T{í·#�(úø÷Ó¬¯8ãTªÚñ°–¼å©Ëy(“œâÅ2¡á�¬8´‹ Z0{mòƒ7Ƚ>½íOq˜ÎNg¾*$ëcëÜçºØÅo$ó³�Ipw¿üáÏwâþG¼Æ‰êqì’ÿˆÀÊ)ðC ¼#X= Z°‚äÐ9X³Ñ}|¦«[²Lˆ(&åO` £ ñÇBV¯c¢WíÂ�g1ö+Òr‡-&ý‡´ÑH#ÀÇ>’á�€ ^IÈBR ˆLä&ÉH­µª�Œ¤×AÉJã’˜”†&7y§;‘à“ T‡:Ü&O˜ò”„¹‡ÀR'õ¡ã•è¥:ZÅ›EÂ-„á+Ì vÉK.*Ë‹ø £ÇÈ»2ž�VRã}Ø(·ò +Ž™#CìxÇýå‘({ì#HÄò›uH¤"¹HG²*’’tW%-‰ÉKn’“�ä(C9J©”ò”¦LårVùÿ•V‚–±%-ŸbKâ2‹÷àe/}©(`¢O˜`$f1YxLd*Ó3ÌáÎà˜¤hB3!ÔL ó˜Mmró�‚g!ʼnHr–SrêB'$'¹ÎF´Ó�ï”F<å9Oˆ’”Âg>ï¡Êä°’N®„¥,ꔂb´™Ó¥B·ÈÐ9”wÕÆ¶ÊÕ0xõ««X+ŠÆ‹†$—Zü¨@¤¹&eUaÛ0€\çÚ1mnó¤)Ué!YêÒM„Iyá¬`iºÎ›CP€H¬b³šŽÆ:ö§ö„P&KY}Ú…Ÿïð'@—ʪZnâ–¥!a¦JÕªö窻Ë*W»úU¯Šu¬>¼R˜Ì ´ÿŽÏPj[똚·òM3s¥«¸ì�“’!¯ze©úú×’ v°ê¬iø»Xˆ:ö±õŒJ˜([Y¢îÓ¨ýDê?•*ÐÎô³ mTG;UÓvñ?_„èj·ÚZ×¾¶d�-¨jg[ŽBÌ£é|;4à×uµ«q‘«Rå2B€}n8[ÉéRŒ½n: «]Ér· –5 f5KÞYš·©è}ªF�%U…ºWI¨Å†jç[ß0Ü¿±µR˜nFÑÞv¹Ý­€{ Q¸ÁÃU0^½iÈs8ùɹˆ²”q@å*‡é)­’ð„£»N S7Ã×åð>ž’‰2ÄÞ½,x3+ÞÍ–Wÿž-TYL˜�,ôÅ8ÊjþŽ<ß#ÔøÆù…� Ó_ô9·0p‘K”#'ؤK†š†¾òd(K9ÊU¶ò•Û‘e {-|ˆ½0˜± Ôv”9gqYFÜæ3µNÅ¢�í¼K<çHÏøã3�ë è÷`ÇWI�×ûãCXbЦ‘üh?FÚb“~G¥�|iLg›æ4«´üiP—ç¶®†ÅLf3XÕÝ`54’úJÎÂù¼r^ñ  CëÒÚú È·¾ã›Ua–Q׫ýó}c`{næs±�­Ûܾ§ß‹6 ƒ¬àhq)ïÏ8œ¢=ísT;ׯö¦;ýÜ;yûÛ¢ÿw˜³;f§œ:ÕiñšIÜî7Ç9½sžw�Arç{+Dßû&ÄÃøï÷Yà¯%¸o þ=a¡þU‰€V` ª»ááCã‚TqQ]<ãßø¤;þñ�g›ä‚5ùÉîQ7–Ü.77wÑ­nvÔÄïFq¼m[oŸ3èùæ÷ЋÜ£ózà¬+¸ ƒm‡„ë|á+™ºÕ „õ¬o7]¿Ò×Á.v ‘½Úfù¶%¬öµ·]夎¬©åÞÝ¢"ç¨ëoÍñ~só�çµöûÏŸÚˆgD#Në3qÇ@üâwŒÈO~–Ï|éA‚_â/B õ“ XÿúgȾök'x­3z#Qÿÿ\¿Ú”§l'.²;ÆÀþö§¨MáˆúÛ¿øÏ¿‹ÁÿþëãÿèeŠ…X€õJÑ,µs—6JWjOqdn>µãBöbA'c¾w9Ô4ÂgWÅg|â’|ÊÇ|Ëç|Ðç ÒçcÔçׇ}Ú—}ÓB`¿GáãçUåççé§~í×~^)2öwù‡€snh€˜€|²€ËÑqwò€ª�6�sS�…!†úÈ{È�‹hø�´�#膸X�¼ˆ�Œ4r ɹ‡I%‰ƒ9ˆiˆˆ˜qÕè‘Q’Óv'#I’,'é)©‰+ P-É/9–m"“ó@“¼a“7™“nÄ“\”�Xå}¶‹þÈUY|Êã†o‡g�©ˆ É]u‚P•5‘’.5FËh_r—î Kq‘q0š_é.D˜0é ù·>fy–û�–!áxˆ1Ø–°´¸Éé8! Ð›Ov'tÙ1;ˆ—ô™ÞæFæ�œÿÕ“Ào�i†B‰ŠS˜Ä·y÷!‹i�L©gfœö0™ YcÄÿU•.’™€H‘œé ž šp!š¤Ù‘¦Ymg–š«©>­i’.U;²y´I€¶ùJ¸¹ºé’¼é›Nœ2)œÎHœóè�¶UÉiËÙŠ>ù—Úðœ‚Ù4ÓY”†Y2Ó'Ù¹”ŽÙ”æ�àÙâiWäùæiƒèÙ™æ÷™¢š7šPš²òqó)—RŸ pŸà˜Ÿ÷±ŸöПåQœ  — ¿9— *.ÃÉ'7Ù trrÈ©œ‚C¡Í)túœ(�C\ˆi�a‡�ÓÆ˜ÛÉÝy¥‡q¢ü—¢Ú´¢iТà÷¢ê£ìIîy£ð)+!¢ ;Zid‰¬i–øINúùtƒÿb¤ÿ‰Jº» ½é¤ ¥î¨ `òŒ+R¥ôà ÓG:¡ å—½÷¥�¦ŠC¬Úªeê¡ê¢iª�#Ê�%ê¦ßÉ�”Y_ãy™ Rc·™0úŒ{Ú§pâ5�:¨OÚ£†jŸˆ¤Š:¤Œ*(ŽŠ¤©î0©UQ©ËšÁ)¥ J¥U ª,(ªZJGÌéœ`z†bÊ-­êªnh¦ß «•¦¦µÊ¦· ’©«áÉ«*ê«T¬ "¬yJ¬3Úž5:šÇê.ÉúaôÙ¬?ú¬n›N7#ÆR­Â”¤¹)©J©zš©àº©٩㊫j®º¥x3G¤•?Š=EàÒWÁÿ"SåÐ.;U0³Ü0³5ëR7+S:{m<ëd>KI@K6BË:uË!G‹´ç¢´KNû´†µ2µNQµ&rµÏ�µ[«µ^ûµÉ¶Ë1¶eK¶g«~i[fk‹Š4â¶M·r !t+“v{·Õ“·$²·ËÑ·[>�«Pƒ³† *6Ë'8»¸™Ö¸çð¸�¹à0¹†S¹Éq¹Fÿ›´¶¹œÛ¹sµç"µKµ$bµÓ†µ[‘ºª»º¦¶‚!¶“»²k–h[»·;‚¢»XÀ»$2·æ½ñ„·|¢·!·¡ê·€‹4/‹?±cÏK%Ñ»"8ë5;‹¦•†½Ú˽N3• óP´à+¾ÁE¾à‚¾©¢¾º&¤[¦‹º©K¿õÛº÷ûºù«¿³ vµ› ÿëxLÀÓaÀÔ…À�¤À+¢eÆkÈk>¡ä"±EÉ‘SÒP�!‡£grBå Âî´¦4´%|Âm¾ñ Âse5à¢r<Çt 'Z&<5¿ò«aé`¿õ�‚<ÈG¦¿¥'Óȉ€ÿ‡¤U;|d i”\É¿ëŽw¢ÅLÌZÖš=òÉ›:SœœUüWü9¢Å\|m^l&šÖa<Æxñ³f²µfì h\©óplìÆrÇ 2Çt,“v,ax,.zü¾§ËÇð K~ ȃLÈV¶É�Èê§È€×È÷ñÈÉ“\É”|Éc‘É9U�ÕØÉfùÉ.ʨ3ÊæPÊipʼBÎï´Ê™ÖÊ&ðÊa<Ç=;Ë�[ËZ{˹ܛ»ì!¢ÅGÌT"Ìr\Ç¢ez’LjíN¿Z±µÎ¬aîÍ‚\Èd[ÍrØ tÚì¾lÞ|!àÎ ¼m¢Êæ„èL’êÿÜìŒ7î ÏòÜ+©\ΊØÅúÅTöû,Çý\ ´l¶,¹gL¹iŒ+Í¡ÅÛ¨Ð.ÂÐ àÐÍÑ$"ÑPCÑç`Ñy€Ñ¢ôÌ£ÌÑ)àÑ¥ÒÍ!Ò¸È%'�ÒıҌ�&J Ó1Í~3-K5ý7}79ÝCT²ÓùòÒ>„@„|mE­G�Ôg"ДëÒ'R ‰TýV�Õi¡ÕÓÁÕãÕ`-¿ð@ÖSlÖh]¶pÂÖåÖSåÈ™ÛÍòÍàl×”�Å9µÉÛ±×¢Ô×ñ×?Øž.„­6†]Ï?ÍÊAíÊŒ-Tüì¸þœ½eÌÔ¸<Ù˜Ü&–�SSý1qÌМÿ�ž ]1¢½ÌÝÇ]Ö�Úd»Ú×6ÒúöÖ ׳­Ò+�&pbXš<¼|ÂÛêàÛ ÜËBZÂý)ƒÍ:XŒxÝ~‰-„îÆÎmÔÐ�Ôÿ,+·œ6JœÝï´ÝäÒÝÂüÝÏÞp1ÞPÞ6¼µ¦¡¨=ÍúëÞ™ßù&ßv@ßÂAÛ•Œß¢ß¹ÍßM,až ü3>Ê:�਌ÛÈ�ØÊ­ØÞÜøôÜ×Ý!lJ~ÛÈ¡á›Äá¥âáÃìŽÅü\�Ìý±£�Þ×µÑëÍâ±ëâUãŒüÚÛÛÁ%×[A×8Þ:þNºíþ à !à:2GUç„^è\.Ç ÿî órÁÄ>ðè�¾�ÄH¯£Xã¬àš$+�5�²œ^ã5y=ZË­úU•žXcmiI²¤Ü%ëp%¯S¶–¶N•œq²„7q}„‚]ò:]Žé™~&Z°´ÈáÎ#ÐìÎn5t©Åt�Ïþ­'~̉œès‚n …nèÁÌЉ¾è×Öèµ é‘‰“¾H§—î ›¤éáÀéÓö~Ÿî.¡>êKQê^µî©>i«I­¾ ¯Î²>ëVRëd{ë•”ë·ëÑëÖ÷ëÅì®3ìîþîÆÈþJÊ.GHãìÏþ1#í+Mí>n–Ö®aØ~€ÚŽ4ƒÞípè ÿî5Åè|âèæî’^=”î:–.HïòþÁ)Rï²rïð@ê¬jê>�êb¡êÂê¢äê”ë²Në®cëÔ– ¸Nɺ.J¼n¾îÀÎ%ÂÞÐ@ñÅÐ�`+òÍn5#ŸSÓ¾Ü&Pí$rí+K-O/ßí2Oóëdó+‚óæ¾ó›Óó¬ðój¬öB¯~�žF&H¯ôDÀô�ïôóõÄ!õê@õ“eõ±Žõ¬ õÇõ ïõ ö/öOöoö�öjüN²rìp‘ì€gs$÷#@÷âBòàlòÏÕš)]Ù®{±í°ó1ÿíÂLø•Ôšäž¶9¯óèÎóêÿÞôìžö�&›.ùÓ–&•o&—ŸïK¿ïÞßïòïåð_ð¦�úQÖõŒðõêö+:p0Æà˜ Y-TÐpÞCoÞ¤M”f¢ xðÈmD×ÁG�DŽ PÒä”)¡¬dÙÃåKŠͤ9ÀæÍ‹Ãíä©ÎçOlA…¦#ZdÈ‘I•.eÚÔéS¨NMštSÕ*A¬ÒlåÚЫhaÅF$ë­ÑY´?ºcÛ6Ó[¸>äÎuT×.8¼y7í]È Ð߇óÈR̹óÛaÄç/ÎÓØqNÈoN¾™Õe"™ÃlîûPàw¡E;v\ÎôÏmÛʬ.Æ�Ø^ö-U{qÿ®\hÑDü“ÛïÁf x¡B†!J$|1ãFrÑý¸tjÉ”*Y®| 3¦4š5)GæÙS­:¡C‹¥Ž ê{øñ哼nõjV­\·~m(vlY³tkä<ï@ÌDJ)|BpöÚÿ¤3‹¨9‹vÚpÃg*µôC!‘Äm:•̈ø’ÑÏ¢æTT‹Q­Ys-6Ù\¢Í6ÅpÓíÇo‚ä&¸†+ÎHäXQr¹˜rzÊ騳îº,µÜ²K/Á SÌ×±öZ3;Js[lÖTöMpÕêº9é¬óÎ4øS@Ïwú�@@ tPB¹1´AD•ЯF-¬H§ 'EÂÒK? Ñ4N;ý4ÔQW,uTS…HUsÕFØpdEGo�iU)yõµHƒŽLR9G‹u:騬’ÙfØ h¥�6¼j¯µ6[t¸MÓÛ£Äzhh0úèrå¬s ,švÚ¿°Øå:èà�ÿ÷êzí½wiEI]’I ˜àg0Ýçl´7µ¨ÓÊ๠ÔÃðÚÔˆ©Q•bV-^íÕeÍ‘Öslõñc¼C’8’�C29–TÙ¢c£óèÛ¤¬ŒY€ 2×¼fiÑF[gбÍÖçô€FŠhÔÛ<餗vúi¨¥�ê�¬¾ЬïŇë})\l€Å&»ì=?[mø4ÑmEU‘߇ë¶{â\+¦‘ïŒýÞpÁÏÂUW‘‰4ÎdƇ£'%O6è—§º\óÍ»´Ùø}B�gÒ…2�ÊÔû‡ou£%í ®{  Ùé†vä°Ýí ”»­Õ©kûÚù$%°á™ÍxÈS^ÛÞÆÿ°çùbu»[õòv=ŒÅª³ÚQ­zä=™Ðp½°',”=ê|‘kåè㾘Á/sœýì:üå¯[Jq™ÿœX¹ë BŠLAÑ¥.±ˆ†,ƒ Ïý&ç¨t@Œc âÆ¬aÍ£k$FÉ>åëmoK£hι9¢Â¦øÊ¼�›âŠgæ d!ÙqÈØ@‘‹L#ÛH cÁ#/ô ¤PXƒ•ƒ°dn)»£ �Õ³þa-k£$åožxÊ'ZIŠƒ ¢ï„Ũ…f‹0ì"¿Ø¦2þªdhDÙ«ñÈ7æ$ŽˆÊ#*êšN2ïm{ìcXÈH."f�…$ä!Ù‘ÈEÿ*²‘¿|d$'YÉ \R—𤠱:ùÉ%ž²”¥De;Q©Ê)&­Š)¸"²(ˈp‘&^\.§KÅ�¬qñ%0ÇGÉ1�Ç|G2óÈL¯øš´”f¶¨YMDÂ&›Úì%7ÛèM¼P’–\ & BN虯I9Ag;×IJwÆÔðd¥<]©X"ŸÚ�˜øyºøä2qäÃá@ÕèHbó"ÄP1êÐ9B´?ÎŒÈD{ÊˆŠšé¢æ°&6³¹ÍGBÒIßi8K:ΕlR‡+½HKe*’&¾U®¨£i+éùJ{Æò³¼ê>mÙÏùõŒ7ܦG•j¦æe£x*[ñU>F”ÿªìž -zÑ®jt£`íæXC Nlˆ“d(áZÿÅRõ�R®q�kkÃUW›Þ§yÕé^óIK¿ê¬‡`”�`m(ÐÀÔ�fBµØÆžÖ9�ìT¡ñÌÊÆpšÔ̬�ÛѰ‚"%iL:Òö‹Iʵˆ[ßÊZצw>&a]¹æ9O®8�¡¢á�®%ôFÅ·»$lG KÜ‹ 1yyÉu�jÇ•â@ÁʼŒTÁ2Y>áj±ï­"¬4kùb·³�“ägéA£Õ,-¼3íEDd^™æW½+† {[øn%ÃÖS}Ïsß ¨ø)û hùŠÔÚ@À‡!°K d&xÁÌÿmæsoë1¬f¶°u9ãàzT¬&+ˆË â´–““+=qjÓ™b²XÍOq1 ìã4`¹E5~×�­…ß4¿‡ÇD-¬A'™!£È=8òœªd0X�Í}°“yM)o”Â)¨ò"å|Ôìzv»”ô2˜¡ ÖñšØ4(Ž©Ž×|j´ùÍ7½tÓbçuà™}½ýçPyiTá&À ô  =ŸVÁ‰f²dáNù½•¾rÓ8ûQM‹´Óu±JO[f3�¹ÔyFu·U cV;e®>‹}ïœcnCeϷβG1è!ûz³ãN²°— Ù&óÒßPö<™�aqãZËÚ•6ÿˆ= êÇa[:Úv§©»Íâo»—Âñ 8’]dcµàgʺû+pw 2½ÆK�çMãCÛ›Øø6¶¾)élNúß—Fê–Ñ×eƒS;Ì)5'™Gmæ¹rüáéå¯ìpt×°aiG`ºW8¦² jØÃ�Qø®6ÝIï[†ðõ!€í¶¹ J$¢Ÿˆ4%üý@Ó‡Uò;/ËÜ£s=uç«{ç;üþ÷b¡CP_kd2rxxˆH¤Z`|ã#ðøEzF„–ŠLÕ|¢�¡gžÅEŽÖ“¾t·+àéçˆú©ðŽƒª³çêoÊ:Ò±÷°‡}ì?þ%dÎ~Ÿ¨%lý@áÿ¹ã…;RO¯w¾ïýï€/ààI_xÈ >#ЧdãyEJ¾Q”‡ŒåÕ�y͇¿µœ_�ç]ú#8p¥§ÆéSŸ ²¾$G3?Æ`v±“Ýö”A{î)¹vÅi»ô{»Á¾¼¾«»F¹;¼C¾ä[>¿ <çóÓ>ê£ëc¼Ç‹€ÈÓ¾Àà>Ôb Ë?|+ò«?ôS¿z>o�:¼{¿øƒ“ù3šúëºØË?Ú+»Û+‡´û¿Ý ÀÞû‰0@˜»$¾2ÊpÀ¾ƒ@ < ܿɸÀ Ô‚ ì@ÉûÀJ©¼ÚÁüBT:A×Sº:aº½õ‹œ:\=ÿ úCÄ¿Ù;ªÚˉìAzÀ#À¯¸;@p¾âû¯É`BåsÂæƒBèÃCþ3�ÅËÀ+Ì>|l«.ü>0ÜD'í;¿2 ½Ñc?÷«ã-¬›A¨Áìñ::Ô?GœBÜSÝÞ;Cß+Àœ¾A<ÂBô³›@Ä€@x‰ÂX¼ *”Dì3í{˜K,¯L?N¬Æ×*‰2JºÏ«uq>é)E�ºSEVT¡¬Ã‚’› �ìøÁ> BGy"4ÂEC‡ɵÉ4ØG~$ÆÀ çûò2»G,‘j„¼¾ Œ€gÔÂgˆ ¡FkœÈõÂÆÃÑFÿP4Žn¼o|AÐG6#G9lÅs„Å„± vlÇ[üÃxÂ]DBLBC¼‰ÓãÇ~„À|ˆ€üŽÈØÁƒLH \ÈH¾½sHˆ<‰¤H¥Œ “ÈFŒ\š�ì�ŽdÃ�L7ùh½O´?—(ÉTG”<�v´E ÄE@œG¬Ç_®É¨I›DÌÉ�|œ“€ DÈ6PÈ $Ê0JȈȥüK¦´HÊŒd18LÄŒÊÅ�žÊ�8¤Á‘4ÇWìÊœ‘þS‹°\I”Ç—,³Ü#{$;µ¤I¼kK4ÈIÕ¡ˆÈž,ÈŸ¼Ë \H½tHñKÀÌM¦hÊ‹ÄHÄLLþðÆÿºiÌzA/šZ%ä”"¬ä:’¬L;,;̜şØÌ±dÉßûLzÍ´Ôµµ<Ͷ\Íœ”�FðIJ²K¼|¼Ú´ÄJ¹M¤ÔMø„¢pJmüÍÃTLÅ`LÚqÌ<;Îä\¥å|½­tÎt¼ÌèLÉìàLå¸Î‹àŘ¼G%ìΩCMðüGñüò4Oz@ÏÙÌK¢´M÷ü‰¤ŒÏÜ”¢Bš“Â\‰×!ç#�q‡è,žYŠË!?û¨ ­Óºu²!¦{�²üL4 Š8üDXy §ù‹©Òȉºh(…‹—ø»#ñ¥ú3Ä: ¯‰(��È—OS1ÇkÉš(8S4µb ÑÿŸxLÕ<%$ÅHMÒFiQÇxÑ�Q¥¨QÎÛÑ=ºíQþúQ§ ÒU°!ņ"ŲÓ%%žÆpRG€Òv�R— Ò„°R &´ØR�ôÒpS1 S2µ–¥@Ó4•–5=7}ÓŒSs˜Sm¬Ó¦aÑÁsQ�N>M ?-:@ ÔAm�B= mÉ@Ä�EmÔBÒ[„HmÒ‹xÒ(}‹)õ»*]£+ʼn,mPýQ%ÕR=ÕuHUU�5…@yUX?Y5ã°U,!@$] ôúU^)Ì¥ÖrñQc=Td%Âe•L#í:H] &}Œi­ÔjÍ„kå€l­†mµ‰ÿ¥:‹ U/W1]¢�ýA%†(Y“e×v…ÓA8Q¥Ñ¹m”zÅ�{­ÊY‰Ë ~­¡ŒBUCmDµˆa+ØUt½#u‰„UŒ…�Ô†µTLíMýNÕ OÅXÊÐØòàØ0õØtØ–�Y“=Y«LÙj|×–�W(xÙ‡‰Ù\˜Ùp̳›Mšœ5Ž�íÙ#ùY,ZÚó f=ÚHÚsXÚL±j½TkÍTlÝTmíTâB‹Œ×�E”RÝZ�õZ&¢° Û@Y²}8³ —µÓµ�Y·½–|Å«ÀÙ§ÔY¡´Û„À[½å[µð[ƒuTg�WhUXI-\8Üÿ§}‰>LˆŠ€×œ � �|I æÝ®Åܤh�Í [Ïý\T ]0SÛÀ`ÛÓµ–Ô€Õ•ÛÖ¥Û�J€=VZEí["½ÝfEÚg�V†5\‡E\ˆí’áý€â=Þ›X Ð¹šæM�çý™Ì=ŠéÛšµÞ‰ÄÞÑ}ÖÒ­×î]‡ï ßr™Ûƒ(_ó-VôÕÅDUVöeT÷\Á%\JuÚÄíŽüÝ_¯ÿà.�‰.ÙêU`5c`´ÕÞ‡àÞ<|¥ËQݪ`]m\ ^ÈóØôÝÛõ­Ýö-ÚƒmÅîÝ~XhIaÇÅÒd´‰Ö™nÞÖŸþˆîܱÅaÿÔáLJ[ÒÝ^Óýá >Š!ß"ß#vÝ$Ž€%Ú�Òþ[„�_Þ•Vú5áûEáá]¹ OþõbÚùßx `ç½\Ž^ÍU"ÎEãVãMdã“rc†c–cš‰:¦`ZÝFòÝã>ÎÛ?î`¢5?&d¥µâ¦Åbü]dFväþâk cæc5)c‘ÕdνaO–++¡`æô–ð ÏX ²x¤Ó#ÿ\Y̲¦CB—gŒ½¯Ë_Îù ±ë�©%OlæMBÊ ØH¾Í�<Þ}È]\GŸÐ¡€h™—¶h 6õ‰¬Yf€N¥ú¸ã3xæhnˆi&�©Ž‘&ˆ’Þ»“ê”–ç¥ç–î™{†é—�é}®é›Îi¶¾Æ©pfì9h@éjn£k¶ê(JΈ–h¥–<¦vê—€j¯(çÅ8g1i¬6vöwx¾e°Z±vil£1ÊgA™išîç¶îl¢if‚öi(êÝeÁ¡¦ÝŸÈæÂD—¾öŒ-l—ì† lÅ0ìð@l‘Vl’fl“vlÿ”ŽF˜l² Ë#”m)îðlæNÐæé‚ŽëŸFh¯®kb¸kµPmŒdmŠÖ¾×Þqì�.ìŽFg¼¶È¬v€­.€®.màîôPîã>�ä.îæ¾o¡áÍ *ÃÏs+»V0ïŠ8Áã¤C—À{ÆïîÃðžíñV dc„Š«ÎíÅnìÇþjà#Ê–ïùΆú¶lüqù éýNšþÎÁðëðL$pr1p×@ðRp¹ÏñWÚ>‡Ÿpl¨ðô^ïöŽç ?�/îñ4Qnò«Lþ¶0ÿfñaò¯àí¾“÷îÏqßñÿñ§puÖmÿ­æm®öm¯nîÊVòñ1‚r;LŸrX©r¿ò2džá#>p./ ÕÜR0sŒŽêÅ sD3Go4Wo5go6wo•nÐ7�o9Ÿo:£;õ¦Ðo=� >+?t¡t�ô/ôcýGDOôy‘mpšÀò3¿ðÞÎp7Gr8÷pOorûudÿ!^)uØ8õ¡rVÏWg�õ¯!‹D¿�ZÏhñîGŠHé!¯ô"‡ì#W‹$·ì%ÿôåNvw·Yh¯¥ùÌ2ªõ”ŒÈ 3\5Ùê þБыgÇÕ¶P”/qš]Hxò+š‡/ÓßhwÿxoûhY,‡Ïxqmèx�w�÷,‘÷:¡÷†Ð{‡\|ï0pØwpëw<ù €�o ‚g ƒß „WøÚÖ²†xk‘‰‰Ë©ø‹ß(�z� y¦¢‘1Ñ5“GÃRHy«€ÃÓw¦ã÷z’ù™w¾‚Ƀ›w‡œƒ�ß……¤Ÿßø �ø>�£ïŒOz�mz»G�§w³³=ˆ©Gù»w¬Ïw¼0Ãü�´®WÁ€‡ì�÷Ò‚ß‹ƒoš„Gûžgø™Èxˆç†¡ßÍë8úlºšº¿{З¼‡W¾—m¿?*ÀÏúÁgºÂŸ8¼ú çcÛ°û²?û´o£µ¿üÌ_–ÿ©Ø–%ßäÐþ7ý½7ˆ¾¯ «o„¶ayÂ^Ã}¯ˆý˜�}ÆÇyÇ×yÈçùs¨¹Üo{ÌÇÞO“ßç\á/ùÈû£ù.›9ýŽVþ%D”üµ™Àóo& óP‡Æß›‰üȈjÕˆ$Æè ¸„ërkØĈ¨hÆŒÙ6rì¸qÈ�G’,iò$Ê”*W²léò%̘2gÆ €ΜvŽéæ'ÐRBçØèh£J—‚kêôÔ¨@�b©jUÖ¬ç¶rÍåõkž°bÑUgÖÚMj§þÜåö­À‚*dè¥Å‹1zì›-¤Hš‚.lø0âÄ0mÿæÔÉÓ'[¡¥ˆÎ3Št)S§M£JekõjV¬\»~õ*vlÙ³iײ} w`ÁƒŒŠ[¸®!·‡'óVÜË×oGÀ /nü8òä/7¦±ÓAÏ1lÃH¦lù(f¥š7sþ0ýsUhâÇ�ÞZÚôé÷ãuÛ�wÞ™öUy^)w„4çµÛ~ ç‡ƒºâŒëÙ/Ý¥ÙMÍ¡´Ñ6ìëC÷}ùìfßþ<ôÊåNâS�w#ûŸºð«ßi|BÈ{»^~7xô髯œEhFñ>ñËßýõq?ù÷+ÿ›lý‚‹Ãz¢”)r¡ƒvë; ÍÔ>›¼/ ò›_ýèw?"ä�ûã#ü®Š¨=L Cè©  �Œ_%ˆ?ýeƒÌÎÿ8Èž’K„6¼¡ŽHh¦°¬àù§A\ÉpXÄ!“È¾Š¸~v‰©^ºò—Á|&(µ!Íi⦚ּ¦¡©ÍmN“š×´æ6Ã)N•tSšßç8Ó©Îu²³�î|'<ã)ÏyÒ³žö¼'>ó©Ï}ò³Ÿþü'@*Ð�´ =(BªÐ…2´¡}(D#*щR´¢½(F3ªÑ�r´£ý(HC*Ò‘’´¤&=)JSªÒ•²´¥.})Lc*Ó™Ò´¦6½)NsªÓ�ò´§>ý)Pƒ*Ô¡µ¨F=*R“ªÔ¥2µ©NM Œ ÷T‹FumS(Œ¡Õ­º¡«^Õ¨¼êÕ�µ¬f%+Œ® ϬnU«bÿí*XÕôV7œµ®+H«ZÝÉÖ¶Î5®˜«]ϊ׼²s¯\}«_S ØÅÖ¬ƒ%¬: ëVÄÆu±‹õf3[×ÇBvœ’D_+kÙdV³‚åMg×i‘²úõ9Ï-lI[Zlµ©MçjÉÚZ×: ¶£�­.ÄÙÛj3·+Ø­k}kYà ×¶Ä §q‘ûZå*–¹Ýîsƒݸò¶·Ô•mi/TÊ6dºa-wyû]ðfV¼¥,/$aÔ˜£¾öínò«ßt ¡¿þ­€ìƒØ*Û80b`„]øBL¾Í±ï}y«ßýË¿ÿ 0€ \àªx Vp^œ47ÂõÅïÿ„ÓÀ_ ÃÖ° ŒàÀ8Ä"v‰?WªóXÅf±‹ëãsxƆ©±EnŒcÞÌ—b=NñŠ-ä!ËØÃ4Fr”ܲënÇO¦°¥XÜbS¹ÈÛ@Ÿ`°œe-GÌ"^mr³¾ æJ‰ùv¾³@ªAàwÍ4Q3›Û\¯ž¡Ð†vrŠÁƒ…%1©À5TyS×]�Ê׿Žë\ì »Ø°Ö¯¬—ÿDëG;ÚüÉË´)ËkkÛÁ¯Ùvî¶„îØ·ÓÑCÃÝèsÔ*cÚW®Å‘‘L/'ì¶Cwa+çü{¾x8Äã}œy×»Ðlºw¾AÍ•~WËZ·ÍÀ›¶¶ù<á£]xÞˆG\âÅ¡x}í�ŒFÙÇ™ž>¾��K¤à8)¹zO¾p•7†åwùËs[qccü„úÞ¸·pž'�¯ƒçñ9 €ž\¡Ëy:7:Ò‰ssȼ'4·ŠÍ£þo�‡KWVåÈ›spà*|áÓ ]Œî¢°_ù¼ô޹ÅÙÐô>}+7_;«¨þv`}î³­{×Ù‚w½ó=1c/;¾ã§hÿÊ4‰uûW_®^8›¶À�Êï:°¾å•?²ÒÏô™k<œ/ë&Wu�ˆ^&&»«M?[ÔÛ]ò«oýÑ_{¿/ýâ´‡Âæ‰ÒyÉe ô¼‡»ïM\úߟ-©7¾ÔXÏ×+ßÒ±þìÍ^ûÏÜ~4¹¯¾Û¯Ïx›ü~ûËíþT­hÕ‡ù{/ÿŸ�æÉOôÍÃôI¶Œƒî…öÕ_ðq_i%‰þYÿ=‹øéù`K\^à ^ R$àÊš8 § _fÈVE¾Ébàÿi KlÕÁÁV´D £Eƒî  9…¸ØíÌ—ý-V‰ŸøS-�‚.!·�ÿéÄF!}ìT¡¾D]• ²› Þàäàê`6Å.D6Ç*V! !>,!ΊVMJ!}XáºD*ßZ[Þ †á‚C®Ã6F¦À¡¡6áÖ!N!V!ž•jU Ž–~á’„¡b�–á!æD".â"¡#‚$:¡$Æ%Vâ%šU&BáøÇ5•“6€b4 ¢mÌ0ã= #1Úƒ1£> eÅ®Y�3>ã*¶"é|5Vc,âá1f£6nã¾ÞVÝ¢oäb9ñ¢/.D0 #1ã6&#§�#0âZ3>£3F£Îa5ZÿãVâ6î£6vcù�ã^ˆc7é2Uˆ;ÎA:ª£6&ä=°ƒC>äAÂã¤É£3â*\$F’ƒFnä=RcUÐðð£HÚC]¡É?® .Z“.d*¤;2ä62äCB¤;J$ŸQ¤X$F^äFrdG~dþ„äH¥1š¤òdFä4±d&¹ä9ÂäB&äL:$l1ãDR¤NîdOjdG~P€PåHåë!%F(¥41%"9%:¦cLJåTVå Å£„§¶ém¦ÚÝ&Fä¦nòfoºCug& §pK¿%gŠ-§s>gtBçtbdu¶Ãun¥vn'«t'1|g6†g>Œg;•§yÚæà¦9éæn’K{º'p çpÒg­Øç„ág~ŠÁ~òg&Pgu¢E¦d'¶h�v'‚£‚2ha9(ˆ!zbƒzž{öæ{jhhph¡x¨~�h~ލôçEþ'ŠbÿŠŠº ‹ê‰�éeÆ(¼Í�ÖèyFhzN(…î¨ofh|nè¬ô·('†¨ˆŽ(’¢‚’ºCŠè“FéˆN©xV©<]©‚Ù¨–â(—®'¹ô$Zôh˜þè˜ÖJ™Þ癆¨‘®i›¾éŠ>© Èé~Òé‚Úi<ᩌnÎ�J¨6èæxaçþf|Èç ꬘©¢é¢–¨ž¨›2)œB)AȪ\©>ÜêeÞª>$™=Áˆ Z¦jΦni§žÓ§nd †ê¨Ši· ·Èçr6ɪš¨u¾j{4iŸô[AèI…Ø*®ò¥®òêlòƯZ°ΰòi±~Óx]h¨¶Ã²j³ʳÀg´–Ç´¶jµ:ª«hë¬æI·Ž¨®æê­Š+=ùªö¹°e©äh5µk{¾k¼fE©:ë¬ÈçC“d,£ºjŠò¢¿·n‡·êÁîjElSØøŒÌU¹ž�_�«Ã5ªRåÑÜPËáà³ å—ÂJ ‡>´«_iÇꌚu£ieÅZCêÖoÿÀ1r%AJ‡°Rý5(¯Ò€)8ÃùWrÖD°;!l:ÑÅÓžÎÇJŠ c!�E6Ÿî™ eIéÔËvt3R�j|6ÛYà€6´¢EiMkƒ®¶#µ«em«ÊªÑ³Æv¶"ÝIËbÒ“î¶·;p…ÛW"÷1iÞM7›Â2—§>‚î;ƒ*TêǺœDjvm²Ý�X eëIxÿ Ù¹•·*çýlzÕVöº¾a•ï|[”ѳ¢õ»ÛøèlØÚÖ‘¾µ¤q•ëíÊRª x¯1%î�Ü[@ÊÕéƒûÜEW(Ó%jug‡T @Y)ȇŠc‡·Äï*//SŒƒ‡…ÿ´mì†{™_ÖÒÏÆÄ/3çyÛ»äv·h»ë‘ùV`q.y& ^à‚«Ǫ¹nЃpAéJ36Ëb|,46Íé/÷DG3TËÌ“£9TjÞ%›Ý 8ǹ�Lƒ¬gÍ*7Ù-<÷ȵ®Q¶|øú×Ù™§›Îd@Ÿ Hw},1æCɦOfp”eXv†ÆJ“®4¥/]a-_81œî´´•jk‰º˜-èxMŒUq¬9Ŭ6�«_-¿XÏZÖµVÑ­£ë]ÛÄ=¿vm„­"bëÅØC@v‘Å¡ìe7Û٠좓ÛèåÆÊG‘Nh\´Méyxüã˜>¡¦Ã Oó¤Ü¼ÿ:ƒÊWþTtãx#¦^wšÛýîóÆ{Þôï�žûÜÖ6Ãu¿ïÁk�Ü×Á¾¤›H;¢sè(„ ÷-pŽÅ‡Cœ!ЖˆÉ±àhLùhAØÇqñq�w;Ó[F ÉK>îOwfc+_9 æN÷t‹÷3䥹ªáÍjœÓ{ç³öùÏõt~½èÛ8:>’.Æ¥‡µéO_Ô\ªgñ›¸:¢³‘­wýR_¯’¤ÅÎñ²{<ä˜Lû]Ö¾u”*î*§{Ý_®‘˜ã�Ýq©JÍÑëf¿¿ð²|Ï�>/¡÷ñŠgü OQÈwêõI¶êí²ì~`ž%š—I¢=H‘s¢­)<2ØÿƒNL�}#UÄH¿rî-ëͦCÞø¸Ž²“öf‡ øÏ?F�¶“H—’¹qÁf¤&Y˜€ôã Ø€W³1<†ˆ&á±x�È¥R2&V’~H ï‚"x $X‚LÂ#cò vóf¾dO÷´I²7w3•}Û÷»~ñ!~ã—{ b~è§~fÁ~xà~_ò×JôçöWù§ÁÇfÿ· xU˜b`b€’€ 8; è€�l%�‡B�‰q�8qˆ Ø ˜~"8‚%H‚')(+Øj-hT/h1H3¨y5Ø}«ô}L~þ²ƒ<>ˆ*ÿ¸~ìG„e„7I8KèMˆûwtý'…X€¸$€XÁfY˜!È…Œ°€_è h-x˜!ˆ†+��Û°�Ò�o‡!8‡t( (Ø!*h3,H .ø‚ˆW7ˆÚà}gƒƒŸ¡ƒŠH«V!?H �xo’ÈK”8–x‰�‰C±‰lЉ÷‰�0…Ux%ÂaЧ˜©È…¬ø…¾(±H³Èµˆ†¸¨‹ÐÁ‹è‹ïŒ·P‡Ÿq‡q‘‡ò¶‡�Շ˘}áŒÐ8ÒÔ¨ˆ×ˆÙi±Yó�ñçqââ(ä(W£,Ù’P˜p •ÔŽ"’ñ˜%ûÿƒ+‰Ñоp�bà#dø ©E?P”F‰S!J¹”›e%�ð”P & ‰ IZ¿)‘âÒdËcƒt�‡˜ƒ‰X�ÖÈwéˆ@ø%’—$’W’'9ަ•+Ù’,ù’þŠT8ŠVXŠX�h�“u¤;wÁ“> ”²x(C9;Fy”H¹”L97N •O)•Âh‡Ä¨ˆ¥rŒ¤¥•1ÈŒG‘«$%ˆ¸Gf¹‘a‘7^A`âs¡’�Éry’)w‰—@ñkêÈŽ~éŽWx^‚‰™PœÆ™“Ó€ç(>‚(X‘Zi!0�Y”ÌsN’©”MÙ –y™òq@1ŒÐQ��ÿY!Ÿix÷@w¢él¤™H¦I–¨¹�6£š`Áš]áš› "›Â™!µ)ŽYU¹Ù’»ék½É—4ù޳�Æyœ…É?-¢œ«ÄœóáœW�h!�ÓY�«t�r��À±��&Þùà;8ž,FQƇž\Ù• ð=„Èžrš´RŒó"Ÿ&@Ÿy`ŸÌ�Ÿ¨ Ÿ &ýy‰ÿIÊ’Š*“¢Ø¤x6yŠ ZœÈ™+šHJê ú˜šHê¡U¢"êqß©™á‰‡ÆHžaµ¢2Ø¢Îâ•Ü÷Œ±HR’‘WA|¦‚£:Ê£iá£@úYBº!&"zÿy¤Z�¤Kÿ:“¿i~Ù…Sš Uú  ¸œ€Òœ‡òœ_�¹2�¦î1¦”©�Ûy¦óîe–äÀ�žé�w¡k,ÚŒý£všcN”§e|Z*~Š3­y÷Ùs±ù– Š%ÉX`W¤ŠÊ¨Q¸Žú¨ ©ü2©•WZ4šú œ*QžÚ" *ª›Aª3cª–‰ªªÚUÒ«á0Zojž³:šµú•1Ч¢§ƒAx7Š–« ¬õ)¬=J¬ùi¬ûI›¢¬ˆšUÍú¼ù¬¾é¤å7­ÃY­Sz­;y©š©º©Ú©ú©º<Öy�dJfÚ�hú«*ìê®* ¯qJ«5¡JmÇÍÿÕ†íc3 ªÀe7o‚"ˆ¬kᨛ³áàK‚ÉXa©¥Þ „Râ#—”¯Þg·ë:¥Ò0Bg†`×Cñ'¤{»ä�5„¹††.Z6}‚&j7yó³V’Zïg?û³Æ§kƒ ˆ6A³ŒÖ7»‹Zk*;k=k3?‡BëD›FGK I+TKÛ­¼Ä*`µ"µeKµ…aµ#Ž�k´áÀµ†çµ`«KÁcëeK¼„¶ñ#tl;§ à¶Qdqk3y“7uk·“ˆ·yû�{›k}+³Û'®Ûƒ�…[*‡[‰;/‹´aâ¸M ¹H�J;zLûU˜ÿ›!š»œkBäÐ*ºÖ!ºÙKº¦«¶÷€º¯±ºRк­ðºîv¶é—¶±zµ{2 �»Ys»û>½›*¿ ¼»¤ÃK¼æÉ·~‹$´—‹Ò¼o¹†»�<›W>Û‹ÖË£k´Û{ŠEÊpÂ%áËãÛîÕ¹ûÐgvqµ‘µî[ ¹’kò£ôk¿ø»û;»†÷¿!ÀpëVÉ»¬*¢ÀÞ(¼X}Å{Ç+¯œº:¡«ï‰\*q¶Á.ÕÁùÁCÛ¾",¹iÁhœÆ%œ%(<Û!Ý¿#m»%½‹´ß»ý:±óßÀÜnà3]ܱ5Ø…ÍÝFÏ- B-ÝîØí¨Ï‘ÍÏNº¥ÂÝaáÝ#nzœÝãMÞb-Ú¤­âMÌU~Ú[[æðûâªkÖ<ÜÑ5¾Öm½o]ŠäD>îîäßàw!àENà~`-ÿ–f#>$Q¬�§"4;Çä8Pé–nŽRB˜B´<- õ³PÉKæ\`’7Ì–×k¿¸Ä«„±^š+Çògás6¦ÍæY})b°�î‘Î7Çd–~雘éâ³éMÚéŸþ†¡¾K�:œ¦¾Ê¨Îª.æXQ®.0ÇR6hSë¨�Ú¹NjXÀëµäë+ÛÁî×ÄþTÆž™Ÿ‘ìm´ìC'§‘Qí·zí7¨)éÃrgÆîá.˜Ž š~)œ¾ÜT‘î¸îãÐî‚ùîõïkÿ1ï¬^÷ëú ï´ÎâF{ëvñ﬽ë&Ñë­óëéwðîÅ~tÇ>OCßoNü’휥ñnÒíóíªæˆpæ^Ìè®bÂòyФï<*ï½êõÞêZñê-’ï8¶ï<Ë>o@ßÞoÏ¥ÔŒôéì ?<òôkV7õJï]/GØŽñ "Ïí/éÿõÓ‰x%Ÿ'¾)oöÈ�öf©kóm?óoOï{*÷@÷Å£óCÀïmîæ?ϺðC?ðE_ðÀ~ÃOMò ìgh‹�ïøQõ«tõ”ŸõXqù…Áõ¹âõªž_î&ÿî(ï餦�êñ˜ú¦²–ÕÐ&Ùú5óuŸów¿ójþ›zïïºðø5Nø› $XÐà@2 N`ØPÂCˆÝ$N´WÑâ ŒläxÐãG�!EŽ$9°ÃÉl)·­dɲÎË41e¢¢Y“ÜÍ›ûÊíäiÑçÏ|A…PÔè¤I[.ÒTæ&¨í¤âWÇUYµ6âÚµÚW°ÞÄŽ%+ÖÝY´8í%F lµ±þäF ÛÊîTœ< ìõöÓ§>}ÚfÙt]Ĥ¶«ÚXÜÚpo¿údÇ.ÐeÂ+±l¾ÈÆçš¨ªâWº-1¿ï bͺäGŽ:„ø0ÃÿmÜ~3jŒàõoàÁŸì�2ÛÒ–/ëÈœΜҤOO ThP¢F‹&UŠ|¥á§Qñ’k|‡Ö­]¹J†[Ï{øhÓÞ„Üömܹuﶃ®—ou{,³m KŒ®Å« 2ö(³ 3ÁXÚ ‹Î>³!´Ñn*mœÓ\­µA„#¨·vè6Ûp» DÖL\�Dc”QDâŒón%嘋ɹç Ûg:ê¬è:ì Òn;@§b‚j“Ũ² +ôLPo=ÉÊò¾øäsG-¶Ü K,¹üAÌ®VÆ#Ç?úªNÀµ)¬©“JÁÇÖjТÊ:#p A«)Cr6ì°º[›ÿ‘DQ”@ÅYtÆ+µ4¤Uº1Gy„Žœ�”FÈ!‰ÌN»$•¼<'Åãï¦ò¨DïÊFØÓ’Ë÷¼ü’¾0ï#3¿ÐT“M7SƒsÀ9;0A”ÌA?#ÔŒ³Ë,ÄPÒLkËCí­Q!Í€ÅA&ííRt-E`]v3=nS˜:unzëuÔŸîÑw_"ó9õ¨$—d5�'£„uÊóª¤ÕV÷pÕÌpìÓ›2Ïܯ¿�öjÀc 4pÙ;›ÕóY> äOj=”&B ÝÑnedÔDGÅ%×ÜØÒÕ9FvÛEISï8eŽÇzíÕ¯}ù5ÕÈ#S¸I‚]•Róª´ÿòJ†ÉÂ�‡y�X̯ð3S¿4_½‰XŽ‹3Ù:™uÌÙ· …PÎi)¬veѰÕP[Ô`ÑÛØÀ­ÍfIM¤tgÄ_cÆ ”p31Ä`ÎÊkÚçSž�мØ7õùû7ÆCdžÒKçãtÔŸ|OóZ¯r2‹´,fÂÍb±ývl8®nð“ åLa9Ìíä~ùó `>÷ÿý€< ¨ "Ð ´iç@Û}/‚¤`h,ˆÁái°xÖë A1¸�¥„Ó³ ±·½îiхⓈ_fhC<æQF8Ôá6Þ'¹ÊôË‹7G*#ò/FƱÑR¢±îuÕÒìh9LŠMh“Æ4&¶x„R”ò e)¿qJTJðZ"ãK<øA©Ì1 e-ÙS¦2¹‘päÞ&í‚§ÆÐ"wÔc1�9>¶ïqXàaL|Äú ‘ûs�Œ 4–ÿ<2!‘„â$+‰¼LFΗ­è¤'Ûô+ˆr”¥$%*SÉŲh“ el^,É£ ZÚR2¸”‹.y™ƒq“ŽÝ°ãÒŽyP„$™tsäéLAòl†Äß4�(¢k¾«%òä¦c¦*úÅ’Ìd@dÎsRL.ê %;ÛéÎo¨RKò¤',¡4<å“–·ä§?UØ=“:&˜u$ßPzÔƒ.9ŒßçDûRH‰¬æ"¯‰Ž:G’è éOFêÐ’ú²œžÔKãáRyÀ4¦ð$‹<_é'ìž³Ô)OqéÓµ1C%h¾ôeT¤6�J] SéÔABUšS¥fˆ¬yUGj³ÿ£åñ&€¾ÊÌpêµ*(-+KѪÖÓœf¦Ú|k\qŠÏºî“Ÿ`mkÿ©Yqði-’`mKCÂ6³M…f!£ZQÆ^T8ŪdµÚM®RÒ²à̬XOjÎΪó³0 m[FûÈÒP®9Mí[øé�Öºö§½t®P:Û{ö¶ë½áºB×GÃB±]E‰øª:ÖªŒ,î#'k•ÊVç²áÔdyÃÙ²˜uºî¬.1®«�ìªn»¨Í§]Ë^Ö¾ÖÀU‘­_Ó[[ö†8]¹]f3Óð̧FSªªIÚ=ò;#âFÖ¿Çõh€S3àænr¬ŸL°g] Úê>8!>£,£ÓXX.ÿ6€†u¬ ûDiþq•/Eâ>ôÄUìŠ+Òb7Æ�ݨq¯Uãä~ó’9æäsÉÚcéþ˜ºAŽ'i_iZ³q·ÂªÅ%“�ÜfóÂ�¨R¦-•­|èõæH ýè¥"4Z-øÂ¢w_$"QªRE¢·D £&µ'L}j<1@Õ«F/`ô�å(>h*½DH ¶Š’G<á‰Õ´ä`{1nk̆6EF$[Ù{ò 4œýl&ûЇ§>õ9¬}m¿ÔCÛAt·@¢E7úÑŽŽ4í(]i—^ÓÏд¾8ÝO' Ôdf ©KMmO¤zÕªn5``ë:ÌÚ.µÞÇÿ­sÊ]óº¾.K°…=lÆ(ÈØ¥A¶²“Íl‹<Ú–6åðí‰kcû'Ú®·½}hpIÜã.÷„Î=iKjÝìöð¦ßÍ‘xsgÞü]нGýq}ï»ß¯^ ÀþZ×ÚàË®�£ð…Wé×÷Ä#�£âÇxE4îìhwüã!·v¶·½‘“#:åÚY9¤ +é—Ç:3÷‹ì~÷›ã<çHÙy#Eís +hßüö°«ÿk�·‚àK÷�Xœ¨[-“§<Õ«qŠVÏüÄ7ñÎgüó;¾É~Ò›üô!N}QV��–oæå·�;NèþÚ×Þö¸_@ß±¹ŸKáãÀþà‰_t€K<«S¾Ub¾xH8^3¶¬ˆ>é; ê“8ë; ‹Ã¾¸ù‰¯ƒЛ6q;;ß?ãܨ ,At5W›\Á‰˜Jà þ‹AàK¢E‹?7°½H•:a² Ô’ï;5>1Avpµ}Ñ’[9¾²¶Æ€ \cº²`¨Ë:̃(Š,ÌÂ{É:"ë!B"¼@&K"à8\/¼ 04AŒÿdÁ솼‰ ŒA<tÑ¥İ,‹4µ:\‡!dCÀ8B$Ô%|À< ‡'l<²`$S@¨Â+ÌB,܉ëBnøÂ5$Á L2ü 3 ¯?$‹@ô„A,Ä4B}IDEÄaÁ¼Y‹G\¾H” $ƒ¾è»DLÔDcãDOTÅPL’Q|�R4ÅÀBEU¬Œ6Ô‡Vœ‡WœCr˜EZôŸŒ?=ì ><ü:$; ¬Ca\E}@DcÜ’ETÆFlÆ|Æ·ˆÆ*±ÄÂÄL@xHˆÄFäGvpQôŸÿ2<p¼-qÇr<ÇtŒE:dÇZ4Š[¬�ü›ÇĨG�»Ç�ËÇ ÜGr<ÄbüG€DFäs'd«±�D�’FÊ£F-tHˆ|H‰¤Š´HnÄHRÔÈ�¬ŽTÅ�lÅ�¼YœÅ’,Š“„ˆ”ÔEzôC{D|D}t"$Æ{°É›LF&\FGäI±ðÉ|Êl†Œ„{)J£ìÂlüD¥äŽn,‰o|ÊcÚ8Ìd‡XLÆ<ˆðÈ|¶yÐ’8„XPÌT‡YDtHq!B6MÑœ †0º:‘§iHMË„™‹‰p¶ÌÔÌÔ•Æ\L;¸MÜü>H‹`ã«c�WÔÿö˜¹¬Ã“Ž3ÜÄM!â˜Ù�Á$LéÃDL5TÌÚṫ€L_�LÊlAËŒÍÍìÌ$ùLÍÑ$Í:9MmJÍiXÍÖô†×„ñœM/ÉÎä¼MÝtFÞ6ß„8àŒCá” âœ8ãì¸ü´‘ˆÎélPo €Ã¤�ÄÌNí”îôβ¨ÌËÌÌñôLHMôdÒœ€õ<ÔTMËŒÏù¬Oþ£ÍÚLÐý,Èþô�ÿ¶mÁ}‹5¶•¶]P§tP!mÊ�Ðì|ÌÈt¶ÉÌPðÜPÌìÐòüÐó Ñ-ÑÄ8Ñ÷LQ¶ZQµOùÀÏüŒÑ©£QçøMÉÎ($Ðu+Nÿ9NR8­”ê”Ðë¤P$íN%ýΉÏ.­CÎôPQô¬R+¥ ,…Ï-•ØìSàsÑÆ„Q²ÛM±èÍ2…8ASƒ‹Ý�Àˆ7�SPŽ95ÒÚ¼S % eÑ üÓ( Ô)Tõ,Qæ9T-…BùTTúdÔßsTÆ„Ô�“To ÔаºKÐ4ÕÑ5�¸Ný¶ Ug�‘Q­Ó#ÝÎ$…†%EÕ&UUdUî0Ï Q�ÕõœÕöDQX `]Ô'­C´@ 0µ’»6tåO±à´XŒbÅÑcÕÔu7G[ÖO}V� ‰hMEì,UjÅSkÕS‰àÓuõSòìV)ýÖ5Œÿ�×å¡Õs‹tÍÕ‡•Áv¥‹w�Wk›W­Wç¸W©�IvÈQ~Å4Å€mÖ�­Ù‘(ØÊ°Ó„=Õ±HU]�AnM o%ApµX:‘UC-×,ÝXoèXmmѳp×½M’=“Õ{= |5KtÙ¯˜¹˜�Ùœ±Y²½YµNƒÕY ­ÖkíÙlýYþãÌ¡­ p5:£U–q¥ qÏÕ¼Ú²PWÙ Â��€‘Õ6yåXzõ†ØÄL•m–%Â=?±¿²­\ƒÀÙƒmLSÍS&ÝS' ÜUE‡¹e‡º¸»µRÐ[çà[Ëô[²ÜAÜ­‡ÃmÚÄ]\uhÜÇ5ÁÈe‘°eÊÿD[ËÞD+RiEصUضuÍ·ýØm݉%Úµ[£E]Õ ÖeZ§…Û]�Z‘�Zx5Ü’EÜ“UÜÅÕ]®UÅÞ‘ß�Ë¥Yâ-[ŽˆPˆÈNÄ�TAµÄ]Ä“3ø_W9`å°J»¶sÄB« ™b+ µ„ÝÄ]"dL&A‹xÅsäL Fü8"$ Øø႘ßìßÚ¼ßÛÈßåEBþ�Aÿàÿ`~ ž4nE^`‡öXÐý= 6A þ_ ® nÅ æLLrá^žb�0a@áÆTá `áý]ÜþUžá`9(`¸»…~ÃÿfĪØ�~Ú!.Á">ƒ#¶‡$~Ã%æàtâ'‘(–b*äžS,fL-æb›|aþ‹a¦á2¶á3Nã\c�lc¶Iæ¿8&Á9®ã;^ÁåTFe+.äÅc>Ødf‡enÁfÞàgNŠhf�iþÀjîgúMWe‡W6Gôƒ>h„6hoþ=p¶e&3ºbˆh‰þ¾ÿ^þå6« \¨»Žîè NaüdÌcú#q’#¹rìg–þg he�^ámVËL¨i›–A« ç‡8‰žh²£ jt&6qpãa†ãÅ¥¥^j˜&A‘ž’ƽ|„}fi>aVé˜Þâ™¶I›¾éÌi‡Æ0ˆîébø¾ j_æa¬»dv&æNê¥VꦮŒ§Žê½›êª¶êTvi˜è¤é¯Î´ëÚéX3ë³þé´¦†¡fà`~ãŸÅݹ¦k­&Áõm úããhÞk¾d¿ÖjÀŽålÂv)ÃîÄVÅFëÆ~l`.j·6Ævb¹žëºf‡Ìf�Íåÿ|öìϦâÐÎbW–i‚ææ²0í†8�&kž6k×NkØîaÉvÞu ìÊÎí݄ކæßžæà®æŒøèG S²3F\HïOXoö&Vç°ž^ìIÉ@)µ²:4ÍW¼ckØïb^ܤˆ�P"o·”ñ&bðÍÍóNÄôÆönoK}oä‰ï¸œosªoˆ»ïÐÌofVÁý¶†þŽÍÿöˆ?pOœ—ã×ÏGÂ�ðõvïЀï°ÌÔ¯ o˜²o»ÀoŸˆ ñÏÌ?ˆOq$G—çä·ƒïCoõ–q¯ oÉ}Íñ ßñ ïñÿq‰rþŽkG Ø€ß$?sÿÄɈ?ÌÜ~r�òŸrš¨ògóÚjÐqwâñVM"ÔïýÎ(Ü-ò÷d4/t�Qó5oó×’—ò ¯ñ ¿qù~ �ÃçôkJ %ôQö)õSOu'·6V·IöÆ<�:”¢Z7'[6\ÏôÜõ?ïõ$ùuÊvob?fTç]UOö\vfw g7'hgÀZë[Ñ\¿vlÏ(_'ØPÿv}‰p?Xc¿6s7FtO÷ªXwOj÷è³ DŽj/AqÁvk°÷ÿmÇw`ßw‹‰~7dr?öU—ˆV_o‚‡u…{ö+©B…�A†—w|øz×vîàvj¾x™‰ŒÏæ�x�Wv�yq0x�AxÊ;yþKyôpH�x‰yŠïö™oz#ï ÜÈm¿PËÆ¦š@F@2$‹" ÂÝ$rqq§{c"‘¨¿leþ ªo쫟@­×)®ÿ¯÷œaz²¿{2ûÛ�zµ·Éªo{‹{û|Š{è˜{Ñ©û˜Ç{ŧ!½Ï¾÷‰µOkÀW6Á¯%ÂÇ ÃÄççÅï|ôiüE 7I•8Ñyšüd«|Zºü›h·{Ø|Ï�ýóýÐg»ÑO’Ò?}èÁzÿÕÖ'׳#—}âÏÈØ¨}ÛÒ�y¢X�ñOèý(Ò’ào±á/~ì7ÛãG~ó»}îÈ}mr~è—þ¢þš3wË÷ì_ÿÝ~î'—å�æÇ¢ñWýé/ ׇ}ö߈ (hð`ÁA .hèPĈd&RŒeñâ§Œpìè‘#Ž�"½‘,iï$Ê{*W®hérà@2gÒ¬ió&Μ:wòìéó'РB‡-jô(Ò¤8a DèTÀB†F”HqâEŒ36êê•ذ(Q–49ÖÞJ–.[2  ô-ܸrçÒ­k÷.ܶOFU8•jUmW±f�µ•«×®aÅÿž-Kò,Ú´÷Ö²eŠ÷2æÌš7sîì9§ Ð¢'�.Íæ4jvªWC†,ùõ=§ŸgÓ®mû6îÏ¢G—&�:õjխϾÎmü8òäÊ—ãܺ·ïßl‚ žR2óìÚ·sïŽÔ¹ è¤O§n¥÷ôê׳oOyyêì Ënoÿ>þüžßÇ7¶¾~ 8 �Bñ'�|{T ƒ :Hà{Né¥`AZx!†ÜEˆÐ„fø!ˆ!Ò¶áA*("Š)ª8‰™¸×Š1Ê8ãO-ôâS4ê¸#�=úø#�A 9$‘Ey$’I*¹$“M:ù$”QJ9%•UZy%–Yj¹%—]zù%˜aŠ9ÿ&™ešy&šiª¹&›mºù&œqÊ9'�uÚy'žyê¹'Ÿ}úù' � :(¡…z(¢‰*º(£�:ú(¤‘J:)¥•Zz)¦™jº)§�zú)¨¡Šzæ_ ØÔÖ¨©ÒTê©–©ª*«5¡újª±Ò4+­¢Ú:®¹‚º«L½ú*i6Ř6À ì°Šbó,´Æ˜²Ì6‹(´ÑJ› ²Õºzí¢Ù>»-·�ms.ºàY îŸ¥Š‹ ¹È¢›®sØ{/»…º+n¼æÎ» x÷â›oŸ|ð»òþ‹à ñ0Ä9H<1y4X|1€»y0Ââ*‘ÐrH=õÑ6÷ÜÒLŸé´Ç0£;5ÕU›ü[‚*k�fis�íÇ_ƒ-‡Øc\ut6Úi·}.+}ûý6àpÇ�4ÙÔÕ�ÁÝx›™v{oã÷ß�ƒ=8ás¯vx⊓ɸã�÷-ùäƒ_}¹Ýj¾¹Þ^óí9èa—,챃'榟.&çª?Îzë‚¿;ì³^º·kYªãD{°<ó¦8ÿ|;ÑKOõÕ{=Ùk?–vÐðmNû¾›-¹ïö5ˆ„à¿òº+ÏüòÏC/}ôÕ[½öÛ£Ôÿý÷0ñ$þøÆµ-óõ%}þ[_{Ú´…É ~ñ“Ÿ)èW?û‘ãzâÈ_ö¸ç=õÝ€,Ÿ¸ÎgÀ˜ �= „Cæ@@0‚¤`¯wþqÐ&³%BÕ°„Û9!D¢ö¶¶Ð‚0$“8à P'7|W¡µÃõЇÙ¢6„6"BЈL¢­CÃ&†ï/$ßCX@’ÑŠÜq´"Â�9¢+r`KóC ŠD$`DâûGBš�KhB#Z©H0²‘StQݨ8>KŽt\+—G=R��}ÄÁ‰HÒ�1 ™"ÙHF† #ˆ$½CIlX’ÿuüÜÛ6‰Ç=^ï“ üã(Û€Ršò\ˆLeVÉÊÁ¼Ò-±|cCâ‘9Ú“šÔ%/�çËPs Œc1‹yÌT*Ó­$Ϻž‰œYÖò–™Ì%6;ÙËOrSŒLôæ7;NSŽS•«<§tw¸tª“6ìœæ%w÷Î;ÆÓ~žìc=‡3F|~sŸ†ìg"Ë Ðß´n-ègÀY,tQ&ýJ™wT°†åx)b*ÓÄtå<'Á`=òÙ8Ý™´§ø@f" Ô¡m¨Dµ™Q…*Ÿ÷€ô8"ÍIçØS”þA¥a)*\ S™ÆÔ¦­Á©NçS“5©(jRÑjÔ¥R¦©ÆÿyjT¹1Õ”.o¥-¥àKËÁÕ®zõ,`ͧXÇZÖ´"•°%3+[×âÖÜÀõ\%=)]=`׬âu«\í«_1VžŽ5 žý¬YÕzÔÃ&5±.Y,n»�Ç⃪V�Vµª×½bv,>ÛìçŇÝòö³ 5ìÄB[صʇ:¨½�jYëÚº^õ®öËë^ P[”ܰºãmo}›á’Ö¨¢Ujqƒs\Û$Wª�­*saëÜêA7¦f9O>â+ßê~ÓqØÝ­v· \‰í£¿þýn¤ àð²c`ãíLyåzÞׯ¶²³%À{­#ßù¶ ·(Ôí}óË݉ù׿Ìk^,øÀ›Iðÿ\Ñ+ÙæRö¹–�ðp&_úæ.·èº/4¼ßt¸¿q9DLb{™Ái3V\SÌàõR¯½~ŒMeœŸYÔs¬Àq~%Øöx?±�Ã[â"cÅ Noƒ]ü`ÛCn~³”©¼-¡YËÚÕ2—{üåXÌD&³fÌÜÚÈNV¶2eó›á,c9K‹Îž³³oñLÁ.ïù¥a.î˜}—ƒfñ_›Úd-8ŽQK£ÔÕ8µcæ¡êy|Ö®~uÎhÐ9Ï­p¶¾µíŽ]ó:¾þõG�Än»Æ>¶J&ìLM×…ÓBû´ÔB}½Q�£ÔÒ8u5R½êV¿ÚÕ±ž5äjÿ}k[çºz¼îõ¯}ìaÛ5÷P6³íâlO? Ô,5©M�견šÕží¶·sn¿‰{Üå¦Þ¹w�nu„ÝÝp7¼ãM—yÏ Úr�6ð¨mmlk[Õ¿5ê·ugå‚ãúz0Lx8ž‡u#‘Ø'λå»l‰Ç…âè²8Æc§q}g›ßÛö¬YWˆ¬‘;P—©Èf좋r•³œ.‡¸Ìi>›Ÿ ç÷žv¾¯½ï’ôûãCz`ˆ?£#vJO8ÓÞòvÃ<âR‡ Õ·auõ¢ßÕæyªulT°WEìÌ#»<ÅAí³Ÿ;íq8Ôã;ó·'%îsǪÝ7¾u’øÛ·AwàÐi]ôÿ†ÞO𣎮c¼aøŽ ¾íQgü[_ïh_=ãYç8¿õþu̇]ócç<õtþù½†~ô)ýX’}zÔ7>š• "½‡`oºGï±×îåágV¿/ð…Ýàyïß {í/~Ìߦw)«IªW>ë™�õ»k½ç\—½PW8}Ûÿ÷1ôü8@ïlc›þÿ?ð]‡Û© ùýÅ”œßòAÞúIžûQüE€ü%õy€õu^öqUèñß©ýz_âåÃâ} ã< ²@Äœ Úˆ|røŒMøL©¬Íº(ÒkM}ƒÂ^Yˆ„ôtÙ4¡¶R+i�^D+$¡Yà¨aÿÛ;ÖÁ N�îà©$5Ò¡5^cAärcîÃ6$-–D.¢£.*"—\ä³½ã`ˆGz‡Ï ‹H’ä…5 P­Pa|¢J¾áºdu™/i`5aM"äMæ¤,Î"9F¥•ƒW­Dæ eꔤÜåUˆÇ Ì%]N¢qô‹[Æ`Ë� FB%2Iea´¡Uê VŠ„V~W†ÞA&ä7.d,VƒË¹\Y^E7v#�•Ã3d¦fº[lØ[î”[ÒÿÌ´’\Òå\Úenàå…¡‹^r _¢‹_¦`f…`fa†ÄaöQb:Æb†%82ä©E&±M&ETf^¦fn&Ìufñ¬c[®fÕÁ%E”¦ivT¤‡j¶#l�̼¦11LT:ÐTÖ¦UÞ& ÜVj b~%câäo>¦pvqN„q¶r&ç3pæZ2 HÎQ&Ä�&t˜æ\Zçq” ¹d'Fn'w6ÌXáÃÇÄf'¾–3V¥m.œ/¡'bª'o²§o:& §pÞ‰–h+Õç}&§~z&¶LNügFèQ(�¨q h‚JKò4¨ƒŽU„‚ç_Šg`Zhybè'i¨nrhYô¦7º'ˆb[|–¨‰Š~æçrîçP!ù ,*ÎÿH° Áƒ*\h0€Ã‡#>L@±¢¡‹½hÜ¥£G+ CŠI’ŒÉ“€Rªôò%¡—0ÿü©˜€¡Í›8è܉±§O�sJT(�£H�v,šãäI¦s¢JmIµ*©«XhÝÊU«‰¯`ˆ먬ٳeŸ =É©­ÊIpóÈ�˨®Ý!xy^ I¦(R©… L ë€±uŠˆ³±ãÇ�#ã”H9"MŠ> )Ý %dH¦NMªTI˜0̘3+J^½p§Þž¡ÉlfÊiR¥´s•:µjéÁ†ƒwv¬X´Žø(_®¶©É¶œÞÂ5l÷n^�ùú= X0aÈ3ÿfM¾¼yɕӸœ 3g¥žA‚=:åo§_ʤyþ¼kì>Å6›nFÙFÇ€BÅÛUùqŸp@ÜWƇÖrÌ™4[n¥×$ÔUÇ^C¼¦QEXià‰•X‹AÔߌ4Ö(�z•±çÞ{A%[}€ÜWáû©f£dÿ �™€¸%hà�M&XÔ‚ úö[„ÂMhÂ�Èa¨\sFçát]‰8âuJîR_(r§¢wÀuŒãiç��áH™Ž?ñ¸”�ôÕ'd…ER„çcI.‚º=ɨ”BQÙàƒX¦%—z æsòaˆÕ‘hâšÛÑÑ‹rº(žŒ‡¶êjAzJÿÄgO~þIà�‚þ6d¡5½jS¢.e£> ©¤V¢Z)W—VØ¥¦®Å©˜ž’É•™¢hȉC¥8NJߥzÀ‹1>ä빇êyȺìÆVÀ»ðÖ …”'IEÚ}ƒíšš¡è4È¿IÆÆ$PR::l‚!IuɆQº¬YÍ·ÁÄ{ÉdžÓB÷á§eÖ…ÈÇÀnKj›¦¾©ìVs–ëP¿,×(Ñ"0ÇÌn»¡Áo­ôšd¯}ø /-ôï ñY!°°@!K•ÁCšCÂQ-|IÃW.;€YES¬õÖcLto bÇŒ|ŒHÈÜXò·p&.¹u-÷j/Ç óÌëºksòæÿLÆÎAöü³‘s]ôÑNm¦tKL÷)ÔsHMõÉXbßÖ˜oе´_ƒÍ‰Øc_ë1Èÿe7r·n²MùaªÒÉêܰCÆžÝwã­·Í}úwT÷â;8¿…ÿ{8â&)¾`ƒX%¯¼ÓOƒ¤0Ã]9\©åžeε—^{þ¹Ø š�öéjŸ.W)Çûù6ÍN;Þ‡Ü~3P2Åÿ‡ß€÷ì3¡ûö<Ñño’ü2YK”G@RÜà€Ô ä$½ª=¬,Y³^ŰÇ9í�®{¤s�éŒV*ñʼn|­SYÐGÂô]†v‹`ŸûÞµÎOwõþ€¶¿áÏ…ôC•‡Àæf�ÐãŠôÿ*ÁËIpb›sNçÀvA²y¯tjâ É<è6ŽkUæ*¡‚¹˜•$Z´ÙŒÅ¨˜2¢hL£ÖÈÆ'I't[©�çH¥¡ÙñŽŠÈ£1Çž$©3Q‰Í˜B’ÞP…€s™K¥ÁÈF–à‘� ƒ$'ÉF6šÉLC6ÉI=êÑ ™aSòCˆ! ¨¬‚*“¤Ê*„DŒ^R‰"‡óHnd#Ùb캳/²)ŒJã‚̘4ª±’>pã˜àè• ÕñŽÐôdùx?¦�"³‚ áEÈ‘²%´Z„ ÉIJ™>¸¤ˆ2©%i*¢!eQH)=œ2•«üO+_ÿÌX¦d–̪å#o©‘\êrn¼\„/uK ‘‘˜ÆD#:•Y-fJÈ™ ‚f4¥IMšX3Gí ¤Y”BFyÊ'„ÈùHsž™ê¬;'äNxBDžD¡§PT¡•¬T%?�b1YÊÅR-A½`Ѓ-¡ ÍMC—óP3f¢z#R‰óL�Í�­ÈG÷Òlnó]ÝÃ7˜R•GK. :cj—™§¦°Š'ÞF™éõŸUª+Ab,£æa«¶$hS�Ê2¨Ž¤9L™ªrªZÆ«"“¢ (W3zG’�ÄX}üÏË*’‘r³¤Þç›_&ç7ÎÏï­oBó;"þz~€$ð�ºàI/6S€Ôð Iê§zÕýóŸ¢=éIE³„æ7Ïe-qÙë\1Ë&F߃қÞÛZr<:7cŠÖ»~ô°ßˆMOûÚ›Íl.4€îwÏ{ÝIjRÓ’4†O|as’“¨$ŽahÁ|˜$i#ˆ~ZI’…ê[ŸËÂne+%‚9‹ÑH�l$ÿ—Á¾zÓ{ëm'KÁþö'éýâUO³“dùËÛ&ó›×|ç'ôy�‡¾,°W{=€z©«§®÷z±'{Þ%€x{“{½7�¿|— |Ä7|Æw|`�|`±|Í÷ϧÑÇÓ7Öw}–}ÚWÜw=ò}õ~Œ4~!W~æ_è—<•Rpíç~ð„z2•öwñ‘úgaž×µ¢GzµG€¸% Øz È€žå€¶�8�¼W�À‡�¸�Çç�_‚´à|ÿ}Ò‡Zž•‚Õ‡}„Ö‚.Ýç%284Ø6¸m8˜ƒ²µƒY�%>øƒ‚„Bˆ#Dÿèõw„t ”X‰Jh ûGNø„Z…› €TX€p…‘…¦°…³ç…¦�ˆ†b¨{¸‹²h�8!8|/ò"Ø�E |]Á|m(‚oH‚qH F‡Y`‡F†‡/¨5ÞgcàGƒ�(gƒHˆTŒÀ؃마ŒCøhIò â8ŽäXŽãX‰–¨„ʰŽì˜ îøŽ—zP€£w öx�øh�UH!¤Ø¦¸…C¢Š«†ôм'‹²ˆ ¹�ÎÐ�y‹Ò�‹‰±‹jHd¿‚„WpÈùØ‘§€ŒÌ’"i $Y’8�­�’*9 ,Ù’ôfŽË“2Ù 4Y“ïøŽÕÿ([ù<Ù“ØÈ|7éŽ ¹�½P”F©ˆ‚Ð’J¹”L™ Nù”PæTáhŽTIŽèH‰Ç�•Ç yìØŽAy‰Fi”‰Ô‰ô¸ ™�g‘z²F¬—…Y!Yz¬èНˆ�±8” é�y‹YÙ‹x‘Á˜‘.µ‘g‰� )’!Y’&Y{(©’)É”/YŽ29“5I“A™ ›ñ"³µ“=É“?I ™‰—È–E‰”L™šKù”OÉ+ŽÿQ•²ù W Z¹•–Е똙`išcy5hq˜÷˜–PÇ–!ÿ¸€C¢›Êð€)?¹{v‰ ¤©— ‘}ù—¾ÈÀIŒ)œÿY}ºPžŠ¹˜Œi 'Ù{�™Ky�³“•¹ —‰™AizQQÑ™ùø™ ù“£‰—¦Ù ¨©šÊšNéš#ôh�Р:›UY›·É•ºÉ›J8 ¿‰ây ÄéxÆaœP€œYˆË©›ÊŠíÙ :�Õi� Ö—Y‘lè�… žj}å© çÉ é©žŽÉžíÉ”ð)[òY™õÙ ™‰Ÿ¡ŸsÀŸøèŸ�š:”Š Vz¥z ª Íæ  ¡æX›—ÈœšòH–g±¡ûh…Èä"š€$Z!Ìy¢˜¢+j—-ª—/*‘1 ˜k(˜4jN†)ž8jžçÙ£ëÉ{)*¤öÿŸ”9ŸGš¤¥çô晟)¥AIšUz¥Vš¥ª‰ ™•è#^Ú `¦W9¦ú•Jx¦À™¦â¹¦£Ø¦Ç§Æ1§¦¹…v*ž,Š—Öé {š‹}J®p¬ÈÚ�/ñ�^P‚7Jž†ª˜ˆú£Š¤ïÙ¨Dú¨FZŸ’Ú”jc–ꓚ©jšœÚ©žÚ”*ªçCª¥zªå(¦ê¸ª7�þ7�°*œ²z…Rq«hQ¢]9 ¼ÚžwŠ�yê�Ãú"Å Èš¬ɬÎJ¨Ðª£‡šž‰º{‹z­§à¨ä8ŸôÉ­÷9©Q©ý韘z“šj®çš®êÊšì;îê¥ðj•©:¯]ÿY¦œw¯hjjº�³ZInj«„†«c¡«a9°�Y° ¬.ê]0š�ٰǪ¬„)¨6*±Y�£;:­´÷˜�ɨ›­ © {“J $û¤&;®([®ay®¨À²«¹®Ì6ª1³çx•·™•̬Úó´§Ð“f"lq†{¸¨%²8[}Ð¸Ž»yÁ7!HšRë <»¡gIŒÔ· 9I%Ø~/¢’}jd•»�·pºt° ª«º¼A ” ¢Â©’¡0»2)’5iº¨{«+‘_«±§0zQA••¸£5Y’̹ È›¼î~kjD‹C”½*œ *yº$x+Žº·œ«—Ús˜‚ÿ+"„ëR‡‹¸4¨¸±È¸ŽÛ¸�»0Z2¹xY¹—‹¹©¹�нž} ›¢ µ„v¤¸{ ©»º«Ðº¯+ž²K»1i»4ÀH±»¹Ø»J‰�À;ÂK‰ÄK“ÆËœ«Ê¼kú¼½K9½‡ ªÍ†½Ù»½·Ù½ù½g¾Õ1¾æT¾†›¸²¸²µ¾ì«y‘k¿áG¹R;¿ô‹�ö‹¿’ô¹ìº)9º>À yºLÀ,® »‡™À¡P»!y»Oœ»¼ ¼»’¾[Á Ü ÌÁ^éÁûÂÀ'ÂJIÂgiÂ�†Âx«ÂZÉ é Ãv!ÓDÃ!`ÃÄ�ñ Ã}оµÿèÃ�Ä +ÄC¬�`±¹ºé�ùËû[ý‹�ÂæÄÈÅ_̺T|À±›’³›Å ¼Å ÜŬ»ªÆî9Á÷HƨjÆçY¼$©Æ7› l\… ½"½+žtev<³xÌ·•l�|l©f ÐÍ…KÄ †ŒÈŠü¾4èÈÈ É‘\ÄËì —œÉ›|��\Ÿ,ÅlÅg‰ÅZÌ \üÉ^ ÁJË-IÁ›¼µ|Æi¬ËËÛHÍ»¡pÜ’)WYÌ vÌðšÌÇ ÇÎÐÌ%ûÏÍÐ<Íå[Í_qÍ:œÍ’»ÍñÄeÉùÎ]iÉG¬¿IÌ¿Kì¿FæÉ ¬Î£ÌÎéΩÿ Ï«,Ï­üÅ°Ü `û»ùlÁû|˜˺¼›¼ Ðk*ÐÁ<ÂíiÐùˆÐõ3û¥´‰•{›™ìè¸TªJ%]ÑäKÍ4Ø£ÓY¦=<É� ôŽ Ò§�z”¬ PWíW‚r| M|¤7ýÒ¼Îlʳ{ÆìÊ`Áb,ËöHËUÉÏD]ÔÿÌH`Ñ“n�®íRù²vSmªÚkÕ·‰Õë¨Õ ÂÕâéÕ_mч»·Ç@ÖviÖîÛÑ?¬�k�¯n ×÷»ŽsíRu}w�×z�Î}ÓÝ §,جüÀ¯lØöÌ’ø¬Ï‹-ÔhÜØþ|Ô�ý’-Ò”ÝÔ.õwŽÕÿ±Ù��·¶yÕA™Õ�»ÕÚÕ òÕ¼€Ú†«Ú¬��®½ÈhÛjD´-Ò¶ÍŽ¹mN»Í½�Jz½×¨ ÓQQÅÃ]ÜÐ=Ø:­Ü<=Æ?=›Œm EmÔl|Ý‘œÝ�WÜ�EŒ%ÕðJÕ•¨Ú ­ ¢Í¤-œ¦ÍÞ-Èð�žeͪ–pÖ_Ñ‘ 9ÛhZÛÚÌß§K×ìg×ÃÌÉ>àÀ½º~]ÊÄØ ~Ü„½Ó=­ØT9á® �ݑ͓“½”T²Ttu[B ~ª"îÙZYâ'.)~˜+ÎâÐ\ nþæ/Θ1^¯<¼0š�7Žß9n�)º‹÷¸ß¸Ýãºýã¼äæ<ä¿ÿ}Ü>Žä ®˜ñ ÊMîàOá² ˜žé¸Ü£ÞÁHm>ÄL¹åÕåZƒÙíúÝ!ÎÙU=ÞŸ]Þ¡}Þ£�Þ¥½ÞlÍoç{ß²8ßwŽ�y>5]1¿}Î�¾ã�~ >.@ž´,=àÍPä¢|à¤|Å€ Æ�ÓÈ]ØõüàˆíÓÎM•™®éCÍédJÝVnÝXŽÝZ¾ \¾Ý^ÞÝ%„9`Š” ÝCT4T’±ßn� }ª;ªÚÁÊœ´¥cÈ![I³ H€‚ï7W?êmž¼�KÕ—wÝ—¿·sÔJèº$O =m�™Q4ÿ–Þ&ñÕü.·³ÿ�¢hf½“‡9±bHÙD\!ñE+@ÿE³@ÂóîV…´Èƒðì¶ð±Ðð¼ñð�ï³?›ñ$Þ–mb±T˜bLÑ—™!¯JAŸ)+-�ï/_ö@?y’�ó¡¡óŠhôZáóñáö±2ôJQôÜ“lZ’ôE±ô…�ðÃŽ ´Qñ"ñU/Wo Yÿq\¿5^_`Ï„2öy¨÷qöž‘ö0±ö=Ôöž/prïtÿƒv?úeÏ÷@á÷†Ÿg(øDAø·�¯f‘øµºøSßC�ÿ‘o“oEcQùZsùD‘ù‰¤%œ/ûú¥åY¤DúTjÔÿ¿ ©ï6t­ß~¯ûݯ'´ï¶ÏnÍ yG ô^Âô­öª¿ÿôŠ/RßøTþ@!X�ÎA„….ÐÐሽL¤¸ÁâE15æàرÎG�yDŽ4QÒd ”UT`ÙÒåK˜1YZ¡YS£FB9u.\˜ÀçOA…Ê$Z´%¤I•.eÚÔéS¨Q¥J­Y“ÌU¬73 âÚuÒW°Þ [ÖèÙ¢†ÔV¥Y° ¸qÁ†;Àä]¼GôîíØ‘Ï_À çÖàÈpÇX±ÜÎaLÊ1$„Å–TùçOµ†t aB…’F”HqâEŒZûr v$I¼(k¨¬‚ÖvÿK¶V´ŠÑ¹“g¡Ë>…½m{êqäÉ•Ký™kV­]“šû•pYDÙ‹oÏœ»3”¸r«Æ[ÞÄ^¾«.4¸®aGˆdùkì±ÈòÛo�ýÀ”¬ÀôbÃWspó�0¥•j¼íC6ܰC4Í$ÊD8ã\ŪT$ƒE®¦ã±.ì´sÓB;Ó�=ÅòñG …ÿ²HëރϰĔ¬oüœ,‹¬(Õú¯³éø­°ԒKÕ¼é£0Çœ­Ì?�BSÍÙü°U˜ä´õÖ}rNE<Ñs<>eô“V¢¼TÇB:Ô$ �Pt=FatôÑHé›”Ò&E»Óþ4�’Ó* µÀMÊ5—Ô›<UU¥�X¢^…õ"Y‡ƒ÷(\óÍ—N«x�.O��LXï�ÉX·M¶¡eKjöYöÜ;òQGª%èZló`Û2Õì[·:ýt\ÒÌ=7Á.ûZ·ŽTc#³6ƒa’w^ƒkÓ`}s¶•_šììõW‰Ç"8f˜~ Y�•møaõmÏH‡(®x¾‹¯­ÿTÛm=Þ4äpy"9"“ËEw#SOmù® Y%š¥™ç­—¸{u–{D˜&º© Ž°ª/®KúI黲\¨¹à"›V+h3¾û6!¿’Š�|ò6*·¼g¬úʨ¾ûê‹É³¸¦¸ C"ÏM’<Ö[O¹£Ý�ò’.°ýÜs§(w(VÓ¨>…ž’ãRä¥Â“W~y\ëöân‚ò¾jo¸ú¾äo†ñ< Âç>Ü¢ÄûZ\ Æ/y\´È'—ÜòË­xNs18,u“@/BtªI‡ËtÔ U½ˆÖ¹®Tð»‰ìC;Øî¹ÓÝDxç»Í1&xÃ+\ŽçæePƒ”Šó ×ÿ;Žè�1åÞ]´7¸ î{_GÆ÷‡ò�O2éSû*‡¹«ÀO~¤ÈVöê:ÑD€àýL°º†àu‰�Žf‡¾ÚÝŽ�‡Øî@»Îa‚« .ˆ/†QŒô FðÂé�°z~ àL²½îÉm…-äÈ cH;õI®C8$ƒ—ÄC#šÀ~ø"MJ™þ¹‰dƒšž'Î0Š œbqE&fq‹Ä«KDŒ‡¼1†R”:+cFΘÎ�„môáQ("Ž&bPA·Fóá1�{t_永Úð‡÷ "A†XDÿ¥/‰!h$ èÄB1�Rd %1™ƒßÿI°Ãã¤X÷Zïõát \ݳ^7ÆÙÍeƒkÚݸöò»ví?ïÛ¼–w¯çÿÍð_×Ëá)vÀ Žï¶æ‹ÅøÕ×±(>nZüe2ÂsȨ¼ Eâ2�n^©7FL*óf(ÙìC™É̘ݢ×ÛÕ%(j\âˆ2h ÉDçÈŒ,„›[vȧåHGz:‘t#,}i,]úÒ“Š–ìÔP‡Z� ”ÚL½b0§ZysÄ\_°bf¸ YcXóp–ãf8Çù2h¢³Zì\Èò¥´${îóEþœ€@¯†1½)ôcíLE/š0ŽÖQ¤#]ÂhÚÒ™Ö6§ƒâi…ZÔ£¾@©O�\U§;y¬î¥«Ë<‘3;&Í¡ªuÛü’\ë(sîõ¯-ì@ÛÏ-ôÿDˆAë¤Ù(~6£}âFÿæÑÖö¶ë¢mFp[ÓÞ¸Ÿ#nP“»Ü3õP­n”7OÌ}”` Yç‡Ölþ(¾sý¶ ôÚþö©’óìFÜØG¶ÁWCˆ9ÔAá2tb-†‡Û7?ƒ:›I²­m�oZrpkɧA.rs›Ý)'û­Ø=æWÃ;Öòžu½Ý™\ÃÙNvÒ9ÏñÜ7a�ÏgIÁxp„/ý5M�ÅÓ£Îh¥:¤ê%¹º¦³niŽÃÄëâ;ÉÏíå²g^Ngg9]®v˜³]æn‡¥râþ湫¨î�')°q™w¡[äØÉîKN’ž“…?" Çòáçÿ�ø,¾­ÀøãíW®³dòãuØO®yè·yåîþ¼âMŠß{“ô·f mv•ú«¬ž´=¸ž÷>ô¾'€6¹|æ�8Ä¿„º'ÍÓ5²èì+UøQ3 üÿã»—X¾�#· ©•èK@Ó›¾–{¹˜#�í3½îS‰ï¿Ô¿»+,ó+6Ù#ºõÃÀC:¥‹?8˜¿Ñ(ûËü¾ºØ¿†€�ÿû?üI ŒÀ–È7�ë‘;ÀpR@Œ Σ>=¤¹©h ïK ? ô9¼ ¸óëÀôûÀCA÷#4ÁÀ’ƒdAÅk¼à?GˆAÿ›ÁX¨ÁY±98ËÁÿLüA9tŠ l@Ð{@53šÀ*¨À%T‘&,? ‹½ 86* ÁÀËBVB±ˆèBxDHÃ0| ‹+Œþ3C4>°A–È7ÚøDPäAýšCRLŠ:ô¼!ľ¶ÓC äC?üCœj½Ã¥Å#DCT‰Ü±“Þp?EL$ú‹H„ÄÝÆGĸÄsAK,CLœAMäÄðDPŒFQ|¾RôÁS$³ê»¾ü�„;WTBXDç"?ZC“°EÄEÜÑÅÞX„^üˆ FFb4Fý3G«{ÁKŒÁLg„ÆhüÄi»jœC¸÷Y�«ØŒ?€4Ó &a2”`ŒQD ˜Øÿ�?MÌA£:NøHNp�ª"˜™É¹µ°‚XÉ€Úš7¼p„±«ï`y”ŒÃIm ›MØMÔ’8¼·Š,H¢\ŠƒLÉ„t7†tHÓ¶‰œƒ¡¼ÈÉÈÔÛH�ëH:É�¤Ž‘œ“| ¡¸–lI,zÉ€›É•ªÉÕ¸IŠÉɶԶ ´H£(JºLž£4«PH2XJ?xH§¬ŠD5©D -ÑK±JqÃJ­IÈñÊai‰°LɱtIó‚É»�I´T˾`ËGqË΄Ë”Ë¢¨KÒÔ™»ÌK¥Ü ¦¼7zʨ|‰ ÑLÏ{Ä 5ÅIÆDÇ,—ˆL¼TI–¤Ìÿ%³ÌsDK0�MŽàLøðLøpF¬šËÒŒÎ[9ÍžÑK¾ôK#rMÁ„ÍAι«MP»Í�ÌÍÚÍ“¤ÎÉ,ËÊ<ËÌì ›$F�Ô4©qÎ¥é¼O8¡Î¤”žëlÊìL¨ÜN—ˆM÷¤>ÚŽL(�ÄM®lLÉùÊÞDÉßLÏL2K=3NäÌå4 æ4 úT ûÄO]ýd=2ëOÖl%í$HÃy £‰WÓÊ�ÏÏ­”Ý|ÐÇd ¥ Å&1°ÐA«7Û�÷ ÆÜ•ùPS„Î}Òã(QëT;ôÏ ZQÌS �{Ñk"åÂÂ?%Oò0O°ìQà\Iá4ÿâ6"­ #]KbLÒÙ&Í7�R=� )MM�XMˆDÊ- ·PÈ/ ÓEÓÍÑ’ÜÑðM NõNöƒ"M�#…D:5 ;]Ã×Í=Õ¦èSþ¤Rì¼ÒAEµB­ ïLT°Â?žì‹ÏF-OåMÈDÓÍ!]*ÌÄT8]Ò‰ÆN­bµ—ÐlQQ%UgE SE# Ô“XU™hÕšø;�Õ“’Õ°¡Õ¬dPÅÕGÕUEOJ­Ðõ¼Ð•ÊTÔ@ce %}WPÐ<}Vg�ÖEU+mMk� lm‹ÎØVUTnšÕލÕíÊ\=O±LW ýÕˆ º7„ÿOŽx­Šy½ˆ;eÖ{Å×Q�Ô è—ç°£ùŠJŒˆÜX+øŽïÀŠóƒ/TÃ0›5Á˜…€É)¹©*ŠlX©¼G©jY¤å(‘’Å “%”Ã<€•í5.}Ùk‰Ù™e˜š½Ùœ½–�íYSûÙç € u ;!Zø0ZMZ·].¡hÚ«xZ°HYˆ¨Z:»Ú΀YŠÛZ»èZ›ýÚI [ÉñÙeÅ �EÛ¡%7©aÛ,}[ȧ¥•[2 Û¨½ úÃÛÌ0ª 0ÆØYÏ\œU6°Mš†Û! Ûúœ‰Ä-ˆ´e\ŠqÜÈ�]qš\>š[µ‚¡“�»=€|JPÿ£ÂÚÁ5]ò]Á­Â-à ճuÝÅm¾Ø ÌÇ¥]êÝ Û2§Í]ñà]©ÝBˆøÝ«ä\áE^â ]G¸ÙÑí �%^ÔU]eÝ–ÚçP[Ã�Ýê½_C;É©D‡ßÄß½eŒH]C1^y¢¨×Ó-ܱ=Ü3Ž×5E¨` ŽKüÍ`9Ò_áßððßVàM(†ˆú(àò=àóõÚV£&Œö…à•àçU ¾àeÕ`n.Ùcùàîýß<áf*á?8aH3`š]áÀmaUÚ]vàÔ•á]¥áù%·®` Þa.Ž“¥õÍÌðà¸ažâð5*#Fbÿ?Pb®eâôu.†š^^{=W4ŠhÌâŸ�Þ.îãùb ㎋‘© ¶MÎMcNâ^bô…¨’ÚÞòˆáP­â;Š<Îâ-öcNn3^ë51†‹B‹CÏD.a5fã¿ucHö*IÆ J®c@¾ãL¾áMîä Š YŽhDC#þüËÇà3b.S8fd^™Aqfnfixfh¦ižfÙ� Šh ÚëyTÙ¸å§ðf\g¥ÐåáePôåæEæbæ3dNæuYæfffhŽæi–æjF‰kf‰lNNbäf”ðâg‚N rF sþDtfHuæ&vnçw>feÖ‘ÿy¦çz–†{Æç|Þçèg ýg—©f�Ê‚.i]>• •^iôµÙVxi˜ž™žé…ÞŒ†a.�ˆ6…•aŸþéŠv…‹ÆèŒÎçàh˜@¥^jHhj§~ê¦ç’žêü Š @é•f閆阞i¯öê_þ�`f¼¥2�ééŸNë´ꌦ£Fê—Xj¦†jº–jª¾kµj¬Îê0hiàê—þjÁž…°æ‰±–¡ò8ëuQkÆf¶.ê�ž¢�k¥¦ëºh¼Îì¹j�Hi¾ökÀn…ÁþêS(mÓ>íÒöÛ‰5ëêh×~íÆVë×~í¶6ê³ l°l¨¶kÍîmÿ©àì�ðì¬mÀm¯Fmä>ÕNìÖžífˆí´vîfhkgLjÊÖí§æmßÞî¦Ø¾îë­.nã–éäFí寋‘nèþié¦îz• ÜÆn§Önî®o¤ðîÏo®oò.oÓ>ï»Hoç^oŸ–n`8p¯î¸¾nù†ú¶oîÆïáÖï®oÿöï¼cí¹Po7p?pw‰ønð‡pß–p­FßÐæïY¸ðòÎpŸmgÿðo‰—ï7ñúÚ¸ÙUr!rdFnwñS�š0áðõ^'r(wò_˜r*çq+¯¬·Ù!ßò"Gí#wq%‡&‡î(/óe¸rÿ4¯*W ßr"?f#ço$ó×óØ6ó(Os=_®,77sSˆs sŠùð·óÆ.ó=_t,gs-ÿóUèòÓþò —CDglEgtN¥5¯‚6ÿsI7mJ÷oK7ôLWëMïtV£O§ HrA7n$[¿õKOõ´nu^¥WW‰XòYmä¦r*¿u\Guç6ö)ïug¯Ýh ö öÁ.vfGv[Ïõegögïö1úuPoii�ôˆlŒaö_Àö`¸ttGwowë�F¿÷�öës¿vlg÷v7vxï÷å÷y—özoé{7vu×÷}ov_xïy‰hüî�G_ÿ=†‰„§rºfxŒ÷¨ ÉxŽOÀ�ïx�/»�y’O·‘/y”o±“Oy–O®•oy˜Wóíˆyš·ª—¯yœï¯™Ïyž÷õ�ïy ç ›z¢/z£?z¤Oz¥_z¦oz§z¨�z©Ÿzª¯z«¿z¬Ïz­ßz®ïz¯ÿz°{±{²/{³?{´O{µ_{¶o{·{¸�{¹Ÿ{º¯{»¿{¼Ï{½ß{¾ï{¿ÿ{À|Á|Â/|Ã?|ÄO|Å_üw•÷Ž ÆGó³¸ñ¶�|îžüÇßqËgÌWÖfÝ|ûîüäƒ|ЇpÑ'-ýËw|ÏÿXÕ÷mç1� Ñ Íý>Ž}Š˜ý›¨}ÿÛçb=ÖÝ×#îý»†‰ß?�àÏ#æ}âOZãÏbàg‹ÝX~Ìnþ¤m‹ˆþªà\lÄŠ•­~ëYìß-ÉP±“ï'éð¿þÁÈ1Ãô~¶0ð_ÿ|mÿ©|ÿ5*ˆ†$à „ 2lèð!Ĉ'R¬hñ"ÆŒ7rìèñ#È��,¹á$Ê*WBié2̘2a’©i³Μ éó'РB‡-jô¨Ð’&Qž\ÉÒeË™Rsؼ™ç΂H·ríêõ+ذb#*%)æ,Z§*¡F�*³jÍ«Xyök÷.Þ¼z÷v-+mZµl¡Hdø0\2rÿÒåëø1äÈ’û|Vm�Á…N¼8«ÁÉ¢G“.m:£—Ôª-‹Áþú÷èï¿ €ZYD� r ‚é)¸ _æf„–·`ë-Ò^[9Ä'Ÿvõá—ß~úù÷_€¡Uä O&H!ƒe¡( „1Êè…bHØ{Ò1Ÿ‡N¢ˆ#`0Rô"A*Èb‹J!ÙÜŒQJ)Z�ìÕ䞆:òè�] ä�%B9ÿÑ“J¤‚ "9%›m:Vå…Wf¨ãŽÚyy'Bi$™Hš‰fzj¾è&¡…Šç�1Ñ9žx‚¹§‰Gú©$ è Š¢¡™jJTAé©–XL.Íw ©¥6z§`¨JàEZh!k‰ Fç“›Úz+H�¢÷)\¡¶4j©¤žêeª«>()O¯®+\³êÈ«¸J;í€yš¨0‰ª]°Â d±`D{"]Ê.ÂlUÎní±Ôºû®Bº&ÀkU¾Bl°ß‚ÛŸªâ¶+‘! l.º7ºD'»áÁ»ðÂòÒk“½øšªožô;®C~ <°²Ë –UçÃ%»ë0¶½jû+·ÝR\ÿñÅÿ.¤ñƆl™¬l… ØÈ&û<­�ªvÈ!PÉDtl¶y‹ª�Ž8ýtQK�ñAÖlÈÈšÍÄ]{Í�!ˆ=6Zéý|6¡A2tÑXæ€4lJ_Ò(˜OC-uÔY]sÖlIŵ×]ƒ­ãØdŸe6Ú‰K©6ÛFÇ7}µ-MlÓv;‚wÞí½qߎËxàƒoX¸Øe£§8ê22žÑž¿}HÒ’Ïí¨�ŠØ~;Õ m.pήÃú×–…Mºé ¤~<„«{ѺÛ�ËMwí·ÛžûB»ܻۿ[¸àÂNüá§#?¾xÊ3Ÿá뱓2y—`J?½ÌñÒu5öèk÷|ˆÿé!O>¡c¾¶¡Ïy²ƒÞˆÞ§êÉ�'ôk–ß¶¶=îí>ýc â¨AÓ Ðu\ß옖À÷10!Ö3Dýpô¹ ÎG.œÄ-“Á Òp2lìâv@Ú�Pz%DÈ Sø7zí…>Š!`fXÃ%:æ†Ìaä@Ø(ÌÕA�?<È“®âtÈ;Füâ$!Æ1bP|L<ã^œ¨ÂôéPŠûaãHE+þ+ˆZ¬ ÑòEõÙŒF#ehF4Ò.j<Ÿ÷Æ8ÂqŽ$¬ãüjvG<êq�mì£]H1–Ñx…4düŽ€«YÁ UaM}He‚UšHŒ(Bˆ K"°†ÿHD2Í QJSÖÄ-9ø0ƒé‡aDßb%+»¤‡e2Ó0JùdX®¨¸QÖ¬”§´L*/�LWÂr–D�Ê`pY�íbn ¦0‰9Lc ™«T&3—éÌ’@,ÒL57fM› Ò;ªLfˆ^ËY‚“-âT 9÷I_¢˜ê\ç}(æÎV)žòÄ3ëé•{¢-~QèBg¬m´›�‰Öd’Ëröòœ }¨Øyª‰vi¢ó$‰F7ÊÔy´, •ÊHúF“ʲ ¾ËÁ.w™P^†t* ýLeÚ(šɦ¥gN¹ÂѳõT)?iËH:Ô�¥”IRK¹Ts:õ¥ÿ•*ž¨"«f4«HÙêϺZ’¯Ê$¨ï,)Y¿iÖ£¦µ°V`hC1ù¡—éG®û¡+Víz¼úL¯$ákLüJѱzÓ¨ÙCªa“ŠXt*®3ugMÝySHö®;E�e€Y˜h–›�õ¬ý@ÚRŽ6˜¥�(cÛXÕ^§­ýˆ™®FY“Åv¶9¨-`;;ØÏîv—½æoäJF2bÞý®pYã·#É­™¹(4¾æ2µ©™ «Põ#PéÊ$¥1©.o]JÚÚ¸°KÜíîw½ ÓÔ"sµåõÈy7–Þ­÷£í*|ÿÊÙ“Ö÷¬÷Åïuÿ�]ÿr7À~(�Yià7ðIaÊÿI ;˜§¢%Ë‹‰éâ—K9ˆBW{ªTèt˜RåáNcäw`Ú€!9 F>²TžÊcNL>x2”ÏbÛ Êíë�Ô¨°ãƘ'(Þ€ŠÙ’˜ŸäÅÑì2Afì"$Ù¸f8ž‰Ž Ãc‹ȳ2‘‡|d$ÏDɳa²;� å'KY}U&À•�å×~Íùr˜¡2泸˜Ñzqtli\ 6oìÍ2‰3 æì¥Ûù0xÎóž�œä†.¸â ´�Mh1L¹6‡Nô¢·ÜZLC:­ƒ™´*­k:ZÍNbó‚®fßmhǤêñ¨ë\jÃ4YH©êÑÙjí¾™`b­Iÿqë}):jZæ“]1]ÉCà À6º#ƒic—äI"œuäìK@»K¤æÌD«=¢kg;˜_|¬;YnC[™Ü¹ŽwNÕ]Év¿»Ì–Î˼é-{/ߟַœŸMçFp'à°xª ̃™ —`¸Ç"ÿ<ûî÷�”^e¦³L�::§>תæêQÌz�Ê]Å‹£çy;?-3ö¯<Éì8Û¹âéro҆ @÷ÿUÚ=åx7¸�B¼Ê—¯0æ Ÿ9–ÍMø3>éj_ŸnK€�–Åë”'øµÂÙy^�³/û¹Úyû©2¿yt~ÏëîÑb�4ÒǤÐX?½ÖU?ìO&øjÖØëe22ÙŸ…öE9áís/²Ý?~‹PÙ|€Ÿt¹¿øG>¾C¯|í0_{¦G´Ã¥q4Vÿú®ŸøLlä‰ÝêÕ^A�~‰Ï�`¤úý^Èñ[ð±ß湟‘Á_rèÝ~,ŸÕÁÃáê Þ¹ùÜEt ‰� š ®àq© ¾`N¹ Î`!É ÞàÙ î`é þàñø !Ú!aÉ!.¡»( !>á­8!N¡¡!ù,*³üÿH° ÁƒX@€E#z™Hñ�Å‹t2jÌÁ±#™� ;v C²$”“(ç¨4ÅÒ‘Ë—‘bÊ4@³f‚›8&dÈP§Ïƒ qR´B4¤È£A‚<´©S¦5k–,‰TéG•XçhÚÊõ‘ׯŒÂŠ@¶¬Ù³dó [˓۷¡âʵJ¦cV•>òŠkâ쥿¿3ôEXãFŽD­ˆY\¤±‰Ç�!˜|wΆ˘jÞ̹³Ož#J¤8ñ"FÃtªZE:•$Ê”+[¾t™§¶í¨4qæôÌs¡çÏ„NLl©HºO“Ám uÕJ+síúÕëÞ°h³›UËví[¸rãÒÿµ{7¯�ëŒúšý{)ð¯Á…QwL¼XLã"‘óO>Psæß( @ =$š"¤•fÚ!¨¥vÔxG9÷ÚIX±dÊl´ÙVsºÝô[o hPP7 UÔGÆ=h•rO1çt I7�&ÕYw�v8r×Ýwn…'ÞjUfzê•Åž{ðùÒà|DÕw_~‘íןˆhå•;1Ú�‰té%R„)&Œ(FØÚ„PT(Ûlnˆ[‡ |Ø–Wâp'Ö•¢G+â§!ʹØ™dÈ8”8&º]wÞñèc(æ ¤^×IÖ‘‚-D˜’ò!Ö$cŽAù˜”wQY%�¨^Yà�ŠxùåQbŽÿ©btwI8¡šbØfPÂ)'O¨’˜€‰V·''È&{ÄŸ€&'èT„Ê¢Š*ªc[<ò¢í¶‘Nz^¥~–i›.é©b â'ª ¤fejªð¸*—®&f¬D[ë™·Æ–+›möÚá¯=Ñ),±Æ¦˜¬²ÌŠÛ‹³Æx׌šP[mŽŒÃ#&Ûr ¤¤åQº—¥`úž¦ñÆ$ºö…*j»X½ï̼ii ‚Õk/¬øê›•­¯YhaD½+”5$­tLsb°v‹g±eî™ÃÂÈ.û§ÃQA|œU•q ö´ù]œ¨Žr£öÚkQÂ9˜‡ tó.{—lj³C%ÿÖQ}õÑ-8 ëF¦ô4'þÓ¼8{¡ó½±úŒÐ( ÍRÑFœŸÒK7½ÙÓG�pÕÇb­µŸGœ¢úê5¶þÈê«Ó…¦Ø�™Ù¯•öÚj·ÍËÛ¤s$·J‚Û½Þy¶7ß~søbƒÓ]8d‡_¦øõ:1NÑãé�}îüî$¿ö!™ ŠHbvÖ[Ö+ÿüçê^2³A ¡ MhfJÓØô¦´È©NwšÓaš @ jGý8VÑ¥AÌÙÏ~0)ˆ¦:•UFµ ¦JÕ‰6&¢µª©dvÏ+ås"ûüú™Ò!t Û4èºbšP†:´¡X…(”*š ‹jt£¢ËGRˆŒ´�a:©JÊ:„•º¤¥##[{@ÓšÞÔ¦<�,-|T¡Õ QU Rq£ÔÉ0Õ©M…ê�èBÕªZ5®°j¶J¥®bé«^k ABÖ”ÿž5 U«¨ëÖ·¢v®w±è‚îšQ4éu¯|ë«"þZK| v„5¬#[-Ųµ±3},d%»SÊV Cm_A2›0:$µ³áhC+Ú‚¤´SU-jUËZÿ¸Ö«TÒçbø‰5ÂÞ–¹�Iá:{ÒÂ÷·ùQ­pMCÜU×* ioDJ’rĤ‹AiY¥K]E‘ 1vû Ýpw§hH±ŠÉÞŸ„÷(æå,zËÒ·×½ô›!jÑRL®ÞW@°•-Ÿ”RÛbhº×Ñ-”làÒ"82 N�Õ8ò`¥D˜¯ök…[€çFWu,ÅŽK;bc·Ä'Ö©ŠWÜÁûäÿÅ"‰qTLc²ØøÆçüXGtW«ÏÇ?P�÷+Ö"ûóÈèQ²~:Ûdª>2Q&Í”sPe�\Ù‹ÊenI�›áÁṅsbÉ\f$ŒÍi¦ÅšSÌâ˾y¨0þƒJjBg²¨çÎ7&MŽÍ·ã³ô¸µ�þfô 8þ.Œ°ˆ®T™,ÕÇJªEÓ¤+ý‘_4Ó[nn—;�dcè‰øp©+Aîr—ˆtY5ÈxS¾º£0Æ ­g\$\·W×Ò䟱êgÎÕçŒÁ>d† Öç!¥2ÿ•‰L’=²e3ºÙN~v‚­*í)S› Ö^¶­`áˆé¹X¡Ø‘Ñ’±d˜üäâÿ.s¹WÎrt[EÝì¶©»uçŽÐAÞ4©u½;˪Ä$ßHÙwDû­´[/à�aÁckð£ ü¶ � Ãùâp¥6zª�~L´'4í¼B˜¸×Îòr³½ém‹AZ[ùYJ~r“§<Ä,�{%\®˜w°ÝDEHÍ9"çy+5Üf±·–}©=óºÏ¾VŸÑAˆtÍ(ý2Är�î’ð¨O=‚UßÏÕù�ulý5] ]2nš�wüãÜùŒÔn¶·ýí –{ËŸ—îUǼ3OÈÞsÐ÷œ£×RfŽÏó7¡C”èI[|ãs¸t œòP·<†ˆ”ùɾ|håÄ'Zq«áò�£ûÿ‚IaŽwä*ù·×Ψ¶›üQP*5d¿rºƒDÝ�Ç{�i�ðn6*„Á‡ÃMÅg>…�€ ˆ|5°x¬²|ñxy„&OwVQ ——Õw×_ÚeÇuSö}~wuQä7x§X©—~«·~­×~îù!ôWnö÷ø'q‘¡üWþ‡ÌÑJg1€QQ€…§o¨€ È€x H=çCGáeeE1P2 \Ø…ãÔ&h�45SG‚baÈGÿW´C;ÿõKp‡ƒ”(�M¡aCpd/±+oÕP‘%1ü†I|¤˜öxq�Kz êÿR8JG`O ±ì)Q4Ò°‰“ /aæ1iÉAX¶ƒ#/A>¡CSUM?Äm„E}‘Ñ…^x»’†6D†a†tƒ†„HL5°†4цbó†qxŒ/4‡DQ‡Gq‡ž–‡.%|؇СNƒN…8‡¸�7Š˜Œèˆô”4’H‰u—ø1™H4›( �˜ŸŠ> ŠOAŠ–D2fqŠ–“гЭ¨H°XV²´È…_¨!¸ÈGº˜¼¾ˆ�ÀØ waÄÈƈŒr˜ txvÈxøÒØ&}H ÕH<‚8t¿XF†˜\ˆè�ñ áøˆë‰o4‰ªX‰èÿÈ4˜hšÈ‰žèò8�S6ŠYx�¦è¨XHý8…ÿH?X˜RùùŽÛ†) Œ Ù�IcjˆY‘‰‘¿¤ŒVÀŒ"áŒÐuhјÓøV%ˆ×È•À¸’ÁÝèߘd“ãXåx“瘎JÑëXíH•g� H�Na�ß„�e¡�BÃ�¾±Š¬x ó“o«�P©l³X�i ‰• U†ot† –�I#‘YA‘Äø_è�pØ` y¹–‘Ñ–õ–t—¶–�Û8pè’²ˆpÔˆ2)*4ù6¹”�©“êÈ“ìè“ð”òȘMá˜ô“Ž�”€¹|Mÿ©™OùOQiSšµ1še”•§Ù‹©™’«é•­ –·›×1›ÄU›·™›Ž’2’¾y’Ç'Ÿ5@—`—ʼn—/y|9=Íùœ•9B–(�ƒÉ…y˜Þ”ÚÉÜùGù�û¨”Úx|S~‘R•¡Zç9•¸ð¢0£/Ú4*— Yš»øžŸYF‘,_IŒ(›¿Ô`Ý÷\Mqdj LªK¾0 ÀnÂɒܸ y¹—É)ŽJŽ5iŽ"q€†i�!ŠCY�e%Nh!™”"x¢ƒ—¢4±¢VÕ¢)£xŠ 4Ú6Jš eš€šH šÁ˜@Úš­3¤ùY¤Äÿu¤Ü–¤²¤MªKPŠ’=š4ª ‰Ø ÈùFÊÙ— �_Úaºkcꎊ¢˜Ï—ÉÑ:jš˜HÉm:…p:vX5*z,ê™y§y£{ڧ퉣 ©£[œi¨È2‘‰:}ø)úyWŽzv*©³!©–कZ —z ÚH¥Ä¹©Ç ŽYºœbè—]ž`:bª¡‰¢ªNw­Z#¯š�±j ³ú¦�”™Å‘«Y±« ÷™´ø«ÀZ£Èz£š£� Ÿƒj ?º¬ˆZ#ŠºGf¤$¸™Ô:Ö ’lYLš­”:+Öh©6Š©ßZ—-ɠ㪗 ‰\êœ^º®^Юdº¡yÿa‚•1¯ÕQ¯‘y¯ùº|µÊ¯¸:§ºZ§×±§{ú( £ÁJHK£Iãž »£ Û­Ë ÌѬ³ñ¬bQ±�z±HÊJÚ±yð±Ú*²&¥6”©){¥-;“/+¡nJ¡-*@í¥øÌúü´Õ‚Ôf¬ÔK-Ð@йl R€„¢¼èaÇé;MÑ]íÕÖ1<Ö~ý�8¶Ó³+ Ñl-¬*}›MQkà\ ¶Øy}É{Ý×м΀Ýî쿣ϥ\§ž‰Íª„·ÐÜM›(Ž=Ë�Ý@”1MÙ­Ü×ÙëµÙgÿ1•ž­Õ[ÚýÕ¤-È ]Öª­ÃÒÚÐûÚ ŒÛì´]¶aÛ¥€Û1 È|�Î5m²ŸÜ¢ Ï<ÀÅ}Ü÷\— FÆÑÜ·ðÜüÌ«�‘Ô ~áÕÍ(×íԖݘ-Vš}#ßÝÙmóÙÇLÞmÞ0ŒÞd-Òz°ÞiÝÞî ßÑ,ßpMß3VÛ· Ü—±ß”vΠɽý×sà‚-ÜÞӞň­àÎàÌíÜ’á nŽáÏcÝ^Ù�ÖŠË=yÿj´{�n áM[- (~Ñ*¾×,~ÚÒüâ¦;=îàî- 4.†³õÉQßiQø­ßz-Ó@.ä!ÿ ‘6]ä8]pHNØK^ÏMN·Úm{âà~ÔnèqÄGœåD�tæ^þc`åbŽ+�{æi>kÞæ=Ú+nÚCŽÚt~­ùñ ¼ÞëwÞÜy¾çéÓçdðç9nß‚¾ã šÛù6Óþ}Ú‹näŽ>à�~ŦÌäÈíä<æ"�éS®éUþãéð ê  êDêHwê–¯c¾¸Gû´®^ââ Ú²þæ†^ÚÝâ=šÚu½îë¿ìWYFÄnìWăÎãÌŽÉAžÎ·í�ʱKÜÖnÜØžà”¾ÜÞÞΧŠržãNîæŽî¼£î–?zÔmC�v YÄÿ­Á /áD¥ZPrž‘Á]ÐQ4ò·dÖÛÅŠK½x“Tx6vJÁªµ+ªÅ*¦R~H¡p¤Z)yS€½á¤Ø× ¨–j -±Ñ*Í´QCµÕ*ºè2Øê�í#úl+©8ÝZJ¬7�~¡úrÚ 7ö|¢n9¥š{.*é¦K®Dc¼j»Äò‚¬³ÐÒH­¶Ü‚K.ºêK=QøòKF Ü "à „M(³ï.ühÑ�2²Ѩ5‹Úð®Ï>óaLÑä̃ Ó6œÈA‹œ\ :gkÌÂVÑS%‰²|i¹¶jDÚÆô¡§©ƒÿdQFyqôÑ++yôÑ££ILc¤ÑF¿Û1<¶Ær.!ñúH¯"Õ+*SÁ”dR-9;‚R)§$T¤üôó3#.Éðr³ÓÂ4´Ì?Î$M0Ã<€MSÜT„µ図N iÃSÏUøŒh×P ôC!é3QöetÑI�4]^*ýåRVãµnÓîr¯GQË+u"�\/S%x5>—"œµV[«Œ”Û^E"X1É$ÐL4LvÍ6Ý„6Ni;¢;I²[m!âÖ[¶jºéÖ‘ÆE FsÏewÝtÝ…W^œ¹¢÷Fï̺W¼õ=ïÔôŽØÕ‡šì˜£ƒW¶U8\­¼’a.†ÿx¡a'.¶b®^6cE²Ìrc× †íã�EºvO”T;Д�+UÜ1ÉÍ.æFÓ¥yR›_Ìùo¯Àª±^O3âhò‚:Tý]õh÷Ž•é(�NX2©u%k˪ÙúR!e³vi c‘ãf›,²'¯íjï™íÜúÜ<#”ç Érº}9ÑäÎEWï+ÙíÛhÀ“×NpN{ÖÑpP}LœÔÅWµ:L–|é:šÞ×>…§¾³Îçø!e]#Ò¹öšY“Wo�{Øó¨pölÛ¶]KÜáÖ}¦}õÎnØÁÛð&µ7JUêfÊËYÀl¤´@‚È[†°;§M(¡à࿲ÿ0Â@U a–ž½AI6OC&\ø(Ž�„óË�a:B“<¨é3EA{x ÑXç@yæ†à2— bñD(bð{*B\4a,Úè�KÌKŒõÈÈJÆò ÍxÆy)é�°Êˆ @A�XPŠCšCQF�0„2¬‚ s8¶¨$,€ 1C’° 4´!Gp¨Ã…ð0‰Mâ�õ#:‰>ä¢K(y(F€–C­ˆEhQ,KŒÏÆÅåaŒgÂ#myË¡8p•lŒà-RÁ·ÌÑT²±c-a¤ÇÁ$²„8úcôùB‘|d¤Zn8“ÿ^l‡I Á'-ù0Lq“=ì¤F>Ê' ó.¦Œ *UéVºÄ•€€å]Ĩ2>—ûäg«Ü³F‚¹Ž�ã(…¤ÁbêIÈ €2ûÈÌŸR+d¡4CEVS ×,B6#ÓIú0Gfù&dè3N%–3çD§:?:’SfQ•ñÔÈ<ëIÇ�ÌÆìgO“§KxòR ¿Œc0 ŠS�${ E¦CýÑ9<Ó£¶²(/0:C8•­‘ux$•hÒŽ %½mPªÒ•R�‚p)ËDÓTΔ‹6]HA¢SžúT¯ò*‡J`^ð¨ÃLjšÇ¦òñ©ŸJáDYÑ^Ôÿ¡åèT¡6°†@¬dõjcΪR–†²­—}k;eªEšf„®°kNñIËÃîU¶ñ"Œ"á#7²¯@Tl­Róš†:¢Œm‹Tmõv]u‘YýÔF‰Í²‚”››=Oª‰$^¦Glùd$¼û]ú˜Ô¬¦5D¶¸ÄÕ¶V–zXàlÝûÁØ>¹ÍH�þÀÛÅù6¶ÇL¬"‹Ââ:šSBnº”KÙçv4º˜�îH9ûÒÒf71Û�Cw¿ëÝð.¸´WÄ¢yW9WŠ|±®±„R{ß{âÕ–„·¥oì‹_{~D¿KE¬…[–f6–¢ö)ð¤Ì\è9—«Ðí,ƒ“H]@Xw¼ÿv …-|á yèô0¡C�¤æ6¿yÎ'ÄóžGèAºÐ‹î¤'�KK“ӟS]óÌŽoÁÑÞ-:hÝБa¸ÃKq–”½ìgçXÚÛÇöÀ¿ÝqŸ»†\bw¼§|å%¹Œß]ÿs ›`ð4¿ù) /ÄïÜç‹FãoôÈóAé”·|Ó¡©o^ûI²: A/úÆxµô_?}Ø-.ÖÕ[í]÷eeO{”Œ¼î%çHîï¢w¾sûçàé#’â£�K¾å[<ç#…Ç# UX@œ¾¥«>i¸¾_ȾíÛ¾0ó>„�­?°‹±C?²#¹²a?Yk»Ž+‚�û ¨=4¹ɻݫ´â¿þ ¾ÿ»Á‘@Ä+@Æk¼ lÀÉ£¾ê“@ ¬ÀÍ»À:û¾± Þáº"ð:N Ô£œ8ĸ×ã »¸‰¯BA¸SÁŸ¨½Ãàú«?HC?°˜„À¿ÿ’X:ý£A\ð?¬CL<¨`¾æs¾ € \@dº"Ä<ìCB ì¾%ÌÀYq¹�B)ü­¬P�˸BlA+d».ÌDÌÃÙCŸ C¥±;5\C”»¿„Ã%’Ã9´Á:ü¿;ܹÛÒÃìÃ?Tv¡<€@w9BCœ:%ĺþˆE4‰'¿)Ä Er6ÒJÔK$ªµãÂAùÂ4Ž E6E5dC„pÃ@ÅËPE:lEWœP8GtŒEæcZüÙ)žš©^ìÅ€ûÅÏSÄÊ ?Òë:Ó Œd\1ø˜Ä‘*»gT»ö)N„¿ �¿Û;CûkÜA9Gr¤ BÇÿt„=dG%©ÅwÔã‘GzÔ<{l=&üïA˜…ãGòóǼ-�Ì‚T©Kì3®«F¡`Áù#, Ü;ÞS)qdÅŠ‰ª¨ Œ<ÇÛò:¯ãH÷ðHâÉxl‘yII+ɲ9É”,F–ÜŠ€ùG1 ÈÄhÆU(È-ä8–y?O”»ø£»†äÉú{AÝJJ9Ôâ¬Ã£¤Š¤…¥dÊNpJtǨ¬Œ�¤J«ôEDF­ÌG•tÄ~ä¼0SF^bÆ� Aš„ÆƒÜDœ¼Æ¶´=ŒëIÓéÆˆ´KÄ˼¼Á½Ô…¾üK¦L $Ì‚G¾ÉÄ 8åê•æâ¨V<â@‰Š!ÿOó@‹Á‹ 0JHNåÜælΘœ'.¼ÁÏX C¨NЫƒÉŒ@¥—#ïÄA) _ÏÛBU|ôLÏ� KhO÷”ŽŸ`ÇtI¶Û¬OëÈM.ÙÍëÍßÜ€à¡á̆ĸãÜ.å\ÎædÎçÜ·èü¿éÔ‰ê4„ëä¾Î Ë2ÜN,êÎï”Î…0‰ñô…ò\ŽóLOô\ϧpÏ÷Œ¬`ú´Oå üFV3(éìÏÿ€}“ˆ3Î.1Ð¥„Uб4 èÜ ð\ê´Nì¬PíÌît9ï$†# ñ$Oø0O9$Ñ5QZ@Ñö„Ï«`Q€{Q2…Q‡ÒÍ ãÍ:ôÍÿñÏÿÌÑg)Î�,ÐùQ ÒŲœÒ$•Ð%¥L‚yRBˆÒ)õÐñ<ÍR-åÒ.õR0-SHÅ™E»-þlÓ…S±º NèTO¥°L ÒMÈÓoâSUR T�TBåP*­�EÔ¤Q• v©ÅG�T]Å”Im½J½ÔH‰L½6ˆØÔÄðÔOÝ®PÅÓ!…‚"ES-��П 4±tÒ …Ò uЭR_�U¤ UõŒŠ[ýÃ\ÝUt-‘µ‘ÏSŒùXÓæ(�a�‰0Ö´CÖNÕL2¢˜< c1rìSjõ‰�C‰eÌß#r4Ôo áùHÔÏG©Åt­XÿYW±h׈`] ŒÕ¢DY‘µ×‹ÀWN°"+ÚW~mVýW@ØSõS %Œ”8ØHØ…õÖ‚ˆ¥ ‰�Ø?´X¡e��ÕXޅ׿øXÙ‘)Œ3Y”�•u„~%)—…YiEÕjU’š­L„õ½œ…ÕCuX™)LŸýY^ Ø¡]Ûã(Z“t×ÅèX�PZ±`Ú�%Y‹€Ú¨�Zº¨Ú±ºÚVØ%¥YƒõÚ›ÛVdØ�íYIA[µe[ÈÝ ·ÍJ¸íˆô¡ 6eв{'»M¼%½EY¾� ^Ž.~¹@V_1î• öàNã>b6vä‹€äÇ�dö d®b<žáL®eÈ! ?n9ßûäõd ö¶PÎGfbÖ;½³÷ŒU^å†@aWÎíE[^Ð^[®æÃeNþã]f!0cxfbfcV9dnOe^f2`å8~âžä‡E[j¶fy®MNŠNv9^Æ`_ΈoNÎpçq.gK8çeVç„xfìˆfxžynè4r��Ð{&ÿBʤ²ƒ7äôçgFh‚Veƒvâ‚€âW~çŸ�g‡Ni¯T’ˆ®Î‰†@ÈȤO˜išÆh¥„~ŽöèH¹7næ…h¡j„¾…>i†Vi¥–ÌÁhiCxéê‹i#¢éš¶é¶çpÞé)IæžÖ�Ÿîß j¡.jë8j‰Eé¥Nk¬Ø¶nëNº=Ô ú(>ªžéV¸k¼æ5œ�Kèk¿®ŠZbA;²#ÀÞ/µNìžjk·æ"¸f>¹¦ º®k¼Îkz³H¾öë¾>lÁì¤(lâlÅ.í½bl¶~k‹ˆë ™ë›«ëO¨ì»ÖkÌ– ÍÞlªìtíÐmÿÒ6mà–-§Æ8n à£5Ø–íV íÆÐ Û¾„ßΊZ$lßÎmÄnìF£áþáâ>nW#G:tîÛŽn¬¨EíÕ^òÎnõÖî–&nnònvïàoÍNï¡0ïó>û^oþ§F»âNOSûîV ïÌÖìõ üÎïEIðþ~p$ùïÖ pôðø.ðùž1=F¡Xpwpqö�ð²¡ðg°pÒªH—� ‡DððüqŸñã q�0qOͦ�Õlñëþ ?o§q"ß Ï0Z“ï»xîŸÏ1íð?dpFò"¿ò¡8òHrËJq&O'ßKïl)B*oðÿ(Çr5׊H»>xs8WE=k¡~îä›TA•`Øs>_s?GB7‡ó7—sæ£óF°óäËs½àó>ÿsG×¼@tB_¦j2É©ò3Ð&£¬°Ê+³ èЇÀ¼´Š2êgÿÙÌ/±ë0ÏŽztÐ"']´»Gÿ—´ÉL›­œÓÜbì-�s\uÎ?b-rÏqý³ÐCƒ-«Ø]’-òÙ�Ç á…ûrø~b@±8ã¡8þ¸Û–Œ d$çQ×–›¼–5 ç�ÔMaˆ>z[¥_Eê©¿[°à­ËV¸áˆïÇxã�;ùä@Z^D“ugÄ\ç�Ó1<ñ¡�.ºéÉ�ºêÒ²î:ôŸÁNøá¾$Nûâ¶ßîvî îÞ»Öü(ÄÐñÈ+_:ó¨¯>rôñ/6=/Õ_�½ö¡ä±ÿ?ÿÝGòùDÀw!Í9%q‰3ßðŒw¼õ±¯}ï«Âšä'A¼ÐÏ~³ÃŸöø×¿� €^`…<Âî�tP éx::~|áXêSAÙ)ƒ¶ÓàþüçA¢K|e!¡LˆBõ©°!í#Â#Ã%zE†Ó"ö �?æAøâZv"ƒ…ð"#$¡Ñ—¾"ò䈀âÓÈ•úxˆ1ŠÑî¨hE,VE‹ ââ„<Ø. šP:é CzNñˆA²�ƒ4c—ШÆE.¥�$|c~âˆÃ9#‹ä¡)¤Gvñ�~L_ )ÊG ²FŠd$*�âHBò’Ô %-ù9LZDÿ“Ü#=É›?†r”… ä&‚)ÌS¦²˜/YeâZùÊ šàŠ•¬ã%·>[~—ì#oÖÓK_˜Â &1�)N• s?Ê´œäLY…–¡&P¬y@]ªF›éá&!½ùÍpŠóDn¢–罹„)ì&‰£ÌîŒÅ?i0´]‘ñ ¤j’¸P´¢@”Ž&2ªQQžÊXÆbHCR=�4 Åôg’>è t` 3è~j9…î�¡Òpè_ '‰î§¢%!F5šÑSuÔ£FÝÑHKºÒq¥Réã×Ò“ô �LBµÐ†²ë¡Œ(M&êÓ\”7B*Q}tÔ£&U&ÿM¥S9Õ.²´H=LÅ ÓóÐ46ÅiZtº$žŠa¬dªYÏšVµ®Õ£m}+*ãZ˜¹ö°®ºk^÷Z�¾þµ«ù#X­ VŸ–U5gÕÄbÔXÇ‚”¤n]ê8%›Ê*Ѳ¬UcŠÕ™jµ¦\…Vd@»Ó°öt¬¥¥ÌiS{ Õ~´µJ�*S+r¢DP·º¶2d—6UÜæ ´ÕQ펨ˆ‹ñÎ*¸éka {ÜÉ$W¹Ì=”H�ûZØFÖDÕµ.˲ ³íº´ªÝEìt¨Þˆ—¼²ºI+ÿˆ^âÖ¸F®bÝ{(LP¸ÂÍ©kéÊÔéÞ7GÓïËøKU¼Ä»^nÿxq8^\”÷ >/»Òë`U¨Ê5�±*laøÆ7ÕE¥›’Öaç—¾!.’¤òFâÿÒx·Ep�Y,«êUïÅÇ[°h÷Ó®kôÆ�ø2˜“!æ1ë˜Â~ì�ä¡ ùhœš’ì5ÿšøÉ(&°Š L*ÎÊ£Ãrâ¶œX+Ìa³˜ËŒ‰3ËWÃjN’�;ìfÂÉpRrAê å®íµÔ¤&Ù:kII»É7ƒy“ÿ<4²V—›2Ô¤`§ÔD’ò`o²00›Î^lu† íiS¢ÚÖ¶çuB€=eëdÓžv Âÿ-îS9Ó™Ï87ºû nÊ¢Ýx·³ãMQ§u‘Ä~}!ZG N‘Éõ&víŸ^Fß�"va†�ðÉNÈÞöA–Ýlg[-Úß‚µ¯-œ@j›vÜNÈd.>„—ûŠèN÷º'Ón@¼ûV3A½ïý¡|<üÎ�¤þ�k�¯‚àž©yžð }¶ _ÒÃ=ñª0 ñ®8uDžñjc8gÜÇ�0‡?ˆœä%?ù¹ÕÝv»ûÝ/�9¾çô›sˆ:ÿ&Ï}Π]á ?QÎ’ì¥ë¤éOϙſ½ �Šã7ˆBþ0‡#t]¹%F»ÄNv–›=nhŸ¹ÚkÎöÿ¸ý ÒxÜ]è뚻ɄGû§};|“½#žé'Ô‹0øÙ¾L-oùÕ÷ñ­�ö7îðƒù”Ïaå-?{ì�vy­ÝDEï¼A¤Ã‰éS?ô Ý“dz–¡¾DC^ýá ²š#ø�‧í}oûÛ ÷Pà¶â¢þÔ_øì’¼ÊËîrË'_梹Á%� ¹ ô‰oP_õ¯‰^ÁÕÜ�m_ßø‡Ýø)]ôM„B”ìÅÍ�¤ßì� ûµßá%È-^ï}`ZUXýßð�]þQÞþ� ½õßòa‹šx�š AHr‚õÁÚÜI¤ÝF  }ŸÞa�tÌÿ&„¾\z`íùHº_¦íÇü�(Äü�Š ®` NÞññŸòaó �î ÝÄçíœþ²Y‡aß$¡ê-!íH‡Ä9�ùÉ`™Pa"ÈŽ ö†ü¡ Q…aý�á –!!Èåý_æ]È¢LšJo\ -àõ)FœÁIV—Š R tœ ºž n`%&ˆ!:²–˜v¡:"RØ v‚$Ÿþ!ßbb®à�ÃPv"|b~Ó(Òa)&Æ)Ú!Eà´buÝDy¨F þ]-N¡!æâíí"“1b#ÞbA¢ýA þ# "N£ÿmÀ®0#Ò9#Bc4¾¡ç…b®UcÏÕ!^d#‡¤"u­âÑ€#u‰#,òF9b�â-ª#î)¢^UÅ–‰<²àýŸñU^-^¢>ªD@!ù,,"*žüÿH° Áƒ(\¥¡Ã+#æ˜H±€Å‹2j¬Ã±cˆ� mˆI¤¤É#(S’YÙ ¥‰—0-ÈlAó‰Í›rêÜÉS炟@{Š€’ÚY:bÄ„§>H½Ø£ªÕ‹ùhÝZ¢«W¨`ÃâKÖªUhÓ®$s¡mž·pÈ� ³®Ý¹sÛê½`¶jĈ/ þ ‹a1ˆÓ(Ö ®L L"7™ Ô�åË<2kæÀ¹sØ B‹&@†i'¨SZ´µëׯ2tØ�ðби±#G�!GŠ4y2%ʵ-Ø5ñ˜f‹›8{Jß¹ú'Q‚×MJa©�¦`¥~ÿ ÚWw�­\½výü™lÙ¾iÕ®dÜ8^¹Ë—ß°·mß¶ 6a†a�˜Š¥A_c�EÆÄdMTv™ešmÖgŸ‰6Zi§¥†Zu À&∱ɖmµ†ÛDæñ–‘o¿‚pÃG„qDZä’]ÍÕÝÓ‰ˆÙ TdAÛ)Å”SP‰GžYæ¡§•zë±–{cýZk-×}ùÝu_|õ €/ØVà� zùVƒ’QöÓ„VÈÃ…†¥ah¤` ~X‰„:�‰ È¡è¢4Ú°b-ºc2†ÐgŸ6Þˆ#r;ÖÕãs? 9‘< UjQIv·dxSYôß°Æÿ*%T– Á­¸>ö–xh¹e—nÕ·_˜uíG戢™&�‡%¶X° Êä „Nhç�xf¸gŸêˆ††;âä–»(£4>)o“Vz)i™âx§Êñ8“�Љ*©;™Ú/ªH)ù“O9éj_±Ê*%® 7¬ëÃ�ù°Ôg˜Ä¾dlAtìq²hªÙ,‚ÏV\œʹ�\‹'ÚjÈm‡‚+îÍ­•kî¹r4ª®n.FЮŒïï¦:Öëé½ æ«/Oüêä¯ÔsçxM¶ZÀ« Ï1kÃ`k1ÄËÇ´_╱ÆcrìqÇ (²�Î*ˆö›ÒÆáœtºÿœ­žÛrh 6ãl¸@G  3¹<÷œîŠëöæ›»ïâ`ùåHd®ÒZ+-ñ�@>M]uGIPªW<�yVâz×sd.;a;<öí2m©ç+Y<ìÚsáJæÛp›¨¬m˜`‚4ïØÃBȲßƼá¥Þ‚ØÁö‡ãœøâ_4î3ä@K #å—^޹æ9r¾ÄûðCìÂüôƒ®/ˆ"䯿 ü÷oú@¨[TXW×v³Ë\í†;Ü% ¼#¯~—±ý8Ç9Ä ¢À§¬äfyŠiž§«èM(LáVÈÂk á…0œ‚ gX´$Øð†ÞÚ^ºw³ï-N|�ÃMäÿ^t>¢UN}8�ÝæÜ¿÷É�~󳟨ð§¿üõϧBHöÀ€LàsÕÀ±=0‚ÄXïsAšdpƒ‹ë b”B’ð1&lB UȺ†/œ! ßuCJ‡<—uDáúÑNª‚ eXÃB&!‡ÜK¤¡¹³s5ÊèLg$%IÉI^“ Ó$•ؾµ€r O„"èöÀÿÏ~¢2•ªd¥\IÐWfÑ(²L]mY@\&L—»ì%ÄÎÈ;^‘‰˜-&�I<8êLŽb ãò ™ˆå‘š°æþÈmN¡›…çÅY(r2ŽgçL':× Évºó�jÈäÕGOO2±‰ù¬ß�úéÏ’ ›-¨+³³E¬=Å‹`Ì¥#*Q]Q”síOF3jÌ "S6Ê3�IR“N“š*ei · SCz‘4ÕbâŽâ†¾úµ)3OKXØù ›„Ø~öS�Æ>¦��l TÖÆüéO:Ȭfmcñˆ   ­NчҚDÜáŽV;†ÖzV*„…!O‘œ´ÿÍÅb;€nwË[Ý6ö·(‚p‡ÛÚâŽ!h¶± T’ÀûÜÐA©y€tCD�…dàº'È®f Òj~B/^d’Gê0­P!lgRâ�ö’E4ÞLè KEîU~ý«UKØÁÖ§‹ °€ûØÈBv²€¬,\.kÍn–0�}mhE;ZÓž¶:©MÊj%PÜ×~ ¶/œmmß²ÜÖ§·(>p;\â÷¸.J.a–Û’æâ幑‰ît b]ìj73Üåˆw3^ñÎ…¼&4ïöÐûõr†½î |½9ß©´{÷Åo~ÝØZb¥¿þíÚaLæûX&>0e±„6ÃÀÿÁ™å¬n<µ‘å"“�üàq Lz»^”´wÖRMÃGùð%Râù¥øê,#Œ÷Vãdæø»”ýÂ�GË« $ùœ%<í «|å3Ð6·Çàᘇ{Ð$¾�Íó€óD¯XÝ<ïù ~þ· ýÆDϱÑw\]¥ã›éúv:¿¡îo©œêåÕ Žp®?ÙëQƃhÆŲSíì|í+`ÕîåÎLŠL‡{€å~)ºÁîw”ÉÈõ~iO8å|à3ìhñt&›É7Íá’œ;&9»ý-ÿý¼ùžk&"@·|�‡ž„¢;áèõÀ½A-ê �z¦^ªUmõÕƒï3 {`'{b·bgefÇC‰£_»÷á{0|o'|‹E|}b|ÈrÊ—wÌgÎGa:UmÒW$X‚Õ'×§JÙ‡x�QboÑ}£õ}-~�5~�²8˜ƒ’zèWy—gi™‡i›‡t�—žFMgO‡Q§S7U§z«w €®k¸p´G?¶—4µ€º·{ªSq�¾!�¼E�èX2Ñq€”�%õ0Ë×�hg~}€W‚&øbÖÇØ·‚¾£x/ØÞàç[58?Þ’ƒ:(yçÿé÷ƒò„ô–tF¸tõwù·×WG…ˆa…aÐuGðuZh€d‡€·§€¹×k È¿×Á§†xa�¤��aÑlrÈ�;'·I4‚zX'ø)H+8sÂ"ˆyƒ:%ƒ @ƒ`ƒˆ8¸ƒ�x‘¸~˜×~š÷~œÇi—øy™¸„›ø„QE«· (¢HЦv ‡Šúô#Gwt_ØŠb8†kW†²�´8�d¶' `1¸Hº¼ˆw³c³;f0‘)Œ DŒzxŒÉCˈ�+Æ}„ƒ†8ƒˆX�ŠxƒØ¨�™ÑƒÕtÞ„à(„âH„äx„ù¶oýÿöoü'…ŸŠñøz¥{³g�Jù(]û¨e®È{dh†�†»Elé‘ðn¸l»rqè�²‘<%‘9‘9;¹‡ÆÕ‡ð‡ÙG•¿’ Pˆ`qˆ*–ˆ.°ˆ)éˆ+ ‰>ø’““•X„6 z8Iz:Ù‰ŒDÞüÒ1�ÕrAÓEL´ç,"8].ƒ·uapg‹"BˈyÎqíHŽ,Ã2Þáåj‚Ùd=¡1pÂC&m±ê¦PA�ÇÖ†FPÚ¦�¡$õÌ|©“�m4Û”Å5)Ÿ!B01ôã §dÀ2‚±0t ÷„bŸ"©×‘Î 0Û"/æA†–TóCl@»'¼²IyT8°Øä2ØMÿömªtØ?­ØøR8 ñØtÙK1ÙÙUÙOqÙ€£!š}+zAÆŸ} ¡]’£�l¦}Úh‘Ú±ÚoÍMÛ²ÝÞ´ÝZ¶ ¨�Ûr±Û‘ÑÛJÜ�!Ü/DÜ dÜLƒÜY¤ÜÌ-έÐmbŠE�Õ­!×�Dyt3ÜýÞýjà Hâ}ÇlC‹mæ­è=!êmì}î=ð 9ßPß-÷-šù=—Àõ0Ðߥ�Ú¡ÚÎÒ2là4Àܵ #·Ý<>În^þ>ÞDn"mPfçáÞÜ8òÜcÝ£†'.)®>+..-þâ€C3þ¹6^Þƒÿbo:¾ã–‘e?äCE>J›}öÍhp)Úlh•RnT^V>BXîÚ~m±½åsÞå¾ñå Î6b>?¼MÉÛsæi¾æðÓæožÜ8ýá�âX1â¸Uâ‡b)PìÆÞç—£ÝI¼‚�¿„�M…Þ49žök¿áèäÂÜ–íqñ-FŽäP�ê–éú½é¤-åŸêCàZÎå îå æc^æ:Dë+1܈QܽuÜѬë÷«¼þ¾~Àn1ÂwÄnìÅÎ+Uðð¯ì7ÍìÝíìßЮ(ŸœÕÓ~Õ~í–›í÷õèZ÷ÞÞNä{îmqé-fîN¾ßQ®îÿÿ]å~å/ÛÚòî©ï«>ï®^ï²þÛtÜù~áûžáý¾áÿÞá»>ç ^ç"~ç$žç&Þ[ ßðXñŸèèð Ðìš<ÏÞ?Þ@xãO ñ "¿Wié'?Ž¹Í¸Âòדó—cÚ‘A³ înê§ÛÊ¢÷gÇÄ´â 7¡C+ðø—R0”ðCa�G&„m«¨è²áW‚±ƒvîOõÃnõWïðZ_O"�nñ0Žñd/ÔÐñ8Îõ±ömoS_ ,Ýþ†O!÷\`c÷Â…÷.Ùzo9|Ï~ï"€�ó¯-øƒ_ø™qøÉ‹QŠ¿øLÿÐøÛóø+ùË„“�•?—�dÑ£ù^h‰ áù�úQÏ+î‘ð·ð ¯,©¯ú¸$Xp`€ ~a(Ááˆ$†¡8ÄâE9!l<ÐÑã�’$iQòÉÉ)UDØ2€A1e2¤ùåÅMœ'\¼¨sÉOA+ %ªÁèQI•† YÄéSQ¥êÔÙÀ*Q Y³ÀÑÕÈ×:aŒ�PÖì´yÔ-Ù¢ÉÛqiÌ¥‹'¼aëô”¸Ñ/¦ ™ &|òIÄ+;`l÷¦È�Lþ¹Ïe�Zµ¾åÜ$î ¡ *$�ÀÍiœ'T¯.ÐÚõeرakÎØöÿm�SìæíøEàÁU®4XÜ8BÒ4J€8F'Å0<-f”ã7wG¦#Ûž’¥Ë—eάiÓ±NéC|JtèQ¤J“Â7êÁþ}©S©N°Ú«f®¼K,²Ì* ­ Ôʃ­’8ûŒ®ºË½øšà¯�l#¬°“ë@±sÀ7ÈÄ�Œ²Ÿ`ËŒ¶ÎàŠ+4F+Í4ÔnZ�5×Z“mGùæ£ï>üò3`?þ®жqøÊ½ÆRÀÀÓZ˨¶”ÿ B|›°B‹t°À6Ì0A‘ÄÈ,šìˆÊTìÈÇ={Q´‚f¤Ñ�Ôn<Á7e›Ô¶ëÒ©$«0r7ßr]ÒI`€2å¦t®Êè®Ôˆ#-CÒ®Ë'~}<1Ç+Ó74yR“M7+ Oƒ8Mø–Nûì¼s¿þþÓªÏ?-Ð@dÐ-g`´Q ó ËÂY+µÓÄḵO5EÌFe±ÅÏ`”±´ÓXµÑUXc…­_¦j½µˆ\wM¡×$¥ – aÌàd”ÙPY'sõÒ 66TКkvâf‡GÖY 1QD<³zè?Ifµ|4ci¦'œ� ¨Ñ�jªÉ€ÿMÁZ ÐzëO?%4‚þÜzëRA0ûìå–›P'—ÃÂ3^µÆÖÚ0Ã0°Û ¼}»bo¾»Fq �Âmk»“rv¼ÒvÈÕWóuº¹æÈõ€:êÚ®£äÐzþasÎß¹IÌ@9å•%j¹m˜ƒB:�šmÆÕσíùgÆ‚Z袱;i¥™^Úi¼¨–�ª¡¾Z­¬åöûˆ¯ÃŽ[î²Ï6[q Ö–Èò· ÍCnè>Én ðöBo¾÷^¾²ÀãZÛDœzÆrˆ$§<#Ïc×?ØÐG?Ye6°ÌN–KV×:šÝÌ íÛ_qfG;ÛÝ.wÉêzç;àñ@xS+Þñò�ÿ¼±-¯yVôZ$½é)ÎzÀÞ~à¶=¹yï àùÊw¾Ÿ¤O>ëk�aXœ÷).~Ž›ýÆ`¿ûå¯�K,Hÿü@懀—‰Òèþ�‰<íA¢ÉÆh° m|÷;àm�x¼ Ö®Ã=Êy0[ô¤G½¶�*/äž i˜7Ç”Ï|~C_G·>Âng=¢]2hD$RN‰[d¢GEÓ uTT�˜EER’‹ãñ"q'FÝ‘‘w´!A+]™A5ÏjmDÞ•ç·6 „uD.”#c$ňˆHÿ’«g“åþ,IºfRŠ›ÄCevEPƨ›yàÏ‚Y‡Û�26c,£f\ùÊ4F�ƒUó ¹†K9’°˜dëåUÌë Ó…Úë£÷þ8¾@îmhÍÔ¡Rx˜Hu~®š7’ßãè'¹mRk�± ÝÙ–‡'©¨A¥ßb›ÒðR˜rŽs¡['Œdœšë�CI€ÄõA¨eºg+spT¤ª±§=]�GzðÔµæSw ê·V·5×B«[E! <é…iVEÚÖžÚƒ2¤U­ý*Eø6´7ÄU®µR lü—šÆ®g=ëhé·×1qs¤;ƒ‘Iý†Ò¨¨T ,m)`S™þ ÿ¯#½iNí´S¡õô§T‹Pû@Ô¢"5©úDÃRGÒÔŽœ5ª˜jUésU­eu«Zíj[ÃÖ°ŒõµeÕÚYÕºVdzÁ¶oš\çz�º^殓]$`�û\èÊD°ƒYaÍvÒý¤t¥ôi¬c›†ÈJsÔ­ltºžŽd³»ËƒgA{OÑU©¦EíTÕÖÞ�¬2ÃjkfK[Ú·uÐ-|`Kßþ¶ lmë2�Wº&Å®þc®Î¢{a KW¤ÔýœuA€]ªhw±ÜmìwÁÙ ‹²¼ç¥Jz}ºÞ µø OŽ2ÊÆì$+Gz¯Xβq¶|Øì&v»ðén˜Q<ÞÁ–9?Ô¬šÛËfš¸9¾p>­œSKgÛÙµæ-€¼U?ÐFÎó. �Ö%C§ÉÆe´r) j�JZÙ1¡t¥ ’ð j2¢¥J J°´Öý¨j� NèÒl�…nIò�¹\£tM ë^ïÐb¤žyh«66ËðLûâŒuÄÆH…B¿ïü-Û(è¬6 xÿÁ¿¶Ìxf�‡ë€RúcDœA­ô.‹‹KÍ6Mˆ1¥qvÇ=>2hÛMÚG ¶N¬�íši›³yèöM¾½á%Š»;äFŒ¹[ƒn-¨›Ý›u÷à=&yk•â°·ii¥ï}ç ßPø7}®–�œàd¾^‡[â8�x|Íbñ4c<(wÇ?~v´$äyÉ%rr3d;0 jù ^¦-Ê|84ï€Í €s�+¡ÝïæM¼3o¯—¥èK=ú’®tÏú(OÏCÔ¥NõòY}} Ïz¶.ñ´ìøIÆñ²qÒ¤]õ_{Û‘ZíkÇ=åsçöe¼=êê]%|÷;à…ÿ¶nÁóœð»1|/ÚzKíÞ�üÒ›Ê[Þà„Bx<Žõ¤<œ~ï:ò+ŽfÆÆô<@½BVþJ·~,Ó~½Éc/÷m³Üö.Çý`uŸÞÛéÜéþýÎÚóŸ� „¡[¼‹ �h¾ÈÃ3製Ê{*©›:ê$º¾Íê¼Ïë>¤ú:ð;@�¿òKôÁÁR?`¿£‚=”£•c¯º£‹ÜÜq£¹Þã¿,¾Áó¹ÂºÃºÄ#:å3ºÀHÀ¤s>É3ŠèƒÀÄ<¾©@§Ã>Ð>Èá¾ÐûÁѳ ,»Ô#A.¤$DÁPAÙcA|Áú©û[¾;©X­ÿ„ÃAܾ@™à»‹Ø@BÙªžÒ ¼¿à·¥ë7 \9‰@`½q¼À8a“æP«ˆ›IÄCq1,»ÓÓB…€¹.ìÄ`ùB’k¿·{¿Ù‹?3¤JZCšArcèpÃx‚CZ‘C:Œ ;´J4 = >‰Zùã Ä~K8Ês£ÜøÅR,Eœ<(T G„HÄ)Iœƒ\ü¾,ðÀÈB³k OìÆO\€h[¿PLA÷[AhAU’?<¸=TÜ"U”VôW4X¼YBZ<™:¤¹;<ª¯ÙÅ$èÅøÅ�Ä@$F4F�@ÆdTƒeDÂfLŠgƒh ‚i¬Æÿ°DñÃDòÓD„ðF‘4Pt» €;ø[¹SLEšë*A”wlèzCÿÃGÜ�Z€[ŒH�$H0È¥CÈøSÈŽhH¤tÈõD —‰¬È‹ôGBÑH±c²ÛÆ�I­T;p9q4I”,E•œ?»;Cœw<›—\KA™Çz < @ÞÈÉ�ìI­ÚÃÚðE?,È`Æ„ó‘úòˆ¤lȇÔ!8LÄLÌÃtÊ xÄ´ŠÄI”ÊJ?Æ´ÊLÄÊðØJ­,IQ?% @ýÑZV V#5V$EV%•�e}Ôîò¢I=« �‘+� µÖ ð˜ ÕÖíÕÿÕµÓ WïÄM�HÕ5m’%I×¶Z×8�Ów­Õx�W_ÜU|µØ@ÔB’CEªD]ÔŠRVeÖfm,„…Ö]ØÒhXxXk•Ø�¥XoäVoÕ Ž-Q�í�5W6E×µTWBaW”ýWxÅÓ4ÑpY…�ˆ“I;ý/@ÀÆd›تIV(Ø&=XÚIاZÒ Z™€ØˆÝ•‰UZ‘dÚŒ­Õ�QSýI©%×¥Z‘µÚ—ÄZÑZwåZ•õÚ1[±M²µ,z¬Q´UÛldÛ£JTª™ÓFÝYf¥ÛŸ¹+/ÂÛMÄT躗ðú[ÀµN‹S25S€©• VM ÿ’ý*“•ÕÉEÔ�×”ÃÍ–­×{[Ì)ÛWôÜÿÝ–jÛ‘%Ó]RÔ5XŸ¥ÖmÝŸQ½,Ù�,Ú­ÝNÜ1%Uà ×Ýíݘ0ˆ’:Í«-YB9#3ØZãíÚ[ýZåÈÌÝ\óŠÞ³�Þ°ÛÈ @*�ÁÞŘ�è–É /ú^ð Á×¥ÖØe”ÙMZôåBõÍÝÃý_ÞU\5e\�˜_é ^èøü½¢”�OËM^t [æåÑ’�ÞÎ-àÙ¢^ÑÍ�.ž9�!Æ�ž öŸ ñ…Ýç*_™:ß&Áfß2 atá(Wßm"ÌqÉúÞû=#¦\îßËý_ö¼ÿ>µaÁa`ýÜ®ÊCý᪠â!¾ã"vš#�$¶àß½rbÎ�â(F?½»ÛZÏ+ÂŽ€�{Y/~Io�$¦�K¾dà¾Øä³²1sÁ߯ƒ ê1ˆˆÃa³-‘åC`6á�åW~eœÃ9#ò˜ ò ê¹0i B.d^æL Dn+EîÀ8ÎÍpdF�dú•äÁ¥ä¥¹äK¶�M¾�NޝO>£P¾ŒQ.ˆRæÜS†ŒT–ã `e‡xeXŽe-˜å]©eÇØæ^~ç�;d‹Hdõ\ä|;æËxäîˆä‘[ßpf3€fK–fN~*O¶Pfd|Æwˆnà_m TBÿqfr–svetNgú¡eà±eÅ�g‘V=•æ¯æç ¿{†�hi—Væ^ËI&ph hj6èøbׄ^imi`ñ»±6¢.�Kl©‹î™�Vg#ag»h葎êôæyæz&fÒÓË…vé—Þçeîg×h›Æéj-žÆf…e v¡†Œ¢¶¶£^åÝXŽèbjÞpjœ7©Þk&*éª>é«Nilô–æê€iµ”éf¦éöëÀ˜æ²Fª³ö�lfèµn’¶ƒ·6jUç¹vˆºîèuþhÇÐk¾>íØYW‚v%êžbFcöÃ>l¯–ž@m ÉÁßKÞ]È~ªÿû�ì8• ¦¹¸ZQk Íâ0—q�ÍŽkÏNº†.Uñ ,NDmìn Õn%ÖŽS× Ø®•Ù6—®ºí&ݶdÞ.èøí£bWá^â¾ãFîj‘‰ån�ÍÞìîJjéfXð¨îñ0íì.p’ìŽÕ¦ˆÖ¶¶×†ÈØîˆñ¶“òÖWÜFï3Úmîíö¶àŽÑø6ƒùÎ�ú6Kñ“ü.€ý~ëþþl ˆ®%v ×0¼3pß™í&�îŽÑïN‚ð¾ŽÏ�å1ïܾpõÎpövï€ï¨î°+îŸ>n'ˆž9ñ/ê‡nÐþï¡ ð ©¯q0¯ÚáHð0Xðhpÿ èÃÜøq©r /€kö ¿b Gr%7&Ç7'·l(oG2qÈ`î*·¶)(tC÷ïçzñ–ˆqf»î0t®sîVpïfpðvpñ6lsqóˆÎ‘8¯ä"§ó#çð÷î%—ï&§ï'·ï*ô0ôCgqpïrëþrHßu0ÅœEøu`÷ œ jçî.°Û9í�eB[8hvgg“Ÿ’õB¿³;ó sñ‘îBmßö5èvog‚@+#vǸ;^O÷NTs¢6co,Iö]öÿrögŠŸº7j§*k·“eÊöm×voÿv`Aœrowú£êTw‡??v7÷ÿw·“xo©y§÷³²÷ÙÂ÷f‡v á÷~ÿ÷üøÆx‚/ø5w÷�„Wxtx˜O»ˆö‰Ï�¯é.ù–9Õø­âx8ðøÛyjy©X¦1y$@ù”?x./ …_ø†�y©w¶™÷�š—Š›—wÚÐùz$fçx · ¡¯vÇ0£— ¤Wz•?ަ'�§/K†ÏÊ©Ÿ{«zǸú¨Èz‹ßzúØy¯¿w°×÷�7­~¿¢�г��´Gùµ¢¶Wˆ·yºŸüu²{a7½g“œïû®/´=]¦è–{ã»Ã7€Ä‡�Å_iü\ÒðrĉzÊŸý%R•»*ý͇̊ÿ›FÊo}Ô Ó"}Ç@ã?þÓ¿ sñöÕgú[/ Ø�ý̤}ê×Û÷Ü'œç{Þh߇í]Vá_*â·‹ãG~AÚ‘åïöæ?œÇO€è�ýêŸÿعþÑÉ~™”Ý?ŠÞ5j(hЄ2\Xáá€$'v¨h‘ÆŒ(6r¼âñ#ž�" �,¹æ$‚” °lé@€˜2Ь)à&N™:w¾ìéó'РB‡-jô(Ò¤J—2UZ³f†¨R_P­Z²d„¬Z!píjá+Xƒa�-;p Ø‚ 6dø°Bĉ-^̈‘cÇ�E޼jàäš”VÝà)Mœ9 ÿólêø1äÈ’'S®üq©S«Rõk@ëÖ®\Á†M[ÖìY5i5¬EØÖ-D¹sév°{/ ½{ùâñ X0a †1+¾É¸±åäÊ—3oî¼ç�èg¦ãF1á:v2d@‹¼à=øð¯Ç“gHà<ú×fÖ³àþ}OÌ'æÓ¯?þüÅ<ïïÿ?€ èSt?LwFuØe·�VÝ}xåIØzéµÅ{CÉg‡û ø!ˆ!Š8¢Q˜ ‚hÇ]HÞ]a„ÊXáyêah††ˆqØaq$úø#�A2g"u¸¥¨"ƒY9ø"Œ2ÎH£�&µ•= y%–Yj ‘™âŠ ¶øÿ „NNH#´uðX•mò·%œqÊù¡L]¢¨`˜JŽÉd™f–‡¦šlºI圅z¨euJWduÖ]—g¼ác~þIc Ž J(¢�zúiQŠÈè��JJ©¥äJ› ›**¬±ÊÊ’��:Š$‹|¡šêk«ÒÕª«7Í:,±…ÖÚ肹ŠÔ³ÍòZ´Ñ &X¦Mûj±Ùj+d—r”¬˜|5Û¬åšËºéŽËl´ÒN‹@µL]‹Ó¶õÚb·ö}ûh’‘ò¶næž›.º· í»ð²ªé¼oÞû0Äj‡œQ•Æ�±1Çxüñ‘=ˆ9å”1NÓã…zxå�{¾Ôå d>xäp~:êB…>z�¥+�:ì±Ë>;íµÛ~;î¹ë¾;ï½ûþ;ðÁ ?<ñÅ<òÉ+¿<óÍ;ÿ<ôÑK?=õÕ[=öÙk¿=÷Ý{ÿ=øá‹?>ùå›>úé«¿>ûí»ÿ>üñË??ýõÛ?þùë¿ÿ?ÿýûÿ?(À°€< ¨À2°�| #(Á R°‚¼ 3¨Á r°ƒü �·©�°„jz SX†°w#\áN˜ÂÂ08-ÌÝ W(â°†7Ü]MHª†?Ô]I†%2‘ˆ=4âq—Ä0±‰Nt�£x»MU±‹^´" g Æ1jq‹ÅÑ;¨F0¾gŒd,cíöƒÆ5®q†n#S‡™2ð±�s¤ã‡ ÈAÞqyDÝûÈÇ?²‹ƒ$äãuÈ¿%R‘Œl$)ÈBJr’fÛÏB)J9�²”8%*µ£J2xf•Ú9’b)ËzRÿn e(KiJTžÒ•¬ô‹/a)ËXÒ²–h»%.uIJ^öÒ•­t¥0‡YLc~²8ùÉÏ‘˜Y_>s•Ñœe ©y¶ý\?Ùd&7�éJÒ|å4d™¦8µFÎrž“—鼊/ÙiwžñdN¤RÎÔ³�Bê™Õ蓟Mx(|þ)Ï›”ž)B¥Aë�Є¡£e(; Q÷Ht¢¨è5 zÐ�ÎÁ£MKCÝùÐ&D´¤K hTªR�²Ô¥)iDJS’Úô¦Í©E„Ñ•nÔ§p*X„úž„5'aT-êpš�^ô”eiK} ÕvÊt¤¸êr¬ú.¬2Ç0ÿq\«‚Ï€U•7¸ëòZž¼òõ²IÂLYˆÃìGM8,bA ØÅ^‘¨l�Œ[1WÈõ:te©]ñªWòô5¯ , “BØâ±‡],cûXÉD–“­ì.»ÑÌÞ€¯{íìg*Ø£ŒV1¥5-jÛØ¬²;yk\©2W¿ÔU;w­ífÇÓY¿Ê´6 ÕN KÓž6¸Ãf,‹«”Ö¾V¹–e.f�«Ùܶ¯¹mÂn�Ò[œ¨ “]œ!xEàOñú„¼É}Ár¯Ò\2<×¶œÅmuuÚÁf—´´±oñ Þýò÷%2¡†';Ù#É6¡Ï}®Œ¦û×,ò¶ÁŠñ%ÿ„™è™üR¸Â-¹p†5ì€#a¡Æ6MV>|×w¶†$6J‚,d4¢8ÅaXñ„ÃéâŸÀ˜2žqŠl|cëø<î«�¡x!Y7EN1’¥©ä%÷¤ÉO¦±”±€ãTYF|x3œ³¼Â=…ËA&²+�|d¿°xÌdv‰™eŒf)¯¹Í¢œã,ç3vŽžW©ç0ƒ…�o 5<è)ƒÆÐ AS¢ß¼hFÅÑvŽ´*'Íç$[zan‰2r ªpL• ¸µ Ô•t½F ¾þupA &´¶$aŽS$µ’ƒe3›ÙÚD£2å0¶¡ÚÖ `¸‹2Ç#³¦J­µÿskä;»FW¯íë`{­/16á�]e7»ÙÏÖM´§­ k_ÛkÐ6·e=ZoÌÖ¸‚®¹Â붨{ÝÁm÷´zïÁÉ›Þõ^ö½õ’o·Q›ßGð÷¿¹poÜ÷Á�…7¤áJ`7mˆÍ’‰¨âY¹¸³™ meŽÕÿ¸¿¾änSàÛ/7Æ]î뜛éV7Ìé"s$ÌV¿ú‘,~ñŒf�íù[Þr¡»˜èFGºÒnn…£»-Lx;°sw»¤êW·zÖoŽópÝ ^— ØÃ^�±‹|è?ÁÇ`pr«�élwúB „‡ÆµŒÄS‚aÿÜï)Ú{³û^$�¾ô_‡);?ø ¾ì‡Oüâ—>�¦3Dò”w¸åi“ßÌ#`ó�·Ã‘.VÑ—Þô€G=iTOxÓŽ¼è%?úÉ“žòµ¯¼í0ˆË£n‘Ý¿[óþ}ðë=ü¾Ÿô§‹>•Ïzæžäˆ7¹âQÎx•³û ?X 49„üª ÿþŒïu^ø5Ûøq]ù!ÁùDú žË‘ì¨UÄmÑëÁ_ì5Þì=^í„ËáŸþñŸÿõ~Ÿ~žø±ñ•_Ć�ËÍÔLMÝä@ æI ûÁžüÉíEžÞßÁt x} zç� ‚Ÿ ’ ú¥6ÿœ > öÌ~`ÆT¡JØ0ù˜ì8Î× |!JÊk¬ÆÈŒÌœ!B�®a´¡’Æa~h… Ô¡Š^¨ñþµ† L×kŒõ ÀW¸¢ÿ]W5)Zab¡,iaìp¡Åx!~¡¶–a a®¡ºáÆ!ÎaVØáö]R úa["ä-Ä 6\!RÁ!ÎÍ"#6b å$ÂŽ$r%Vâ%6D&–!'ž¡'~"(Æ�(Ž"~С)Ú†š*¶+6„+6D,ªÛ,Ö¢-Ç"2¢#ÆR/¦Î/VE0†!oŒaZhâ&c2BÁ22c3’bDÿ£4¢"5ÂÈ*vÖ¢6Z!bÿ!"×ÜâSÄ£/åW!¤çœ#U¤£%®#&¶£&ãÄã<6# Ø#>Nc¢UãZ\#Cd#Clã¯ucAÚ"8"†BºCÞ‘CvD¾€DrÀ0f X¸#Fjä2r¤GF#H™H&I.„I¢@Ê"AªÀLJa•h�TNåK®ÊRCn!áÉGØrŒHØõ¥…Gñ$<&ã<¢Ñšé_F�[ºbQ"Ät¹ãÔ%Ë âR*�J~àSòŒVIÅTRe2úÒUÆRVÆÎ"$¦br¥Gxå‚eHˆåjxÔ¸�F¢IZêÆZjR[¾% Æevÿ]Úe nã^zc"¶L`JeUªRaŠÀaÂŽb.fŠte�}寄etMfGUæ­]&�d¦^læ#u¦À%?Z£hjb]NÁ]šfS¢æA•f¬¦´¦v¼flVÎæmÞl&&c^�crdâ�d’eoúæ�˜šü•Zâ[”[çg&çZüÜh:giæåi®$Ï Õ_F…ub'h§LFLÂÔÐÔíGwbØw.BxŽgyž§XP¦zÞH{ÊÆ{‚F|ÖÁ|"'„L~2'i¾"^¦dtúçÎ(uæj¨�ºQ_K‚ÂЂGƒÒÀƒFèm>fnFæn¢'ø¦¬g†ÊņjE‡~ÿh}†hg�h6çsògŠ:åœÈ`J dMÔP°q$|)˜b¤Œ)™FÛ|Îç<�MUJÉ|UIÂ�œÎi°åWŸ¡PŽ”6yF%~aü) 6 [ À¯ñÓ_½†êý•/} 4j:‹®†X4KÆ`‡þaÇdjºèÓÛu*F|Á –"€–Ò———‚é—Š)™Ž©™ž©¤éšºÇ úÈ›RIœÎ©œÖ©�Šž6¨ž2Ÿö) *³ j¡º“Œ$ªl,ªG4* <*³è¤¤¥bŒ¥j¦j*ºpª§~êI„ê–Œj©&À©¢Vªª*«¶ê«ž©¬Ž›"€›šX›äÿª®òj¯S åi9í©_ô)ëŸ ªk,D²žÆ² ž¢º£:j¨AêXV«µ2K¥^Ç¥^G¦.Á¦²Ó·‚눫–�kK>Ź.GúÒº–©2Áj¬ª)¼Òj›þȭÒipåk¥½¿^“¿^À l¬ 0į©^†Ý®RÃFëÃNk¤J쵦@¶>Ò¶jl·rì·‚*©‰*––ë=•ÄɺRʺª2¹Ü»ŠQ¼Î«NlŠ/]œ6-$«½�ölIü¬À -ÑúšÑN³Ê…³^´JkPkµFíÔRÕn,it¬ÖÎ(�ˆ¬""Æ×’DØ®ÒØŠA´™­Ë¢-ÌÊ«ÌÒÿk•´m½½-LÆ­{Ì­°þ+±Þí±,¡ê­àí[$­*-­à®¤®Åj+Ær+x«§6n¡@.NøÒä€;ú‘’iW ‰æºQÒ è ªi‡Û¢Sé“g ./ k%N"jìò­à­™*Ù´~„§éäL TÔ\¬‚¸"X¸ývjã‚l–Œªè¯3ùEòºÒòŽióÒÈóŽQôˆaÈ[õ’ÁõÚ“+]Üö¦+=¨gà€_0ø¶†ø†�ì>„ùjú6ªúê;j@û–ÓûònüâüÖïÛÝïÖŽ+–î/ÿª’güï*° p…°°€$0²-p§Ò×[{ÿ¢/Q°_\0wVø¶ÅÞJˆê}0„0 Œð‡•ð _S SmŠÈïWЯ Øo¸jYœ$LfT Û°ÿj¢òú&ór…ó6ÜÙΈ[’—±½aï*A°_(_…[p¯Å¿EW€c±ƒXEšðC¹¯ÐÀ/vˆ±�±, f˜ŒÉ¬±Aµ±vÜ0° 0°o.ÓÝ€ “()pòè²* òUòwà!ã@"*lpp[¸ˆ‹í#×XúzÄúFjçÇ#n³ð»°Çþ(#†(— )×�)ÿÒUàðâ�ÛC@«ÛçqsÐr(Ù²^ˆî;60.7[¯áÿrùó0»n13ò1#ó(3Ž�/3‹°3“ð$G3~L³ì]‡&sò Ÿñœ½D@!ù',"*žüÿH° Áƒƒ(\8§!™‡6"JäC±"¡‹jœ¨£G8 CZIRˆÉ“=Rª,À²e‰—Ib˜IÓ„M7n¤ÙÉsƒÏŸ‚ @´è�£H(]ÊT©P¡ .\x¤ªJ‰ hÝ:¤«×�!+ˆK³¬Ù hÓBX˶eËpõÈ%I2�Ý»fÐi6OÎ-G¥°aƒ“X|Äm�‡�ɘ1£¡²†¼ 2L¡sâÏ@ˆ®ÚØ1ÜoRïµp§Nž;‘"�J»¶í© 5BƱ¢EŒ76ôø,œÕwïª\éøe‰˜Iò¶Î {çO O5*ûGÓï ²ÿ¸�›ôUÞ[¹zíjNÞ÷ði²mk:îܽÉíæ]Ý÷ïæÁ#ˆ‡˜bŒ9ÙC“Yv™Y™1ð_g á„¢�@šcœ–Ú«M÷lÝý`Ûˆ$„[ºAÄ›oœpÄuÔrù-—†ÎA'ÝMÔUw�OâmGTˆà5%`m'š—o6¤§Õzìß”fÍ·†§É¥�Éí·W9ý7Ø‘}¶ ¥µt d”Y†™f, ᄎV–pmØ!�òb‰€"‰[Šd0É".‚âŒRù^~yØØŽ0Éd–‡Õ¥ñãâ­‰!†ß‘U’V-‰ž“P1YŽRÙ`ƒx†ÿ %—x™Å_Y~…'€f7`g¦ÉÒš ºÉ œÈÙ�Vxa}¨©¶¦Õýèµ�H¨¡,&Êh£­âZ£�”>giYÔ¶類~êÖðÆ+*B¤qVN `e«Š"û–}[â—Ÿ—t� خΠ€™ºEl›•½é Ãs2ëì�Ðê9-Ÿ™Z‹íÈhë�ŠXêí·8üK¤’–«ã¥ ûø#»ºûn¼ð:œmy¥öÀd¾ûjÐo.ÃðÅney]�"L’Âÿ-å0Ähx`±Ë´²jl§°,i(-]éúÙÉ×2$ÜšÜúV4Ë-' )J7²¯sÎÿ;€‡ ÞÓÍ,¶«s<÷œ„?Oµ•¤I!ùVwT^ôÑI¿·4}ž­vy—H|áêK¡ú*ЄX“ Ùd°+ø²]°b¼¬Ø‚°ÕÀž{ÌŸi©-[Ql“èöFp¯ÈâÜ,g~·I̹Å÷K~.øNrd¯=Α®wâ�„/>ã�ø¸�‘O®Uåw\Þoæ7ȹè!HJ?ý¤[@5ÃV«^&�Y“ØÖ(¶ ²Ô.Yœ¹�r'šÝ•Mt¾óPðv«¯xäAÑÛ·Š0ï[ÎËÞ&ÕœéU�O�kO´·½ÂåÌ{‰›€øÆ×™Æ-ä|ËIŸ(g¹}a~ ØüÿDg¿ûy.ûC`Ãü7�Öi-2\+ M6f!€�ºÓ ïÌÆ¡‘H-<©à1H›ãj7ʓ۾èÂ䌰\}ëÚßPx½4°0{܃Œ÷¾‚|RÁ ï%¹®¯‡ ú!g²¹+=ÐsE4âè@25ÓéJ‰cb¢@œ(@(ÐbR`�rçÀÎõîl_¼@y5F2Ò+7ŒÌåÀ>ö}\.{ž¢çÊÑz*ÄÞóø�=ÆÐ�¬aù©ÈE¤�­äà´tH­j7 Y¿ú`–›Â`OêS­ÿ•­PÀëQ•ÊT¨úVªTumVƒÊU0|¬3¹‰pËê–³:)±GX+nÝÚ¸îA®V «]¤Û:è>’m†6+Ø¿ÌÒŠBÀbëXȆ·²–Õ$0ûB–hÖ±�ý¬gE;Ú¦”Ö§Í�jWÛÞàú¶?’mvh[[¡²·¹Õ-oÿåÛßšeª­Yîr´ZÜãz5¬UõkÌÌÊ"´&Vºl¥.¬‹]í~஺ýî{Â;^üÒl°çeVz×kÖRõ½ðýÃe˜Ù�×,úÝ/Å@ÚˆxÀ©õq†|ÇØòtÁ ¶íƒqÛÝ ‡«ÂPnk<|€ánµ«±†yÉç¦ÿº(.*ýX…,¤Ÿu‹uY·fëbû׋Ù±ûÝy9;eÓƒèÞí¼‡´Ü3CwØ=´x¿ãä¡L‡¾ç„Óùüà OøÃ/ ñŠŠÿ¨[žîǯ;òP�|åÇ|yyë< <÷jÙt¡§„èñ?néírzÏ¥Þ «‡g§g«â(±'9³‡Wµ7G·g˶m÷v¾w}œgvM…v ¡vq|o§q‰5w¶wÏ'ÑÇBÓçm‰õ{€§}EÀ}݇x$"n0ƒ4C²hQ‡�ç(¢~¢Ss6oö~ù7õz÷ç$ñ¤·ýwÿ€Â19(u¯7üt( ˆT Y¸'!˜|†–/¿|8|X|k×u»Gµ| Ð|#X‚Ú3ySh}7€}ÉÁ‚-è‚Þ~OAƒ5˜87dUyG£%ZÒƒzÿ·~6w\˜TEX�ôçyö×f¸„7Є¥÷„p…«7…Ux4G“…[Ø…Gõ…T†0†pØ{w†H8°‡È|!XwMuw¸•wz—‡)H�&°‚Ú炈1˜„8ƒ6è8˜ƒŠØ/Œ(Ž(s�„í7„:W‰À7GzéÁ‰�èaû— ¢Øt¤˜ƒ¦Ø/¨x€ªX¬Ø€`ñ€E�d8�{h‰4!|@|ãцø†¼˜V È€"ŒÐ7ŒÒWŒÂ¡‡|x~ÈŒÎhÚ!$H!>`j¥„ȘJu’H�…m×v³D}ô3=%�=0“`…·'ÿ„&p4YГ>y_5‹4ŒrU!©w‹–BµBP4"ð”BñR©TéÕGѱVNå“¢A'O¡�3„!i°•䨕=ù•R€ƒÁ$©•V –3q'“&–VñuŽâ[Jµò–´Ñ‘Ûñ‘ás”90’çX’f�’J•…âÑ’Pö’Ó#“4i“„‡“&¡“<é“= ”^%”CY”VŘ–”�³”3Ñ”ûò”"•SY•nq•ŠEZYoµè• –B!–d)>fIh‰—À–Yà–—r)t‰›��—ïÁ—Ï•X™™3˜^Q˜Íy˜é¥˜�ÿÀ˜Ž¹´X’™’üT™wä’¢“š9“œÉž) Ù/¢9šp”3”€š> š§Åš àšzá”PRùT©V™VYI�ÊÉœ– 0–eégiÉ›?7¡¿i˜Q—G1—¼Q—B�ya�o†�ÂQ…Û‰„Éœµ�˜Üñ ¹z"Y›�㈞’é}ÞÇž,äžžŸr@“5yZ7©9IU¡)š¤yþù* 9@  › "›´É ¶ÙÒ¡:�Må›À™¡n±¡Š\z¦m¢ß9¢Ï9Ñi—*j,ºÐ5…UÊ�]á�P£áy9Út;]$ÿé£&¤BºâñFz4p©˜ŸKšMjOÚQú“ûùaUjº�«dJ©eÁ¥–ᥠZ›z›ª›*§ËI§œ:œáSœUqœeJ J'ÎY¢Ðy¢Òy—ÃZ�ÓÓ—¤Af�*£ÝI£à鑈º˜:zZå©çIé©’š”z™¢ƒ©™š¤›É¤�餟 ¥ø™ŸSZª¦º(W…ªªª­ÉªL‰ ³«`:«bZ«» §fJh:!Сĩ¡ÆÉ¡ÈY¬"Š$ú&Š(z'{Z}ªÐ%­þ)¨C@¨†Jc髉ê§'æ$7–®‘:©MA}V„®—ÿª©óYŸ÷YБŸY²ôJ”öjUÛH••¦ùš–Q!â±  ú Xi«Í*±²°(ÛZ妋«z¬›¬»¬Kk;¶á"²VT²p²Ètg*›VdÖ²–q"â*³LaE5k³8Ë®ôé®ö ¯<è´ñ“ŽrªŽ±¨G‹I{ •Á´Ùá´aÊc*µ;T»«jÚ«lšµû¦¤§;§ÆJ{±‘±ÓÙ¬høTF—† DjË,lë¶~·›XsKU4Q·¸q·äÚzË,6K}Ë©íê©ï ªb…‹¶€¸T¢¸nÁ¸”…´ýÙ¯‘+M+«Pÿ››;º›°UË« û«,ºÁ ±Ãšœ\««^«ºÁºÌš¹ïá[±›³ ?µ{ºQ�˜¸;Cºk¶¼ëat[v³Ã›·Å;!Ç›¼�ú©71ÐˉýûyŸG½Sb½-�½ ½]ÒªK뽓 ¾´µãK¥½iº ‹¾W»¾A¥µï»¹ó ¶«+¶®[‹Nn²K�~è(ÿ;±!À雲»+·ì»3¼S!¼êÀŒ¬®òé·:+¸¼„¬Á5“á•Ì ,Â[Z ð½¾G@¦ø»¹Vû¹3º[[º¹ À{§Èd¿ê¸½ÛÃ%÷ÃÍê‡zi�ºk{­mÿ{ÄÚúq­KœhM¬ÀÁËÀQ¼S,!U¬¤9 ¸;»ÅLH�^üÅÓÆõŠ÷º¸ÜZ�{�Ë¥’û”+°–K°·jÇÇ [ì{š¹ð‹Ëò‹ºzìG|¬~¬¹PåÃü Ä,XÈBpÈ^‘È´¡b zgÔ—("œ›ÞLÄö$D!ƒ±©§¥aV5µavÊŒB?nTÀáYBàÇb!x§!sI|žåÊ#LŽp’ÞºúŠãÜ^Ç3¶qU ÀÄÊüyÓÌ,Kq²T©¤*á˜,�M¥%ò}#"+éu³´&è)�Õ²4AfdÖMh™ƒ›%®¶aÍTÿ‰ÍP¦ÍŽË¯4ÑÍß\§á¬‹@΂aÎ9€Î ¡Î>°ÃÌ2ðŒµa0ÏFPÏÿ|‰ø úlÀUÑÏöÐJ5Ð]’Ðñ²ÐZÑÐVõÐ’ÑA7ÑtRÑcyÑ4™Ñ<êÉ=-ýŒ0ÒvPÒrÒù‘Òu=,ía.Í¡9(Ó�BÓZ`Ó†ÓþœÜìX Îá|ÐPÎzgÔs€ÔJtÓÔ2 ÕRíš÷xùLÖi¥ÕS-íÍ_�Ùb /dmfíh=vMÝVäÖ×3)׌ʼ�›Ö»íÑ¢Ò|íבØÉ!ØÈMØ…ýU‡]…Š (ŒíتÿÙ:<–mO˜­ÙW�Î댿‰ËÔ¢ÏO�ô¼ÕUW½ÚFÙ:íÚ] ÛÔm }Îe}]×MÕÛCðÛÂÜZ€Ñ)¡ÑÍ«Ûw­yÒA‘^Ð Ò}Ô­ÛÖ}Ý�݉©×ÒÝu•Í.²Íf1ÞåíJç=Ô›mê�Ôì]½,óðMÚô�ÚV­Ú¤ÁÚ¦ÍÕHàÕÿÖ>ÖnÛ~ÖÎÛkíÛÝàÂÄ�ÅÈ]áÞÜ6JN†,�Òþ£+-â#îÒÚmâ‹M]לâ7½â9-Ù-NÙ=]¨?½�žÙ2žÞ±Þä.t£ãNÍã­]õ}ßAÿžß[ýÚ}ä>àE]à„pàYå5ÀÖÜU~åt]éÊ Ì]£.$_‹n!æ.UfNâQ·Ý%"Ô#€|WaÆ:=›EÍw1>DÍÙsàç,ì2Œr&‚>ÚòÕ=^©Màø­ßrÐŒÛy>ÛPÛ·�Ûmé^±™Nå×>ׯ­“\IŸê#¢á³”=oæ�=æª~\Pïöþô#®®N"°.ë[ëqÞ¹n»».ÎyŽÞd½ž9žÇÎËñ}ó]è‡äY­è…>íŽNÖŽíMŽÛO®àÞ.!šîÃ=îŽÑd®åË(‡*Úóî ÿcNæ!þUö~ïM‘^ú®æÜ݃áï¸ ðÐí;íXº~ç½þëè¬ Ÿ4 O/ÏÉ^Úûmè>nßÏÏ?äÏuÕžä´½äÙòQ>#�%á= áÇMáèŽ×-(/�1æ35?ï8Ÿóð<ßóùê@/BODÿ¸â�ô_ðK?ã4îô6þç­õSñ„0ñC^ñΞèÐ^ü]äþ öHé ýñÚ¾òÜÞi¿öâÞöä®òçžî.�­0ïîxO?If�U\Åu&gâ÷¿óB"øƒ�ßÑï«7ëG�øÖ´Ÿô?ýøWùž}ãeñAÆžz;ÿ^õËÞì‘þì‹Þß�Nú�®ä‘Îä“îä•.ò ñí½êàlïöæn¦´O÷¶o÷¸oê[!B!XPàÁ`.$ÑÐ!ˆL¤(ÀâÅ5nÌÀãG�)R¤PrÄÉ)UÒayÄ%!˜dæ¡YÓÂMœ#"àÙ3äO AƒZ,Iáäˆ9”*5ÐtNS>L=0ÀêU¬V5låŠÃ«C+aÅ [ L˜0 ©Ik… Eä\š£©K—/´Íó¶ÀqƒèÉóbQ;v&,ž°´©�´Q}00Q¹2VjlÒ9Èçž3ŒÖ¢%Âé=Tã},ÄõË—¯fÖSÄÿíB‡^´øÃ÷o9ÁÉ /[¡À‚�/dè°¡Nˆ#'ò¶ÈÑznݤ'HÜÝNq¼á�H–»2Nœ‚ÕÇ)Ì3ûû÷(v/]ü`üÃÉ0àŸÕ¯Äa=ÁŠ*Í´âÌ� ¶üË,³¡®øà¿:ø0‚ª©|P¦9B±¨¢Ž:Š%éøcE#l &ÿ®Ú¬†jtè·ßNB-©¥8à Åa‹Í¯7ŠáHìàSr;)štò,(Ã8.„ÇëìÊ!:ÐrK%»„o;ïO<—È‹Ê<л‰À8¼t3(ù&¢O ûÂP?þˆñ-½bÓÀÒ"H0Œ�h0« ˆÿpº,ÄPC«Bôà D‘D£L!E–XòE·öœ±ÆnÄñQ«ËÇO…´ŒH#‘|ÓÍjµ5ʳ¦¬²©ö˜õW¡À sL2ÍôM5-`Ø_ãä.±úŒ³3¿áòÜó*ûü³¤-ŽÐð„qR%¤ÐQü åÐÃÌ@´tL35‘S=ýÃÅqcÕÆ†NE)U{üqE]•Í*¸Š|ãH’dV7[oÅU×]{}øbí¤cŒ1bÅ‹ÔàóÔ´c/��³Î¿kÈVÀ^EðÛBÅìÁEϽ0Ý ×%—w-UI%ýô£×Þ{#Ì׿}Kí÷ÔTO[uà¤ÿÖ…e%Έ»®Õâ�ÀÞzÖí6^¬ãð>FVdŽÆ†Ïdhé”6ej÷cùÚ—Œ™Û@­yi«͹Ñ�3ì™*v�¾€Â†N©èᎶßPõÝŒTSqŒšG¥X%8Hó°fØa·=òÚk±?J½ô%56m¼Ô6/Ù‘Y n;¢%뾺­m9o¯ö¦ [¿Ã5ð7·. yŽ4q™wüÈÉ�ÜSÊûõr~Iðwó©[ Û Ýö�NïzuØG?؉FËÀì Ð>Hvઠ=Áj?$Ü鮼«žî¶§—©GxÄ£™ñl6œ-o)Í3Üó~= M¯z×c_´×ÿ2R‘ê6 ÈÀ¤&0ñ ‰|æÓúÔ1ö¹ï?Íhèg?�àOü‹ƒÿfhºùÄ e*³›ž~ ¶GfÞ* ¸ð"®ÊA°\Œš`óÔ…¸ ..ƒŽ«Þ»æ€4¶Ì*!¬ÑK¸£ð}ÎjãCXùbÕ°ÿ½ÐV1lϳSÃù½®,â¹_¤,³Ã5õ¯mv¢œ„87"úoHÌûÖÀ'/Š�‹ •‚® úìfíÒb]49/‚‘/bK`F߀…j¼Ú ßHºÒÉñku - <Þp�áé#‡þúð‡”Ûî¦UÀ•q‘~j¤ù6³&þm’É«¤Îu¸ÿeQz\å»\”=äùÇ”¨üWYµV¶‘…p|Ÿ,@ÇÂÜ2(¹Ô#Yø˜C?V�ÊäF.æN1wÅà1 ¨L2’=ÎÞ#£é@ä)Ï’*ܳ¹IÅmsh]ôæ7AõÀ=�ó6g Xç¨V06ºÌ�Yc§ e OŸÈ“†ñ³a= pÏè˜�ìá ™P�sˆ½;`ŒØÌÂ,±x‘)5§hMçiRŠÝâF»i)�~4œY) SiBÎåÀsèLiÂ^Ç—ÚRuj•©H¤sÔ¨F®=Ø•np×kqE=\R’×¶ã¯xíA°ƒÝ@a ÛÆÔÅ%HËӫȕȎ°ÿ'¶*X{Éä’BàM‚+'a-)µŠ\L[@¤Vµ¬CZÒrWØÞ@úCšf —ÚèaK•EJ‚êš§<Ýv¥ ãk[�ˬíÀõ4sUM]a›×­ìUK]ò«t‹©ÁÖ°…Eìb.ËXþ8v“�Í‚dyBY“Xv)‹]‘f9kTÏÒ…BÆipZ¹¨vµt-Lb{WáÖÖ<ÂÍínÓÛÛâü¸ ®Âˆ;ÝãF˜lo�s麫çîI¯‚)n|ºö×S6»{Ø.w“ØõbÖ^�=˜Ék^ 7SæT {ÿàÞßÅW Œ£¯}ñ‹Zý‚µý%Äe{[džÀµÿ1°¼˜H·Á~C‡%|å÷$·ÂÌu.^5]Cøm¶î©¦— ”xÝmLŠÁK™S’/¾ÍdkUYçÀÆ8Æ›Ž'ªçHÖW…- ²�ùÛßÿ 9Éú¼m�µÄÛ' ÊÁ½-•«,f,g~#Qnj¸Œa/ÇhÃq°2ÄÈ<�yP¸bówWÞ8;•΄9ï�Ó›ç=Ëä½ÿñ3�m_ÿšµaÌJ€�¿F3ùÑŽô¤ù3e—ZÓÓv+§·<×.ߺ�n¨{jФÚqhm«Ýüj8›€]³¶sð\R@gV×9¶B|�#Z¼×6‰í—ÙÙ³utÿ íÛ]-˜Á•¦²´©}e[Q¤ÓqUÍ•£Hÿ(T=oªîHÒðq�«ú[¸¢Ÿ««†&òUàAä핌UYcßxÞ}®·|/‹o}ÇÚ?ÿwÊi{lán©ÉpMPõ.\è`àáK7]­$¾¹åV¼3/*V4.Žƒ{" ù¸W¥’ŸûälÔßÊ!Ûr[ÏÞ¹Þ,½í=ß_úZ<e±ok,ÛÞVèËvrÑ!wôÛ&�éK�øD&õX¼)ÏÊÕÛD+­'€ëyIn6“»åmTyfXÞ—«æòn;Íß~sÑæØY¡{S…‹÷ë}ï/ŽÑŒtè þá…OÀá=ÿ�ø©/¾êWq|Ö#¦©L> •' hÃ>z5n^¥�ŸóÙAŸö—Ç»½3ïlÍw wœ¯+­Gžf5 ûØÜAýëß»Á™í÷¢%‡ ä%¯àu?mÞû^®Š7ã­ÎÌõx“ïÑåc>³¸¼�ɼ‘¾²ó<ë+ŒÐõ˜ã³î;½ ?¹Ûò›&ó“ cQ¸õc¿Ù{¿Úƒù3úƒ,û»¿LË?¨û=þó?âÀ�s“4‘ôº‘;Ì;Í#;¸0»,@;w»µµ›@îƒ/ïû³ËÀÙÀºŠ¼€\°T¿ö£½²¨žLÁ,XAÔ´‹p2|9¼H I·8ÃÓRÿ7$Â"C9täcœÇ‘ºš4£*1<Œ ©² © 7üŒÏ «Óh — #‹B¬0­ºB³)ù˜�ñ�ž³ 8ØDN4%;Ü6aŸ/ER¤˜*qCTT ÃãÃ2½3„‰4$-6” T„Cõ™C2œžOôÃÉÃãØÃºèÃ?” ,ŠAÔƒB4DDü*EŒF<Gü/H¼ IÜJ<K´ ¬ÈÄàÄN$£^|ŒUüR,Å㨫rdÅ+sE:„Å—�ÅQCu³º6|Ãë“#]t^¤�;üÅ]ÑÃáC§øE@<Æ«HÆe<Ä JÄYD:À‹iŒ­j,-¹˜Äÿ©ÄmDH«ðFpÜDOôÇŠa+ 8ÇQ4Er$IvC‹�C3ŒGB˜Å ¬Å"¸Å|ŒC]ìǺøÇ§È`Èa,ȧ8È‹JHª D0Ä hÆyÆhœHتÈûºHlÌHmÜÈ¢ìȺÊ�„¯G^QIêê€^YÇ•lÅ–|E‹Å˜œGZ¼GU¼É\ÌIÇéE<ÜÿÆ¥ Fƒ4Ƭ…LJflHg|HhŒÈF|Ä=¹Æ*ÉF„¨žKÌ �üH¯)KuË "Kê8KÍLËsÇ—<4„Ë™”K\<�}ÔIÇʺÚK ìK×$Ê]Ì£TFÂdÈôqȇŒÆ#`ÌqÌÿǀ̃�Ln¼ŠÊÇˤŽÌŒ§ìXNÞðLçÍiMx$Mylzl<¹tˆv³“ü‚@OòÔIြ쿃ÍâàÃw1Úô�ÁTJ¦äÍÄ à¼Ç$N�0Î@jÐÔ,ËŸ@Kè¼éŒ)êdIpÉë,MíŒK[tCוּˆ Oò,Ï»4)ôHõ.ÿ02‚Ü•øÌŠù,ÌÝ„š¨ñͺ’Jk¤J°Ž)©Æ™2P¥Ë0ÐZšÎÛáÌè\P_iP…ж„I™Ü· IT¼Ðë ÝÐ@0OIO…Ñÿ*Ñ*9Qd¼Í…\JÃÔœå”#ǤÑã°Qÿ><ŽÕÑ6(Pê8ÐÏlºˆ)K"-R#Å2ëLRì|Ë =Í U(õš)ÝP+ýО Qÿ#Ñ 4QÀ¬ÍÕMÓ¹AÔ —3m™4åˆ(èTOeÓatSñ€Ó8åQ R%Ò=Í´>-)·\Ò5ìΆè‰x9T�QTªѬpTÙ„ÔÿœT1]Q25!LݵÈ"x ëðÔO…œÕð U9å :R®¹ÓÎdÕVmǵ|G?•Ðí´ÇA…Ò[5I*­Ò«+Ñ,ýÕ-}Ô.�TùÓÜ,ÖJeQd5SeES}Vh�PíKjÅ k5Õ9ýQ RnÒýÖ‡»ùy¾ÿóìÕÄÉ c)ŽíX¼7·L‹Éü?©ž‘ã¥Ø‹¦â! I[‘Ãu…™�Ù)ñ�d‰¡P3/rކ&ð‰ ZB¢ØšJ@ÅX12–)ùXð Y˜Ù,YÈ9Y¼•E–uÙZ�Y*�Yš=›Uœm–®Z³¥6¢Í#£uW@Ú–QÚã`ZÔƒI‘=N«è0YËCÙ«�¦¬ÕÖŸÝZ2ŒY¯…‚šÍŠ›…`Ú³m\p€ŠíA¶uÛk�[„�Û tZB %¼ÕÛæ -«ÝÊ«øÛ†µS®ÝÐÂ5\°E\±U\²�Ç�]µ„Ü¢E±É>„ÚË=d-2�Úÿ=éÜ©ÝÛªMYѵ Òu�± €Ó%ÏÔ=\¬PÊÏÛYa\Ù½Þ¡µˆÈ]Û‹Å]RÚ]�è] ú]»�á-ªu‰Ð]YžjYÀ}ÙÁíÚÂ…Þ«�Þ  ^ã³ìÝß*KR´ÝÖ¬´ ð ñmòýÏŒÀ*h`ýHß#X_¬m_­�ÂõZûý§²å_¶ÿEfŠ„¾=YZ, ßõ˜ò]àŒ®‚&^õ5^öå§8pßÒ \9zÞƒu‰ ~ëý`"&™þ‚¶‹ÎÝ–Aá¡A³N›n<v`â á¶á ÆaVÞÍìáùýá#âŸêà">ã‡9âÿ$Ž2Rº 'V (¦ טc!^ó­b¾âÏåÛã€äÕÓô‘%dBÎàð ãÅ5c4^ä7QcïI6á™Öò"Ö¢ã×(ßdQ¨žá=.Þ¾ÍáúãŸp'B&dž%2Aä×Õ_F~e/qä6ÛÉ%nc« d ²d9Æd;Þd<öääã¶e ~_A>eHåU–^†]X~æ7 ÏÄØ`ˆy#K#UÖšB4I”Ì pF¼¡�ˆ䫞)™ÂP¬Ó1sfh~ç¥+Ëi†7¥@ˆk¶å=ÙæìfogÀçÛŠs†œtîÀuÜü­x^h´¥Žy>¡PµfíÄçÿ|¦ n6o&ç>!ç è¢)hó;èNè`h”æS‡¶ƒ<«çƒ¸gŠf=ûâçDÙh€�Öt>u&�”þiÙ•g–¦ç°ç‰Ži™vBš~��¶_�Æ%éØi„˜B´j«NK¡né¢~é£Fê«�¾¯Æè~ög§èyŠj‚æé¬ê«nkÌj¢6j&Ži°¶Š¥þf²fæ;Bë�>ŽNoõ®/Œoÿ¾êù¶ƒò>ün*ýVïþþoGéðû6ôöæý®¶^p ç߯„ˆðD™ð ¿p�Ý b«äðƒððñÉqoܲtpçðºJå¿~q÷à²,Kþœq„¨qž½ñò ÞqÞèq w!'r'7[#ç�íHrß÷Ö'Ïr‰�ò‹Ød¦*_r(•N-/óVårÿ‹ðrds+r,7s87Ûµ5³Ž�s<Ïs=ßs>ïs?ÿs@tAtB/tC?tDOtE_tFotGtH�tIŸtJ¯tK¿tLÏtMßtNïtOÿtPuQuR/uS?uTOuU_uVouWuX�uYŸuZ¯u[¿u\Ïu]ßu^ïu_ÿu`vavb/vc?vdOve_vfovgvh�viŸvj¯vk¿vlÏvmßvn'rw*Ë÷îv'ÿvêwqrrç s?wO÷‹Xwvwqw·x�wŸw¨w{·p|×÷}Wð~Wä—wYw�ø{ïš}4xwFøÿî8ŠØÇÿŽíØŽawx·†ø‰�ø‰/ƒŠoà‹ÇxXÖøˆù‘¬Ÿ½s‘o\’�—4ñ,š•oñ–�Ý—Ç”˜‡cøÓ�šGè›÷`’G¾�O 4«žêÉÖÓúýzœ¼”Gú¢a†ay¦—X§ÇA¨×p©Ÿzª«¿úV•1 ({³'ú­—ù-ìúáøzª_z±Çù´3û³z®‹z¶wûª÷â¸ç_²§{ @û»çz¶'½?¸ïû³ý{ºü®šTtC'q’ê9|°ç{Å¿^Ư{­çºó<ÏÈW€Éo’Ê?üÄÏü Ýü²wü�û| ýÑ—‚Ò×ûÓG}Ðôš¢0{Ø}ÿ”‡| TÄ’Îâ—ƒœð+¼·‡ ·}vÄý’Ð}Þ÷}jnŠàþâŽô®àŠåïbçßSè§éß}êG àwCá‚ì7~ùãþî×€ïoþðgÁñ/ÿÞ7�ß·~õˆ!Ê)hЄ2Ôà𡚈1`@`€Œ7rìèñ#È�"G’,iò$Ê”*W²léò%L”fÒ¤`SN:hÑá'PBMcô¨Aƒ&–2eØð¡C‰+^Œiõ*Ö¬Z·ríêõ+š5oæÜÙhСE�MZ�iS§ F•ª†âEŒ`÷òíë÷/àÀ2gþ(l“N ;yÿúü9�¨¡Øe`ù2Ü¥rçÒµ{—ªEÁ¢G“.mútG±3'^|Ö±@È’)§¹Œ9ófº<ã­Šú7ðà‡—T€uY�¯#<&:›²mË™Mäîl·whâÚ·sïî×8rÅf3�í\(íè ¦W‡Ê´^ïòçÓ¯oùÕC\p9æËç�wä5ØÙ:é¥O>¹à„GжÊj+θÃ�ËŽaä§ÛP9晧ʪ�{Îè}‡4zé¤ÛnCêàα<óÍ/ŸöÊŠ‡{›³[O_í§ãžûõòî;çŸóMãHÄ|òº:¿þÐ/,=õ._ï‘qØ?þö[ÿßü1å/@ñH×]YªTõ:@f* À (i| Œ ´� RpûûßaJ÷£Éå ƒ”LB¸¾R‘°„!Ð�¤+hÁ¼`Ð&ì [˜ŠÐy/̳8�²PŠ/Œaõr–Ú8cVvØCGýðA„Ëh�"1‚Iœà™˜¿ Š’“â…r–0‹ZÌ UÈ/’@†3¬_ïwF4^ÅVkü@ ¡ÉM"ŽC´€B)Ê#Þqy¼H)ðD-D±…T¬!IhH,šˆÿ!Óa¤#ûÉH `’”Œ‰%µ@ÀJ•j“œ¢•$JQª.L»à�ØGVþQН\ß²©ÍYæ¡– ™NÂ)N0Êï‘dä¥/ù’`3 Å4&!:É”8*s™>h&˜ži¡T®²•d›§ÍmÎÒ›§8ÃIΠq—‘L§:[ÂNSHðŒ'2åhÏ{š-Rú Ò�'”Ìzn¡ ](aÔ ·ÈÁ`�èJ&ÊÆŠá¢ò\ =AiO|ࣨ´ŸHÝ@RÛ½ð¤BIé@Yй¸tœ� ceúšÚÔF8]g¢.™IxþÔAÝ(Q�j‘û%u©Úÿ3aQš*•®´ SuJUzÕröO«\õ•d$º¯’D§˜ä©O3ZÏe¦µ\[GÀã55®O�«J¥ —Íäµ0µ‹äW·,°B,aEbر³¬gjG�éØÇ!²J�,SáZ¹ò‰®š� ^3“P½æÒq¡MÀh“RZÓ¢6µ Y-bɪX¡26¶ùœícmëVÊé–·Gò­]7KUá÷³qâ¥ýŽû?¢½�=œÒNH ÌÉ8-£q$&–ã×þý¯¸JÅ<„ ô^zÐà M«`HO2Uxpé€b0†ð¢êÙ †3Ì�õˆ×)Høpçj,ô @½ùc¯ÿ{­[ÔÖ­L¾©¯}ÅBâürÄ8ü íÌ+/�ÀÚ40‚K¸`Ó6X(®B„2a _TÃN~2‡�Ë�#!ÄÇ"±‰ñ‡â@¼×Rˆs1}åc£—Ʊñ�”cÿXH6B�·f�'xÈ’)²Žœä,…M~2 7eÍÈ…ÊV1z³|¿-w¹R_á|a<æÌX5ú¥IšÕ¼æ6áÍqvÊŸè,d; Ïz&�„}Eá:ü9Ð !¬cýÂAS§Ð 月=…åЮ·Aí岊ݧ00Kz̕˥gr\šŠ‹Óžþ±œEMBR—Zq†0ª•¬j ÓÕÕN‰µ¬KÿHëÍ×WN4¯OìëëJ\Âî±ÅÎ&�_H×é æ6Wð©ú|B‡;Yz'ÂÄ;\ñ*›Ñø£éÀø ô¥wœÝ�9‹&ò mhÞô楙5‚f1›å`rù¿aí “pæ™±ùÍM›óm£�çöyă.å…”ûâç>º[’¾t¥7غ‚:|[ iìÄ­äõFö½÷Ú®{ìŸfH¨É^*³Ãí5Ç9‘tBÿ·gîà–;¡=lqŒsêH×ÞùÞô�Sa5x=ì§Î? g‡�Têù@Ç=‡¦Œg¹ãy�ë�®”gŠå €y´T¶í*´çÃMÂqÛšèv—ÏÖ”Ô¤öýôºÊ}ß›ÂéÀ>öƒ�Žþ–¥2°¿ý¶'­¯r¿ûäú¾ ââþó|±\I6¾JÑœå-PÌZtpÞ\TôIœ¸��åÕémGö!Èö‰T÷åê¥^øéÖøeFù½žì¥_­$Jû¹_Ý™ÈÑ_ýÝ_þáßþ�à@ ÚàO m  *ÎÏ�ž $ŽÆþ(RUàšÙÁÀ Âÿ’שРaÎt0ÅÖÀ™ŒÜiüÏq¹” û1a¹(˜×�Éúì�ÁäÞª­Z"•€AqÅ-Dò W L�Ötðä¡Fö!ZÐ(˜(MáRÈáR]`aºáOºA.!¸4! IQ¤@a I!!Vá!Î^ihahq¡–‹Ž¡¸˜aü¥^Rضáx ZžÒá¨Ùafà¡æaú!P¢ †!š€!š &¢…aH!ášAb;YÊ$Rb˜X" aâj"1"b'æÏºH(Ž¢¥”¢)F *âž*®â µâb˜AÅápÑâ´™Ö²J.êâ.FÁÿ¢i "!# #`(âÆåO#Š 3R°–>N!?úã_d‚Ìñ¤EJ"Bæ€B2ä8än"pLd‚Xä" 8jd³qäÞ­H" ­£å!å…SðNl%WŠ�W~å=þ¢ãLF¤_Ø$‚à¤íèdAò$Bþä%6d&å5r¢Djch!¥7VÊR2eá�ãSRXTNáTŽdUZäUR<þ WvåWzeXæ#0îcyÕ%i e¨åé°%3"Ìc>#\’ÿÐ`VáM�Æÿ<¦Wêe$†aFúeS¦âÞýÖ`†ž†Ôª1cäfb\hecjŠAdÚ"HÊaiöÅþäžfNgB¢[‚f4–€n æ§`œ&jªf3ò¥i­Z_¾æ¤à€xާlÎfaÂ…¤§zÞ&$æfèFyjÕo'jÞã´PgYç^$gê-§ä4gR–KOv�BNgTV§W¡v>¦vä7v'…}çÑ�Éx’'VÎf­9Ùt¨çzRnæ&|^¨ Èço§}º ~�~‚Åú(§¯ä$¯ %ï ¨OF§�ÂE䨎"¨�üÆú'RBd(%„¢�„òÊ$©’VÛ¨x–ç`nÆF ‡¦'{.¡{†¨!A€–n)‰6¦‰ºä}f†Žîh~&(_ìO‹öç‹®%¯¬�’*éŒh�ÒÅtŒiŽò¨?fÝVìÞ�f§E )QLK½xgkzÝ›&)“–F¥4ª£F©¯L©TéÀ\)]pÓ–r©LÍç—þ †)ŽÚ)žšeW ©ó¸è¤Àh¤¸é¡ÆiOÎ)TÔ©¨–i�ž™½uŸ:�þ)  jªj`™â¡ÞA¢.*H:ê£Ú“”N)¥‚‹¥B¦f*t©c>æ‰ЬŽé¨rb@!ù, µÿ[Ì@° Áƒ*\Ȱ¡Ã‡#ØB¢Å‹3jÜȱ£Ç� Cn¬(²¤É“I¢\ɲ¥Ë—0cBT)³¦Lš6sêÜɳ§Iœ>ƒr*´¨Ñ£H]MÊ4áÒ¦P£J�útjÒªV³jÝ+WŸ^¿ŠKö"ŲBÏ¢]˶­Û·pãÊ�K·®Ý»x"ØË7ˆß¿P̧°á:ˆ×XÌx€ãÇ�W˜L9²å27Ø£³ç C)⢴ %J g>¡õ’×/bË–=¸¶íÚ�sC1À»7ŠßÀƒÿ–A|…q¾|Û(_ž£¹sƳHŸ¾zµeÊØ³_ŽÌ {kž=ÿOž€ùóÒ«_Ÿ Ó§³ ™o£þ–-ÁÏèÄ€ÿÿ øÀ€;8Ä�¡…¶|¨a·Úf L!!pÄÉ@Á…| ø@�;(à¡ FpÁ¨¡VÚzÝ1PŸ NÜ 0~!c4Öøß�8æ¨ãŽ;"·×_€ Ft|$¦c‹mYv(ù؃œ…CˆŒÆ`jOföÝkKÌæåm` [`½õöÁ™h ‡B…Æ­à#Ë1ç\sDò1uÕp“Ú99@ŠßIyå�g{ˆZàƒòÑg~ÀéwƒäàrxàT.hZƒ”Aá„Ãw!X ‡ €˜àˆ%*ÿq¢z)®Øâ‹1ÎX#�<öꫯoéWnµÕi$bH&é'“~b¦Y”áQiå§X:¶Ú–°yI[˜¶�¹[™ ™¦plçcœÊÍI'‘wJ—§ž‘ñÙ§“€¶&(¡ãzh¢ë-úi£B¬x_~ûõ‡ã¥™ˆ`ˆž–êd¢ÞZª…î•p‡†k‰³¦Wk}£ã 2~±+¯¿¦¬2Á Kì�Ð[G³{b׬¨‚JKµªiéZ¶/p+´˜c‚®¸¨Y®›ç¢«nu¶›E³òb+j–Õ ž”ø¡/ˆ‚é¯Ã éo’Rj©€ªî°i§5\éà³£º8ñ©©n¸jƯ’ÿȱ (vg+©"çjòÉ+'Þë›F¿\@�8D.9ÍñΫ$ÎRê|eϬýÜelCÖµ·F#�4¹Å'lF?]'³ËV=ÙÕÕ>¦õ½øÎ ûîXôî»Øïý‹Ý|?Jð¤߈pÛo37µsaÈâmqÛ¬ºÚÆ&N«à >rÉ' øù92®ã�K9åKZ¾æ18šøOëpí×z¾íÐ]ÛÔ¦J‡4¥¥n«k�º^'¿ËÈnvWËšwìŵÜíNw¾ûÝmÆŸá9Ê‹TÁ*u0¶éÍm KPÃN£„èM�pÕ«.–=�ù­{�SQøìV8’éjWè ¢ÿ’££á&0†AƒÝ÷>øI&;ˆ¢¥˜%éAË~ ÁŸôÇBÎa‹KK](À!P\¬� .çLà�†yƒaç¤V€vIÈ£í&¸µð�€¼ 3ˆà1ʃÅáÙP�¶äÈ„šJáwVø° D †¦’! ù¶½ÊÊ{‹Ä72ÃÙHˆè#bŒ8˜Ü$q‰Ltâ±3ÅZVBžÁb´ÈE¬Uñ‹\#((Óyà˜ÈT#qØX&7±0r|•dG<êÑ1·«à A΀�…Ü`ðȆH³Om%ÄóR¨ çíÏ…›¡^&Qu½Ö°o±ê˜>6ÿJ–Ò”(C¥âTÉJ¢Aá•h`"d9&ÕrŠ·„ÖgBÔKþù `|�0ñå­b" ™ÉT&3{ãÌ ÄqŽ ¬YÕ¬™„=2 PÚä¦7ÁiHáQ†xæ!òH¨Ö¹3³g)õYÀøs³gþy �Þ‰&ä¢G®o"ybýþ÷7+"#;›F8qþé!îEÔ, µ©Ç„êìVÜÏøÆƒÓñY乎æÈK~ƒ` gØ*ö±›ìr À¼‚Æ2ÕG\sßçº óµ³�¤Ÿ‡!èC·@ѹ4nr3Úhzxž^¦Ú S×rœü¬ŽˆÚÛÞÞºÁwןÊY„½ž”xÙÏnp¯•í »Ãgq‰S¼cy‡ÖÞ�ó÷¿‡<štüuáO~ø”'~åŒwùÿã#Ù¿« èOÿås¾sÎ3†Cý·‰nÒé§� ºm îÙ<ÍõÇ{o {´g{µ‡{¹¡{hwp½÷{H…yc'| bv¢µ€ÆÇiž–|wrqt7qv}®&}…¥&Õ÷q×ÇW•áÚgxÁ�x x§~É6~‘g~y’~êwsì·y=—,ðW ò‡CàÖ9p¶¥GgùÇ9ªçÚòƒñz°G€òf€¨u÷ÆuÈ{`'iÀpG�³…ù51Èw# w7wºQwytwÑ7V°V‚Âq‚¶–‚ÒÕWЂÜ÷‚Þƒàç_P„XPWpˆä‡ƒÕ¡ƒè·~‚ÿ„;à~‹‰½ÞF„ôg„F‡t°„U´|Ë…Q€SÈ„6÷±VˆÁ—Ȥ€ÅÇ…kBHm`8|8‹eX‹2p† æ#3Õ;¹á†ª&‚g‚²"+b‡·x*8–Š-Ò"§%ƒSÅZƒXˆPwˆW�ˆ¨¨9ȈŽxA�‰pw”È–(tó'zõg| €žHy™Š£¨.èH…B°Š­øŠ�‹ZÈ‹_ç‹·8 Á†Ä7i×{ÀèvÈ1ŒXPŒ ø†ÈxqËÈŒ6`‡Å¥x(b{hr1P�r��¨�OFˆq`ˆˆxƒáHs™ÁˆUPŽ»sŽAÿ˜Ž¢¶ŽÚs‰MU„À´WºV�ÎRø(W¤(…ºæ�i… Ék»×‹’�è; ¹‹É€f˜�h(Œ0f‘ÏJÉØjÉŒY\!Ù@Ôh’(¹x‚¸’ÜØzƒá�ถñßA“6©;8 :É<ÙŽ¡7zòH�õø.G RIiŠK“U§Š÷�‹Ç$‹[y�jç{^ø€ ©‹ch�Çç•Á8‘aƇey–Íx‚¹–zHxža’Sð–3Do²�-Ù�/)h²§—­Á—<øˆY �9˜ á“úd˜H8�°ÇP´£˜$™�s²�ýÈïBŒN%ÄûÿKÄýkļ¶ÄºÄ)ÉZe¬P\rLrùWÅørŇ–Åoæ]œ _ì­¼_cüd•|Ƽ‘Ʀ±Æá¡&nüÄ¥ÇR,¾t¼ÂvüCx zÌV|\"òòÇyB”‚œºöû?ÌZŠ,¶üK¶þk¶�|»‘œ»ºë«\jQ¬—SÌPœL(ž<" |Q¢ü·T¥³1pZ%CÆeÌÊàʥ˞!Ë%üε\e™¬Ą̂-wœNy Ã{ºDÌÕaÌX;ȲZÈ\{¿ û¤ «¿ÎÌÈÐìÈ´;’ ÉÛ¶× Ù,ÛüÝ,KßLá|ãl„å̼çœÎ,½büîüÆ¥ÿ†ÆÕ•½òË¡ÁüѶÌ͸ u<ÿÜS�úˬâJ½ÔvdÐÖ!KK½Ô]Æ$„ì=üø Ñ`+Ѱû̲{ÄÓh»¸ÛÑ�Ï �É·œÀ›ükVŒtÈËkï²Å£.�Ñ0�Ê2­ÊfmÓ…Ó@ÊÆ(ÀÓ‚êÓúœÖ)œËý¼Ë©ÕË €ÔÕJÝÔN /N¢½�íS�U}ÕYݹ:ÄEü¿­}JlÍ×üÑ!Ý#íD%='�ÒrmÎTR×€Ó3MË"À×Zä× Ø‚-„MûŒØ+âϼ о,ÐluÙ’íÔÍbÙ��Ù ÝÉ,Po¢!Ùciîf¥E¸Úÿ7à]2+0ÉÆ©aÊ!tv?ø3Nú”¨'*‚~4-äÑ7,:8•n�!Û"‚ÒR©oÌhZ0Òo�Ïê-†{K 2ÀQ2—qé­Þ÷]ÄãçUͦý¥1zA%¶sÅ/ ®(×ö¹ºä'(žâL >‚Ý¢ÝÍÆÝTäÝ¿Þc Þäm«æ­è=gÎÞ£åÞâXF+߸]ß�4áùÍûÍÒKåßß à´82îržEøC;•´à„Óà2òà¥áX®äóaá‹„á+CžÞ´;^K!Î/;Gâzâ)Žâ+>P-> Ù� ÛmÝmÊßÞ22Þpé¶;Þãÿðãæ ™öøcñ]ó�äON扴Òöýß à¤tUžlW¾KY®å( œ þ~sîãŽéåeæÓoî+j¾æ3ÐæSôæ‰çúZât^çwž8×­ç/Îç1îç3è5.è_@è·iè"¦ˆ®è𡈫1Ö~íFnÆ¥&éýMéªÇßâÌê[©éPÅé‘Và5ÍŽXŽà}<\ÎC^þ`.bê”îê"ëi¾á´^ë×öá¸Î;×x%Þxì°ç¡ÑçNx�~マã,wè"æZäÔž׎í�~äãqéQ^NúÍÅNÞíâ^£^w�T~îVžîÚ£EZÞcîÿNê]nê_Žêa®êc~òÞ¾Ñ�2³¾æ¶Þ§ß/×Fðjð׌ð  ìŸì¿ìßd¿¿Þ‹ž 2yoíÙnÉÛþñIÎódégòGîúÕéPöé0/ê NóðnóòŽóô®óöŽöB€ï‘¥ï*3ôÞTôÜzôê1ð.Wð.wð{e.Þ*0h2¾[È~6Žã…®±Y_ï äÓnÁ�ö#0öÇíoåK®öOŽ$Z(J*ÿO�g4T‚¶�ínIE›j")’ꉮޗª…=?/ø‰óÂý>�ø">fL#�ýnË�/ì’Oì”oì–ÿ?õ˜¯ìÌ åýìç]ñ|ÿù]¯ï­ñaoúe oL²úM>Ák/ÿRÞ‹§eã6ŒPР„ V`XáÀC§L¤ˆÂâÅ3lÑ‘ÃGƒŒqQÒdÆBTÆ`¹eËEÌLÀæMœ9o.àÙsÆO Aî ZÔÂQ¤I�-ŠÁéS¨Nu" Z5*�YµnÍiÕéÆ Ä IÇìY3f4¬Õ0ÀíÛq厡ûÅîŠyóråÛw'O�‹~ä² “%•Zxûöáã#$O®R%pàŽ"ŽlyáBâ’(ªbÃ4ËTwþ Zt L›®hñÄÿmÜtu�HаB…(G„@±6ÌŒgÀf&r$h¯I£v‰ü Íš~qöô)Ô;S¢‹ƒßqõêÔªTÏkgßUý×�b�5øÆþý´lÛ6`|¢n»¾ÀK¯Ú3ð¯. $ÃKl1þ ޏÉ(³ì²Ì6;‚5è¤Si6ÔT+€C×D‹m6ŽÃ-·ÝxëÍÃ".!á ’È?˜,Jn9�,è¹Q𮥗0ºŽ¦¹ãÉ»ïÀâI(£|’<ó¢B/½õdÏ+ À’�¾‚îÃO-¶"ôo ï"°@-ÛëIA¢šk4ù›0¢ %«ì22äÌ Ï:�4Y‘ÄÄ^;ÿq6W<¡E{‹qÆ…îFãrŒI#Žz,Ì t%"­Ã.I%™Š<)[‚Ê*Ÿº’KYÛÔŽK/Ç‚±>1ßȯLþÎLSÀ5meïMÁâôÑ Mª³±;!Ès„=1ìHCDOµ´Ó ] ÐÖDEiQÚ&ºÈÑG[|q×�(U¢Æˆ;SÓ;AÎI 2%Rc¨ÎÈS TrUƒbÕÕ(a�+÷°´ÒؾzkAÍwß ‹ Ž/rÀ�€�]3ìfàd”¯Ê,³Zv ˜c6)B·LPÉ8Ü(ÐyžÁ  ¡zhýÖJ(BâP Q5Šb–Y±£j`j¥YJÿáj¬]vù¬³4Ôð¾×‚+.M[âìsoûcmæ–-( ¸ã^ì±ÙÎ^Âã�‘„8=ªøôû²‚�Ê`p 7üpÄW|qÆ —x#Š-I_mÅ›c<ðÙÖ‘KN唣Z¹#­[væ™i¶YœoÓ™žñù' ±šè¢�¶3¢ªScz¢Ó›EJjª«.Û†Ò?àÚ,¯7›!šÝ’ëx»Ó>aí?Úþ4¤¸åVŠn³Ñ¶èc�g‚د¿ùFà|öÛ·éñ"ÿvrŒ5¾sÍõyMÏA?YåÑ%/x©‹ÐêZw‚×Ånv3¨Ýí„V4 èZ¼«šˆšv:gE�!Sk@ÿ¼åÑ¡yGx^Æ¢7½²UÏ6jc›§bÔ=¸Íí!u ȧ?÷é$}|ËaÛ?ù�èbâ‚Þå:6¾ò™b�+™ÿÀ• ƒ%‰ž)’³�õl#? š!(Á·$­‚¿›Â¡fâuÐxeáòFXÂè …(R! pƒ=í½†2< ï†Ä$ú°/êd!µDeUl~¡ Jì‡?$n®MLÄÎ ,yIt�NRtùcʼn`vZ|mçÅÜ!iTš�7E oƒÅSÚKÂ7ÚÇr4›£­‡G†Ià£/‰CC6¬*Éd¦V¹ÂHŽ‘Ñq¤3Idÿj‰’4¹$&¥IN>ÍU¼Ù]—EÙm‘v]¼ÝU¹;ôΕe„¥,+ÀA²ñ–fB?sù†]F¨—áû£Y˜½`ro�ß›!AñÈf*“*¥èûx2±DJ“r� èÆŽhÃ$fgò\7-™ÉÑõs.cê@óÉr†ÒQ±‹�w234ƒ°eF§·DT5fH©\CbÃÔO¥Keê_Ç·õ¨v³JW†­‚`.n´dRÇ*±¢ äX›ùÌh.r£Ôìèý>š·lhdÓ2é Ð5¼æU¥,=ŒKSÖ™sE4å™M;‚Ó‚è8<¥åOUT õÿ(EeÈQ“ªO­�E¥N TÝ"ÕØPõlVõÓ†²Ê±­žÑ«+\EZѲš5™hýˆFëgÍü‰•sk¢«IïšW¼îµe-m–'Ê) ‹°ƒ0¬Å*„±jôÝO!+Y P6±¹,ŠÚÈ5ÎVª e€h—@Úký)Z…WWÛZˆŽ5¶²-$m)DúÑ„Òsë5A*Imò6Ouý-p…ûâB°ÄÍr›ûÜè‚Ñ-=­®ˆ® 3¢rÔ¨Üe‰-3»<Ò�橞%¯yÑ«õ²7 îõ*|ãÊÌùÒׇöµ­~ùÖ�ÊuMeàq�{ÛÍ뵟|�€8�‹\åöÁBÿË©ÑË ;¨BÅðd5\YÇÀÃ[qˆ…0âñ‚ÖÄßV׋Úöª¶Å5 ëk)cç�Æj½-!ùßsed=öñ€}ë(àwÈÃíkq©Ø$ÏTÉB¹)“ëdéB¹±Ž½02ÌÖ #µÃ˜å2×¼üåÎ’XÌ¢=±™UÌbȸX·oæaœÙX[ Ŧ͗¡÷ãAà_ùA¯}Ý'VFØUHD±��d'{„Æ6vŒ~j˜"DÛ$ÀÀcÌk�‘ý-3gÑc O1Æ Ùgá Ì}îÅÈE.ÑŠÖ§=;Ä[Þ”·¼c$|WÅ;ë =óï ��|zquÿÁ™ ëÈÚÌ“³5.¥ë"ñÚ×½¶ÿ†]f;ÙÊn^ÆálÉ$ÚE˜öZpÍZÑb{MÚî·Uãí—‚›•ã6K¹Ïmnñ(…ÝwsëozÿüÞù¦Ê¾_Ôï¢Ü3ÿÁ þt"\áêe8hní–‡ï§8_‚}q�oÙËÎ8Èç'ri—„ÚÖN¹‘²í·m›¥Ûùö'„šÓÁæ7ÏyRv>¡žGïçz½‡.} …ß§ó·Ò™î§C]òì“:fÒKëª'æêÕεֹþƒŠƒîâU�²Øs@vf›¿h'¹ÚMŽõ¯¶]Ggx;ŸâN‡¹ îa¼Þ‘ÿMî©Ýç}× xßxš ¾ðö6 ¾_tÅ�ñIWºç"?yì·©ò}º¼sŒÐðÆd=â[çzèQ6úÒ‹õÍ6̳C2ò’ßšíTU9�X.—æ•yð;9âð¼òó:‹»¸ôÛ¸õ+6Õƒ¶´s�µ‹=ús»•ƒ»–“»—£»˜³»pÀà¾$@ãs‹ä�Ô�l>¢C€Àù‰d‹œ@6±@'ô ì>Pù>«s¸Î?ÈÂ_AÑAÇ2½ü¸ö ¹€¿| Ò¨£Mq6Ô ÿdᾕ‘²s3‰¸á@VB�>ØAäûÁÆÐ¤å‹·QŸ#œòh<€óœ'\DíˆÂYÓÀ* ¿+„‰,”�-ä ' !)[—ê�|¿4®HÃZÃ6Ì‹7Ô$947:„;ô?¥ÉCÀ>,À·\ÌE@TÀŸ _üEBèMßìàd ÿ®ú´ãÑ”J¬Ä×yH1½0hNçÌèŒÎ˜ÑÌã 2=)3£qâ�s ïÜ‚6C¸íƒ“Ð�‘8O#&ò’ ÔÐ÷|OïHµØÁàÑû¼Ïž,Ä¿9�«ðŽýÌMõ ÞôÍÞÎ>Î3ZŒâÌ‘ãÌÂäÔ™å;ç|Îè„ÎéŒëœìt,íŒ�îüNðt­Ú#OóDÏô\¨¤`O–xOøŠž„ ú<�ûÄO�Ô ÿô›ÍQWP5P�¥œ[Ф<Î¥€ݸ mÎ µP˜‰£ m€ ý©åNÏÑM¢M–òÜ =ÑîI·¸hOÕïxÑ¢‰Q§™QûìIÿŠÿÔQ8+ýÍà\ ®Rв1ÎS-ˆæLÒ%Í‚ ¥™'�R™ÒÆøÐïl³,U�¢(Qô&0½1eÑ2È¿AӘɒ8íÔEœÓ­S ¸S¥Ò‹hPàS?•P@]ÒA�®ë»ì„%­ReÔä“GåR•T¥PÑàÓK-Æ¿)V¿éINõTeÍ>PåµÓ-ÕÂ~a–á®a-Ì  ÐaàaÄôa v, æ!Öÿ"æ<Èø`$�.K¾SŠžØ–b§`áÓ±â+Æâ Øb@.È.V�/~‘†¡ n¨ b]xdH~·ÕòJ®ä7†c%fâ=¤ã ]OþäëÓŠ)œž˜@>e äBî�CîžDî#fdßtdH~dIöªJ¶ä7ŽãŸŠGN¶ÎOå;å<>ÂRVTNfdTå6äFäŽe3â©e[ö¬IÎe/¸d^_vb`æ‰bbÆ€B �çóQtî …>é dè~‘‡Žç‹®åŠ~éHÎh}Þ蜨͢øh é`i¾)iž@i¡–<•^—–&™~äÕZj¯šè|~Œ}æè¡MZŒKhŸN ^€¡îê‚+j–Ž ˆŽè¦¶f¦>ëpjþ ¯}Žê›öK¦Ð$äÅÜ«é½ùi�Dh¯Þk³k‡kˆNj@k¦VëÆ`ë¶Îe©6Dª�¹Žƒºîé»Öê¼Ff¾¾lŠbÍ.•šÌ©\ ¶€Kšy�Á¼QS=ðã?æ Ínm(DïÀlÙßÖæì~òìíµí!íÿÒ®·ÓVÓqíÍ>B8›mä¾×ÚV•ÎölÝÖÞæßþíx înâ.ÄãNnîîÔåf’æžÌçŽnÕD ê–7½<â~m¡˜•‰ênøVÖïöŽð¦ÊñNÍ8šnêNo³Úîøþo œo¡¨ïÏVŠÐÆïèÑïßæoùj5ð-DÜ~n¢¶ã�óŽ7‡-‡pJ wn¯pßm ÿ¹«ØpVK�oqƒ qññ¯p'€·IÙòoßqÉëO¡h Ÿqýx�Ǿq~Ìñçq%Ÿ<ŠV™(�r!¯ð;¨r+/ò¨PñÚeñ%ïò� ïxò(‡ò)‡ +¿òÿ¹6ò_Dr.÷r7§¯žXï¿ùGð8ó*M OX{s>Wæ8'î9Æ:·s<ÿ =ï€>Oô@þs×ôÀ!;¿ƒBŸ�CWtK¯aFomG/ò¸tOçëL×ìMW•O/uÌuu&1uVçîÙ\¦V�õî~õ÷–u[—mZ_Ÿ[ßu¾Îu^ÿõ®öu`v…vb?vdOve_vfovgvh�viŸvj¯vk¿vlÏvmßvnïvoÿvpwqwr/ws?wtOwu_wvowwwx�wyŸwz¯w{¿w|Ïw}ßw~ïwÿw€x�x‚/xƒ?x„Ox…_x†ox‡xˆ�xÿ‰ŸxНx‹¿xŒÏx�ßxŽïx�ÿx�y‘y’/y“?y”ç ˆLùg_y–·ô‘q"Ïù¼"].& å—‡ï˜÷Ÿ™çºš'¬›æœïî��žŸ¸Ÿ§© 'ç¡çî¢G™£÷µ"­«¥oúÿ~ú“ñ¬Ùz®§ú’qy«wú5‘ù’áz³O¯Ç°{äÆz€”³ïú?[‘µg{Ùçs>¸�{¬!0G©{»¿l¼Ï{ Ø{¾Gû¹Ç Àü½hÂ/ü9ü«ñûy|ÆGnÇ'|Ãç{ÊÇ Ë¿|ÙÎü¼ßü¸ïüÛø|ÐêÁÏ{È‚,Ó[—3v ( |çs¢Ô_çÕw¾L6ÿØÇ`Ù§}|³ýÛWæÜÇ·ÝG¶Þ'ÐߟûÚ÷Ÿá'þ5�Lyý‰}~ þç?å‘‘~Õ þÞ°þÛéÏ~çß~î�þküB±K~ß”}ò?}óôOÿü÷þ!÷>| ,ã  Jh(à!€ˆ'R¬hñ"ÆŒ7rìèñ#È�"G’,iò$Ê”)°ä’̘fÒ}D›lúéÿò +OzóRï$y’?HÖŽÿ}âÚs;ä@C¼„o|€3[y¡À¦O}xù\ûäö¾Ò åtøÉߨtA’$�„ÿnýϸ»ŽÖXÀß0x,1ÙØ@¬¯ ‡;\'ˆ·ø¡gƒŒÞCîçCŽtðƒ…[šì>056®j'´Ž` Eö΀D``ÃDÌ�†x¹!qØ>¸u‘‡ç"H2ø$4‚¤ˆ,8"³'5&6ñ‰ˆâ‰W0ð±�÷«ŠcØÅË„1Œ9K{ÆF�¨1F‹ôˆþ —Dÿ5ÑvÄ#¸Ç>òñ� Üâ ¿ÆJ‘3ìÙ Éõl’“S%F"¹´z �ÿ’u  3©Çtq’�°²™ ɳE.Î��£$eVÈ8CÑœm?€%EÜ Íi¶²�EISƒ )Yª€–¶lÜ%“KMò²—£ØÈ6ÌPnÅ�vÉe.k³e6�™Cq¦6%2Mj–““×dyò¹ÍÁÁ±›õú¦q™GÎUÓ—gA§:AYLQÞPnð”¢<@ÏôÙs!øŒ—�(d9g2jy&EÁ?{s§|Z.}i F“7дj¸© Ä™ô)II&µ›Ýö)Mµ¡¨F��^®r0µ©7x*TAu�©R•0K¸*V{)ƒ6,¤ò)ÚJzÒ±â--W‚fK_êÒ˜>m¦5ÿuNsš��¢¯§,ú)Py`R¢µ¨HíŠR]ÒÔ¦‚ª@ÀÒV³ÚK®2Ì«ìëÏÄJÖ“šu¥ÚL«ZÙú·¾Á¦8Õéfxj×ïà¨{W_ýŠ—ÌVƒeja³sØÜ$öªZe¬¼{Èš n™™lY�‚�³0UŽLgBÓÎÂõ³s m]Gë�0P·ºyÕëòøÚ׿ޤµ¯õAl±3[ÐÔv ·=cW�H!X®”?ù-p+KÜâN­kEn[•ûÖ¸‚¶¢•nu­›×ÓKD9à®M à‡÷HãLyÏ›‡éö!íµ‹oõ\” ÷¬°4î}‡�Ü,׳7íïÿG`ê^—À¥20‚�°`7Ø@L„‹ÞƪW¤ƒsoA2#7“Ê—¸ A9kb¹€® T¢,凡 wËî¸`œ—ÌÈxƨ±�=…Ø«æ­�¸MoýÖËžÖ™ B¶ ‘;lY´î9IÖ/sùk'§�–RžòŠ­\7“fF˘ár—g,31)¡Ñ޾1°Zf>ž™ÇiVóC،ᱼ9+qÖ‘‘ë–;“x¿Îm2tèç?s€Ê‚Æ.é -¢š ÚË_¾X ýh1Ó–Ìx3óŽ)\Tj:™œÖË�—Wd�¦ÔβSrsO¼çT÷¹^¬nu  råXëÅÐ7Yîrmÿ½è0éºÑ�–ô¯)ìHÙ)¥Äl›¡Ðé˜|z¸y¢�3�iAŒD©Ù£~6ž—|>£oÕvµ¶½ìd7'ëåäzØK]ö_¡½íu�{ègçï�|áð†?þá%ß,_óAžä å¡ÜŒ¸�Û$•Å[lç=TA•÷™T”�kŒßQ”œ'¡Rë©�Ü´�ûéüI›™P‡ÝM� ¼ ÈÞ•W „ðžÅ¬ f†j@1Ÿ§£¤ÒIÚ0 6 ì<à¦ýÿDÒç]>Õ.O–MpDÉl!îÞ´Ýê� £´] N�ÕÁ�Ü©`¡@.Á ¾¡ ú^mÕ Ü äànì!ò`òù`ãa ¡œ!k$ É$a:àŠA ¶�Na’Ίߌpaî¢ŸÊ ÚEÛ�áì¥!“­a¾!*ˆ Ùð£0ú#uA öE]$V 3â�3fá%FcCNäCDDz¢CfE(Z¤`dIRÇFºaâH¢#,Þà:¶c-ú¡â KÅ=ÊO>’‡LŽe?.a#%´Ýòå¤dÖLO¢FÌ%]za4J£&¥èŒEQÆ 5ÆÄ¦`Z�22e:åS¾`TæÒsÐa<&d®£` ¦;¾£^ô ã)#/‰/6†z YÊÿ$M†�MJÝZ¤Nºåó-K\*�Ðe]îÞ]eÔÅ[_ÂÉ_ÂÄd&aN¡aÎ"‚$¦bfÇÞ5&^Ür&'dF¦§dÔnþAejåâeænæ›t&c|æÀ„&?ŽfiFÝiêš2z\"$.ÆkÂfØ%Pæ¥PV#DîžDÖ¦]¦™¾ šÆ€šj› Ç›Fh¥ÎÄœvE�fÅ�â)Bèið)øéª ®©¡²‡‹ÎÈ»SU4*¶fÀ£þª¤*%¥Vê¥6P¦©rj§~ª†ê¨Fi©*À©B]ªJΪæF—~ÿÁ—.M˜ŠÀ˜i™ÚŽœéT!D®’FCìjpôjüjëM kL ¢±+ú|(Ÿ2«³¢(´ÞH‹"*µ.Œµ²D¶6êBj·Zä·Bj¸¦Ï¸A~"é¹fG“v꺆è~ì•R—•AÐÍ+h0Š«F¬ê«¬ò+­ú+À^€ÀÖÍš,p ¬Â2¬M8,L ¢ÖtèÄîiÅú+‰ú…‰b,¡F+•XH¢fNy„,£Žlœ–,7žlœZ­¸ŽkËfG¨¢+ ª«—yÞ²@Í"Ç͆AÎîl§j�ÏÚë«âk¬þĬ&A­šÀ­lQ0ío8í¯ê„- kXÈ Õæ†ÛRl”Z,×ÿª×l¡j졊mÇ‚ÚÇ€ÙÚ(Úþ¨ÚŠ"Ûþ¨Û~ÇÊÆ-vÌ-Ì‚ªÌÞmÞêíÞöíß–Ï ÆàÞ« äë¾A¿:N˜mÒòÀÒºi¯>mNTnÃ^®]d.hä’ÄÚ@Ôå’ˆjíŸ~î³~-é²£Œ†I�û¶ï+MDÒPHëî¨RªˆÂήwéò�Ú‘à®~@Ì:©}�@ïúnÍ/ªê¬ð®Goáo˜NA$îâ6®Òêêj„Oìj(åîaf¨ˆpš«B@÷~¯…/óZÀÖ AמhÆZHȨïò´¯ûSE$Mkµnk}0‚|#â]þz€þîo)¢ˆÿ‚ãfÿÆðÞ>ëëÏæ’­áŠ€­­lš^°èBîchðX\ók¤pŽp Cøö©ø6+ù†nQÐI ŸÅúÒð¼ï@!@‡Åeì°^¨ˆçi]¡Ïﯹ:颢Ûÿ®©âl®“bR/@Ðf1lq ;ïC/«ÿ„÷ŸÕ b&&²¾ñ²Æñź0¡¦ÔEÓ0G–V 31rFß!O)ò�qÀò1uF$«Õ$p%ûí%/p&7°œü,'_±'ƒ²˜ˆ2®‚ñãfpïl°*ó+ðÓ«µ¾qȲç²0èÚ²èâòÁÈ0éèñ¤Àü²R³Rs1÷ð1#Ä"² x3³,ÈòU’ ¬!5ëÅ÷n?q )&+©&3áZ1cqÓL0Ñ*.3®Ÿ3)‡±:S;ß*³r¿r Äò Ãq ¯p ê>ÿS./Ä.·¯@A_…A_B³17åá5´2'² ,r~Vt%atYTóK]³ÍfsðJ13“´ñæë8¯t¿´ã,H!ù, µÿ™$@° Áƒ*\Ȱ¡Ã‡#ÈD¢Å‹3jÜȱ£Ç� Cn¬(²¤É“I¢\ɲ¥Ë—0cBT)³¦Lš6sêÜɳ§Iœ>ƒr*´¨Ñ£H]MÊ4áÒ¦P£J�útjÒªV³jÝ+WŸ^¿ŠKö"ŲBÏ¢]˶­Û·pãÊ�K·®Ý»x ØË·Š_2€sl °a0ˆ;ZÌx€cÇy"KÎè²e˜3kÆüø1±Ï¸BMš�i>™2iÒ¤¹³ãa°�ÈþC»öàÁ€s“¡Ã»wˆßÀûN\¸¡ãÈ(_óÞ¤‰HŸž8q‘ëØ]Øl²eÆŒ½WÿÖþ¹<±Þ½¡¨_øê÷š×™_gµwí�ò‡Æµkרÿ£À€sÍrÛmµ¥– c&¸&Ù3ö·K%Jbàr(¢ˆV,8˜iG”ø#FFÍŠÃ-âb%Æ(ãŒ4Ö_}ýØ‚†Và-–âd”‰Çwä�&i£�†šj¬e¦lÃÈf„ˆ"êz¼µ÷[q`ö�\ràÜs¼E7�t?‚�]v®q'#A:2g’æqIÇzìy™%ôÕ§É}®å×È~ý �z¡ – ¦á�>c!†•hX ‡‚ˆe$šhß�+RÓâ‹6¦ªj�8îåW¹‰ÿØcamÖ9äds¹žû1Ùäi©­ÖškTZùémZîÆ¥—!„YܘǕiæ™^@7ÚšlþøæuÚÉ)^�wºfÞgzò©³jŸeøéZ¢ Xc£�Š郋EØÙ„ö‡©¦rúaˆX†zĉ¤²(œ‹‹À¸ê÷*À«±ò8k›HîKd‘Þé:lgåõê«“ÁFɱ±Év,nZêɬ³ÄAkˆ´ÔV›æµØb¼kœ›Í ®xx–W®¹è.(}ëŽW¨»üù/£Ê9Wï‚÷Nªq•^šá†ËuJ°ˆ#|u©§6 ñÙªJLñŽ·Íj€ÎC¶q®Ÿ ²’¸øZÉPÆÿýZÊW®œC².{ óp2ÓL­µ`KÜRò¬Ùœn‡{wž\š EÑÈŠô ì.}è»Nÿ'/�ô~Zu¾”ö{áÖ›v=ð§a�:¶Â}0ì0ڼ˨¶ŽdÈzñ�?¶1Ç—Õ­ïåû÷«i%û=@±* Nø²†.&´ŠŸÉ¸ã�Ûý˜·Þ¹í`&J_.tæDûi´çó%�¢èˆ–¾è¼Q'¨:mZm|dYóì&;OŒ%:˜íþ—²- U½‹à�”×CX0Yƒƒ s"#íŒ�¸Ï&FHÂâyoÎÛ°ú¹ÎP/p+»z^¦=ÄE+5óizSêâŽÞÿÌç ô��ûé €4Ç9–© tFtŒ¡ê§¨ÓÍ(u�⟤Xwµ¾.S\SŽ×h‡@Q *a¦z Ù$Ø»åTð‚ZÊà ÓÁŽ}PnDÒ KxGÇ„,4)ä›°Zø˜ npZ:€"ÉC fdš–4·CÞôP:Ê[ž¡¬d¥!Îê|QÀq¡ÄÿH¬féú¡:3EÒUj’œƒ´ˆ/G,�^üW;4»&Pl t`î ÈF´¹q/<£A1pP~•1ᎧÇ=nBš¢Ä›Þi²[þ­JÕ‹a"©ÈF:²�¼¡$)9Òf:™|Ì&9iOöÈrGL"otÿJj¥2~Pœ+™/ÓÁRjûûCÿ¸ÈÀ\p@3 ØÊ¨À3Þ.�Ã\c1ÏvL$s™9hæ3Í>æ�žõô•5¯ÙÇl"qILâ¦ô ¹ †1ì8Í)9˹™s¢ÓY‘t; àÎ?ÀSyòÌJíi|úo¥E?ÏôOA­2©£kÚ+ñË„.Ô–­³”Á;1ör¢¿\ …©»�“‚È„£näèL:B“Ò<)=«¹Gø R3£Üæ ÿêÍéND6uQNuºSs:’JT²áÌp8Ô¢µnX]ª¯*4qAuŸ¦l*ß÷Ä«J‘ ö³¢Œ°h/Zú—®ÓeYy)ÑÿÕ΢ÁÄ][Ý ±Ž~4ŽÌœ£ê˜<¿é•“|%¡_»‰™ÀŽl°ÝœÒakšØÅât§p¬¡ É6ª²–|'&‘zÚFh–Iœ5­KõI~ŠÖŸ¤UeèšÕ‚Þu8”å`VÖ.Æö¡4kmos[�®U·Ääm�6Àà'óXmÂ!ñ(ë^ ™Í‘†¿6fYÃQFœVðx³<°H±ÛÚ„Ýne°·ˆ±Œk¶Ò€X ŠÉ×f6Ö€ûxÃ憫 ðð*4„H2¦bÄçˆh= Ü¢�ªµÝá׬«È²–隘÷¸¸¹Ä“¢þ3Ú•µi¾Ò†Œ‡ã‹6+XÿF v°!¬­ëLxšDú0ˆ�ÌaÁxغ71‰EebÏ#ŰXñ�´ó囀2ž1µj<šçØÚá±�{Ìg­É®F6ô~’Lˆ%¨ÉÍy²z¢\KLSy¬©˜–·\#ÆË’{t˜‹3æQ”™ÎÕA3ÊÔc6»ùÍŠ3ƒü©ÛY|ŽŒž1Üéýy±�^ЈÃPâ׺ÑŠ®£sýbHGú4V��A|éLiÓœ²§§c€0¬&ÔÌC²’1Ää½8yAP.‘”]í_±~1Ö²›u–¹|ëÕ4ú3bó¯›ý#a»6kN›}�ìd+›ÙXrvî¼1 K¬Ú·ÿ¹vN³}›mw›¡O=´ŠgåTF;:3æŽtº¡°n ·ûV‘�wP>˜é„ÁD¸wcD­ïRóûÔþN5ÀW-ðV»kÿµò®p†ƒ×�ì®wH�9”…Äx±5~ìŽHÙ¹Ùëõ‹Œb0ŒÅÈ@LjscD€tÓ±†›1Jé‡!ªP‘)zÉ”LwG�XLji‘Ž(;e¦� W‹ë8.å&˜(š¸SQ(…ÝE…5ãVæø{·ÿ¡Ž Ø…©ø…«øŽ¬�e8�ZR�khh¸È�ê5'Ë Nù”�uŒw(Œy(ˆw—�DZ� ¦ŒË¸Ž`öRègƒ!Y‘™‘‡°‘™>@Xee© #iV%)‰'Y'b§’,é�™Ž0“�ø‰5¹Q7‰Ž"¢“Øä…FàŽ@™#BéD©Fy�HYx¹JLéWO •€%•ºa‡P€‡Ä¨‡+Šycù�÷‘x3‘•ð–g™‘jÙjéP­Y–qÉKsik_—�)©’–Ø-ù’䓆Y€I-lÔ=ÍÄT…¡ÎiqƒRÂ{Â`Í1WƒÁiÅ\ºfáèØåc"ÿ5<»É�ÒpžèÙ<Âp=,˜£ä"ŠwÎÑLš3Rs¢’^Ôkã!Š ‘æÒž,„óBœÀ ƒ� ƒp›ÊÁg‘WÓñ”ù9.`rc‰µ �¡zu’1's¢¡Ê0 ªZU&õ©AÌiΩÐI$ÒùÔ)Š×Y1‚¡�f„Mß9áÙc|'É£žÀyP  $%!ñ¹Ud¢ÍaŸjW$…W›±Ÿc#þ  |b¤Ñ5lVr  º ×¨g¡NI7š±1šX š¡*kÊ"š $Ú[Lê˹Y³²¢-:/: 1z…0£l“6ZQ8Ú—�±£ ÿУ·1‰@J$BÊž†áž¦Ÿx#Ÿñr§Ž*E ¥fšTª(Vê!Éä+ŸZÑsgŠ  ªzË1¦Ò!¡t¦D’¦6§mŠ|¿bpŸPZȘáEý›È¹kªdÌ:¼¥NF ¯9ëÄ~a­Å»&+ű’1¸’�xWÜÉ+Å,¡,½ÀêÅþYʧ,¹ªÌÊ%¬Æâ»ÂY[¾q,Ƕø¼…;é¾zœÃò»ÃÆÓÀüÃNš¥Çü·RJĵkÄÌü¿Îœ–OÍðJÍÖlÀ‘,¼ÙL¼ŽÓÍÙúÀTÁV<ÁälMæÌ%¢Ì;_ü[ºAuÍ·“£Š†ð¶&ÿ¼)1+<|‡®�žèé>ýÓ“Ü6©{Ua)2è5Ô×J¸p�ÐÔ˜ˆ38J=˜âš{¡a«€ªêñ9X©Ô…Aª½Ã7V„Ì’™ ýA2'æ6h©_Éâ$¦+-·s˃/½‹2]ÓórÓ“Óº¸Ó<- ÒÔ„�ÔFTÔ0Ee›ÔLÃÔNÍŠP-ÒHpX%¤W]–|¡Õ\ ^ÍŒ`mbÍ;d bfí%hý³ß²ÖâÑÖ³òÖ¢Ò¢`u-³\M{¨×>i|�:~-Ô€�v‚ÍÓ…½Ñ‚|ØÁm`Š�7ÅÐý¨Ô� OM˜ RÙí’UVM‘š�Õ ²ÕwÿíÙõÕLÖþû0¥�a§Ý©í3¬í®Ý#°ý>²]&´½ÈT‰Ûµ¨Û‰y½}E¿�ÜέÓ�1Ø„]&†-��ØÝiÔŒ�Ø Ý¦ÑÔÒ-ÙÔ�“RmÙå…ÙÚ’›ÝÝ�ýÙSÚ£�6çÝLé ë½Ú>ØÚÖåÖhÛ¹1Û¼UÛzãÒ „•ܱ×ýíˆÿ�àNœ^ܱxÜ>žÜIè\GmäôÑ=ÝHÙ~Ý^›ÎÝVàÝž âNÕã-Úå½*ïxâ¿Q�ÌR'rÍ&×*Ò²˜ ã6i߉×7ÎŒ9¾Û;Îã�ÓØ>ØB®Í ®Ü ¾Ø£èRÎäÿÙa8Ù9`ÝK~Ã}�ÙU.œýÝZ~è¸@ÞmÞ¬(æ!@æ^bær�æ8²æ‹éæ‚ ç6žÛ’S*:~çÓã9`è1‰ž¶ûçÄKë‰7èÌ�ä{Jî$ßéå¢óHÅ�Õ”îá–Þ Ýå#>Ö­âé Þq-×þéŸcê@‰êÅDã·ýr[ž®nç°ëyþ׿®°ÚaëŠëD>ë?ŽHÞàJN_ûqæÃþâ¥hìô…ìġ앞åÎâÐþå3í Ç,Õ×î$Ùî!Û^&lîíÉ©êrÎêIhå¾ß¼}î%뺎xîÎ ð®ç¾¬àõ^èóŽïˆ.ì­Bì…ÿéïXðÃ!ðÌNð‚"ÞY¥é€ÊFCíiÈ,¯Ï!Oß3Žñø�ã˜ÑñÈò!ŸîÀ½î@~ž·nàÆ�òó‹fËÍT)ÿà�-×µQ2_Ý4_^6¯F ÓáWþá¿å"Žðœ” ?ô^Rô¦qôIßQïhñëôâþeRÏßT_Û^/Ð$¯õïÎõC¾øÒ·Ü`2òþò§qö´‘öΑVwìù& ÷XN•à½óÏÞó^¾égÃæ ðú°ßð¿Á÷|à÷jNñ§ÎôoÑ5žñùÝê+òêç®øê>öY/ [Ï!.ï÷¾¼^ù-Ù˜ošÿœÕžÏómŸQoÿoå¥积ñÒŸé«ÿóäú°ÿú²´oû¥ŽûÝ®ûÅ”ƒ€>+u$!�h!²´L  PÐà „ ,d¸ÁáÃC9$N”xÄ"ŒŽ4šб£ �&† ÃU’ÓIH ôâÅ EŠbdbɦG�!A{ö¬ÏÏ>0éX<¢É¨N�8;ŽÔéÏQ¥Ê¤*†(Q=Yµ*å: ÏWZaŸöñ¥È¬Y+/aæàÓ–¦ÍHŒ”~ýJ�š¼†ôJâËÐï_À�«\iPÀÇ /&@ðcÈ‘%O.ØÒ Õµ4o6ª‰Ñç¹L™î"]ÚñäÇ� L¨ð/b‡׿ JS£ÿ#Ž8uŽ,‰ë$§”* ·T»–êÛ›J‘òô T(ÑÎHsãd:¨Ô©U­^=¢ukWœtÃÒ[ö¬¢´³ÛòAw.]»x�è5ÄWjüùõïçß?på–0ƒi3ÎŒúL®ðD©4Óü[HµÕZC0Ø6�m­Ú2ÚH¹�x3 %†si¶ŽÃ.®–ëÉ©ç,Š)®ª³®ì¢Òn»«¼Ë ¼ðÀë)óÎJo­õÚCÐ#ºòˆ/¯½úrðI(£”ò//“)3 èìÀÐåK0OóBÃ$„BØ.„)C0n›î£Iú¸Yq6kJN7�˜c‘¢¡\< F¥d´®ÆnäÿîéxDÒGò€<½â(*òD›Žì(É%çkò¾)CuÔȪ�¢,µ4´½óK1û#ó ÑDLMŠØt“C�<ô Dáì¬4¦™0�$Å>WtPèÕ)Æ‘f¤±Æ°öÚFõ Òò&¦Kõt¯Çºîb²>'IUwÝPM½rÀ,·dI‡yÖ'ge­Ö×Ò$Q× ùìUÎ_é Àa'ÊE^wRö§‹r6$h›šÑj¯µ6[GÅûÑ© ÑJ˜-·ŒÕtÛrå£Ï>v[vÙ?wŘ š ôìÀy7�´{G‰•¿�ªz5h6Š+Äu"€qkØ×ß‚HÄ‘K,ÿV\dCòsÙ‰•XŽ=ªw,ŒµÓxcB;N2�žš#ËÛ‘Ã…ëdNÍõÔ�—óÖ¿˜g®Y3yqîr˜Òzþy¿ …¾ñhš“öw¶¦ß`7‚£®aÞ3§dÝŠYAÁN[lÉ®‘ÔS?û€°Á[›í‡C¦T½’Å¥>»éÛ{wÞë["£mÆ9g¯vÞÅð|ºŠÅwüÖ/ÒÐi�EªØ©…Íüj†«7akˆAÿºõÆ~ ÑÔU?›|®^o(Ù¿µ´ö¹ßKùÜÞóçý÷‚|UÁµŠp<»×áô“8æi‡qHÓÎzÖ³´ŠH¯MãÜÀzc¹ƒ €8ÛC{²æÿ0ÏEìEÏ*TéÎwºô1`uì³]Þ÷“øÅ�~™ja§t§?¾ŒþSÕÍH¯ðU?#@�xD$&qyÍ;Ú�ØÒF‚»ªÔ°W ÞÉ8ÜËÔðTBñu.Ý#�hqF4C�kL¡ ׇ”á1B:î‹ÜhÇ“Õ0wzÉaٵÿõ0Žƒ+\ÿ’DD&r‰ t^ŸÅÈ=ízËæðÄŸx±sêZ³41ÆÍ-EAhLãÕØÆÂQ“:¡£ÛbxG#éQe|ôc-ÛU�å­B—X2@&|9H¥¬Q>• f1÷3)EB™F+@3�¹D9SšÓìè ¼áÿRˆa"Ìb¨²@2„Ó—™¸ÍmÚ÷•ÞL³ÐŒÊ¥óΤ4 $¯{],ìyÏrj$Žò‘�™ òMÆ!*ŸŽh£e\cK„>É ¹Ü%¼zùËlS�Ã,&1�9)e‚™Ô„I4ÕÉÑXóšÿó!—XÈ!vS1=Z8É0Î�ž3ééD¤âNx’oŽôLÒ=ñ™Ï}òÓþ,K�&Ð|´%MhS÷³P¡ér¼'0q"L¼TÔ¢úAfF7*Mvbç£ )6¨³ ¯€*M€QiæR˜æS¦4kGÛ9±œŽN¬ä)]|jÏ�•ŸD€[¡€Ôr*Õ Lujc)ƒË¨6ÿUš©jD¯:Ѭjõ¢çñ*ÍyD�޵™Õ© -‹Öª5¥*ñ¦LÀ)N_ÆÔ~t}¦]C€Ó¼RLž&è«_ÿú[ÁöSBÿtm@k4PÅ2Ö±Ë T« UªBô¬Áª´Z‰Íž¥³PPç¢B+ZÒšÕ¤@L­áØjX¸ÆV®³-‰:ÊÛÜJnrHy�P�ðÛßA¿ûµŒeÈdXD…AÀNK�­`Ð 1WÁÍ…ìs%;‘ÍTvº¨îu³k–ív—;ßkxIjUÔ¢”›¬]iq[ [r®—\´­má›ÛÎsmöÅï_÷Ëßþzá¿&>j�L`x© ^p‘³¼åñ2ÂÒÿåŠ)Õc¢Æ Ú]&ãj+Å« ÊÉÄp¯CÍ:8ã�x ‹YÌk]JÛhD¦¸£Æ•mZ£MÄYÎñ�1og,ÔûôÆúͱŽ/g�øÇa²ÌddDûÉBS2e™,QSBy«�•5jåc™(«Ûr—'K À�9­b™cf—¦Ùk.W›3ýfìÈyÎ0Þm}ñœg{î™}ÖW¥'%èúЉNô¢«Ðè‡fb¼Ù²¤±+å‚Xz�W^§�ìiÇ €¢./¬ØZfÆ�9œªfµ’ìâf‰ JÖq¦s­ïÌO\çzϼþs´íãA ›_Ä6²±‘-á&;ÙÙ|³wÿ2«|4jsÇڦĶDRj†ÙÛ$&3ªÇ=½rÛÅÕë´­TÖýñMè)·oŸó;ï÷™À²�‡Íï";£M•„¥ÓìŸ\7Êÿ)øv¿Ê4…ŸmËÒ zÑ‘ qòJ|ª`zÓM�€>‹ÍÓèë4îÌ'òAÝ —õ#¼þuPF¢3�!¹PMnc”÷W哪Р ä—Ã\Á2Ÿù!j.Ý› <ç:6Ï}mðK#<ÓÕº“‹nt/˜xy¨J›îtSG]ܪ®úÚ®Þ̬o�ëqþ:ØA9v£”�Ÿg×sÚý[￟¥íù†û¾åÎ\;¹Ä R]Elûq~B÷q|].|ÿ àÃϾ0“±˜*·Ó„&¼_[ÛÚ¶]ÓäëÒ!åí ©‰iÊ"›½dÝÞ ðß&Ž[Eù± ƒ˜ö&‘®Ç²ÀB¯ý<��ÑèÿzbÇ>-´¿=î}©ûO`¾$ñ½\¾[>â“ãcä4åÈrs¾ž€¾=“>¯£¾ê»¾ìcˆí£”î›*‰ø¾ðÓ§á!?óþôÛ¿õ#Šp¿§X ûÃ?D(ýûÀÚë¿ȽÝžÞû½àƒ¡á+¾E;¾,I¾Œ@ ¤À³ÀGÀ@RÒ@•àÀ‚S?ï4ðkñ+A'+?P8¿´Aö› t $Œ<ÃZªAþÃA @ÿ\4@\ µ Bq;Û”æKB˜ˆ>Œ˜>¤¨¾F°B,Dì‹Â…è@*ÁA,$Aœ1Á.DÁ‚XDèbA‰C hŒDCOì5”*ÌÁÿÛAœéÁüA²>:„ ;ÜŒÎóºâîáþá&Îb¡¬K¢)´º;Ì”ºBë-.ãf}Ñhüâÿ0·B3c7nW4æD5^?1²7¾cW�cv�c<îc1Õc…õ >öcBÆN@^äB^äN]AFcFŽä?vd†PdI¾dÔtÜ�dLîd¼ÔäDædOå„eK&eT>CSåTneW~eXŽeYžeZ®e[¾e\Îe]Þe^îe_þe`fafb.fc>fdNfe^ffnfg~fhŽfižfj®fk¾flÎfmÞfnîfoþfpgqgr.gs>gtNgu^gvngw~gxŽgyžgz®g{¾g|Îg}Þg~îgþg€h�h‚.hƒ>h„Nh…^h†nh‡¶çÏŠh‰žhÿŠ®h‹¾hŒÎh�ÞhŽîh�þh�i‘i’Þh¢1“Æ@é@fˆ’ni—~i˜Ži™žiš®i›¾è“–�”Öé•^ˆ›þi j¡j¢.j¡ÎéÖØé¤îi0j§~j¨Žj©žê™Fê„Pê«fjªÞj®îj¯þj§&‘)©SiDk´Nkµ^k¶®h±k:(kž>ë¶®k»¾k¼vj¸Þë¸7³†Q–ÎkÁlÂ.l�þb¾†k©+Cº6lÇ~lÈlÄNl²7Æì‡n`º›9Ê®ì3[ oüÆÌþ_¢ÙìŒêlkZlÆ íáíù-íE›ìÎVí£am_pmùõÝ[‹½¾‘ÿT‘  �ÂmÈÕíþâm¸öí,îŸnZ"îÇ5nË@î±Vnaî>pn¼�îèž”p$-‘²îÍÀníæîî>�ï–ˆÞÖŽßfîò6ïºE¦ô©äfïåvoç†ïøön okÊ�É;S2À•Q\ý^Xùîoõ®ïªH¥>q2ÿ”?Ù§M@apªpp­�pà+p‘�pwýâùÞëÕÑð�àð[ðpÕ§qÆ¡Ð?Ð=(ñ7zðïp _qEmñº[ —qðå@q×ñD5 ¡‘º ‡ñYÛwîÀ†é8žh#Ÿ$¯%¯&&ŸT'O’YÚn¿�é)—è*—’+Ïòÿßò ërºørÀs4¦ò2OMÈBsúVs¤eó¯póCŠé1�è9§sHrq[r mòËmsüés)�s2t¹òþ 'C7ϱcS=σ/o ŸösGtH‡¨št2¨ôqºtkÍtíæô¦&éCˆ¿nÉPïI· J×rÛKwí(vÅ7Û–áwg°n?3Sw{7ùÈ÷çŽrŽî÷ÿºSw—bw�gm‚?áS6㘑¦pZ”’²VA‹ßÕö7—è.²µø±F;—©#ã Þø2îxgúxîy®ù§(yY‡Œ‰NyÐ… –)—÷ö‰ˆù{Ñ`š×b›o&œ¿ �W žw ŸGvˆO$¡/°•¿v¸>z„'zq“ùnú,~úˆzè˜Ôª /v=ùˆÞzù�y¯oùyù�ºazVvc´W{aûêÓî·g‰¸gôÏúbL´ûuÿú¼GzÇw©¾Ÿù¿çxí¤ �'�'|R2|¸gj¹O¢�`üÆ/zk{—êú3«ü²¿üšÏ|™Ø|¢¨ÛŸzœDÐG|ÿÑW|$*ýºkü½¿{£�ü°§¾oÛI›_³oâÀç|‹°ýÀ}�Ð}ç>üÊHü0O$àŸ9áG}:@A¬—ä?ܾc~ØwzÙÚ�þÛ÷|42ü”ëýí�hÓÇDðÿê#q1V*à „ 2lèð!Ĉ'Rlà"Æ?7úêè±"È�"G’,IQ€/*hY€ ™#2kÐÔÄèæÍ:wééÓР*‡zÁˆ1¤•¤J1mšã)Ô¨OaR%Óè*Ö�;±bæõë³°b4hò,Ú´&Q² TéFŽ;JªkW-Þ¼zñ¢ÊÒ%L™GhÖ°‰“QžÄŠ}ÿþ ”¨Ê¹�^\ØåÛ¤M�J]äùó…Т¹^Õª“t£¯`ņ%+°`¥½²g§½ì6s\�’}Ù½Kû7pà}W tù2æÌš‡+N̸§ãÇ�wS`ùrf+›™JÍñ´èШM@­Ú+ëÖ®ao²:üømCöÒ½þüúñ—­TÝ=€F´�"U®é± # ’‡Ú~}t…v7 †²!‡õuWLuˆ8"%šhŠ)’—¢Šä™Ö\b»È8#$Úè�|9RFd÷E¸_ÿÝ8¤€(Ua�µ  :ò iNX!…fˆ!‡ö(ˆdŒH¢‰%²ˆÿâŠcºø"Œ3ÒH$›èøf<åã�ùIY›yþf$�F%F‚1é$”\I)•UJu%–Yâ!— ~)b˜bšiÚ˜&œ©Œy¨)c�zÚ§Ž¶uIg�}Üi”¨­æÅç~B%F’‚2è iî7%•Ýññ+°Ž>ºeT]NZG¦™–Éâ¦;uúé.¡ºê©9š "ªu®zÔ´Ý–«¬O ¨ƒâª•®úñj¡TÀë(¤ÅJ:i²—j¥l³<û©´ÞþV­|×V•í�ÛVæ/Â�+•@µ–{듹F¹+¢‰úê.ÂÆ •±ôÖÛâ½önº¯šý&¼Àñ LÁöÿ›Ö�<óC ÿ)†Dd®#Ì–7±º÷Ú.ÆËñ¼_~ òN™z&ÉkÒŒrÊÕ­ SË@¾V��S{��ͳ D„7yîV@ç·®¢Qaœ±£Ý}ârŒ,M&¦c>íbÔ ~�WÕV_vªT©Ú¹u̬þýuØâ ”³Ù{§m(ÅQ% ÅÅî +w¤UÕ}·¦y³(9šÍAkòâ%U—ÝÛÕuÙ¥`‚Îâ]§Þm}tè¾{¸9�• Ïäá2<ñ¹ýAòÉ_ž9°ÛõžƒñEH?ýçwor=ö•‚AºVÄÏè(¨ß.QuŠ˜>ës²>û¯ƒ»L¨¥÷ŒÁ2�ßfùëŸÿûîº÷NV’‚gï ÏxÉK-¨@ââmÎëNô¦'½ê±è¼ ö²W)îí„�àßýR¾ó™/}îb_ûÜGøA~é©_ñ§¿üñ¯ÿû�»G@� \ ¸æF‚\N¦.ˆÁ nB{Ô‰Bo Î6m Í·1Χ%ýÓ]’Âí)Ñ‚X!^ò`# <%ìMx#ãøÆ,*":†ø°˜Åú\®K_¤a㤽)f~=$Äy†ñ"i0²‘®! TÞv,MP²’�j&3É€MrRlbL%CIÉæx…xŸ±ãתhE”è‘„œ{eº(ˈ1ÿIÚ+‘§F6"Ì�rü%íˆGFµò||L”¿HšàK_‰™_3¡ÖHG>R ‘ÄØ±ÈsÉLbryŽû¤L*™)RÔžQ:әʭ’-Å4,¹8KãÔrŒ•ÂåðÒX�5*®—:ú%0³(ÌajÈQt<&•’Ù¿eÖ ™…LO4ù6MFVÓšO‘䤴 #nvÓbß%%Ç©˜Rï3éT§×T¹JoÆ3žó¤g-‰¶Ó\%—„Øe?ýõ¦æ�p-�J šE¶AA¡»c¨Cº|åa¢Ò¨¨®é®ºi´9mKRMˆ41$Å…IOªŠuåjd`éOåùRZÆT¦øÿÄ…>+ÁOnù3Gy©SÝ5¯œ� _ý ¢?ÖgÎÌaGæTÄ^c‹åÔF9úXpAœc"§9!Ö±Î,`™­Êf_ûÏ@0¢u«ÄaSœÒuµ9R!ˤÛ9ªÐQ¶U¡í2#:€ÜJs¢¯°*ù[g9§'Žõ¨ï Î�w¤å,é9ÅJ3ù€&ÑíαºC]ë&i´o�ë\VWŒ8¯Àdïx±Ï>Îö‹ìÕɇµy(¹Á÷Wò]NÿU}BÇáF¶¿^ý/XlÙæÆÇ–J‚;ëÙz:8»ÛMmN©H™ Ãò؆‘Ùáþ…8Ä/qwJ̇&Å=Y1~µº_®ºx²0®,JO†‘úØ¿¯<–Ò¬fêò»¥Õîio äîz‹ŽD¯‘‘†dXf'<¡éT“ïÆT(3L ñ¥ä|u²˜+g‘Å[–,eeæ6^„̾qTЬæ4ÏO–mäƒQ+WÕÖ9‹wVaž§‚­xöÙÏ€´è>6èÊEÙÐ&F4ŠK§âFgY¿Åå/‹� `å ˜Æ°4x1 MoºÓ]ü4÷ÎgîJØ_vÞŽ…S�×Ê­ÕáyõÒ–ÿ%ëÂúfb8´aª¬kF“ÐÑ¿ær°ý›ÜåºJNCqž,C ï} ßþ>äsŒÀ$&e +b‘%…ümš€ºtb™QPÞ$¬ê,×v! ·˜…÷›…‡üxÿ!„SX‚l�zÕ P9úùLÜÇ poîÍ]•tÈP3£ E‹^س–ß é/K�õ¾ŒÆó½o}ÇàÏQ¯ÁÃBr…3œ{}Ä�"qGQ\¬'eÊϘ{äfù~H“W½g"ñÛ°ò8¶üå1ŸùóÞvs”ãíg\Ù9†z®•Ýׯ�÷‹ç]lQÙ[% îâÒ™Îq§3êW9xîïÿ¶“–¾yx¸Œ"®£‰S¦â¤»à]9vŽ—ÝìG»~ÔÎöà<î*ŸûëÎÄ»«¤)]Ì�Þ)YûÐù+€…à Þü÷ð)vŒ‰=cÆ#ýhÓ…|ä›ÞCp3�¦�À¼q4ßoÎWô»}ŽHoÓõ;,É¿CrE�yæKþ«“»Ý¶M‹;î垟ÙÇáÝïŸ& ß䟌ðÜû ÞÏ-_Ð9ŸýÉÛ°Ñ[«4ž}è˜qD^Äœd)UÜEÝ3LÝæÑžÕ=SXd�!l]–tÝI}]D`Üù´”üÅN§ÔŸ t 1ô ÊÞþµ]ÊÅyœîeïy�ïðaÿÌÞõß^Åñ%_jóµây™âMŸžhàãu`öq\âÖ^žÔåÕ¡àLÝ–ù¡Ÿ|¨F°�¹ßEÀß+Ý `ä ŒŒ¡þ`þ­]ªáúß™áî^öS  ߟÎ5`à= òYáÛóY`ôa`›`ÖmXAK±�‚Ž ø¹„ø-œvž¢© Ö…žÖ�ž£ü‘VDTÇPpT|†¿M�þ"fabôa!ðß vŸV|…!†¬à¢"#ò�‰ôØ›ùøPaá5&V`â]àⱉ'*E(Â'q)îa~߆¤aÃ×ç­ ,¶à�mÿÇåüÑÉ EPF.®šÜðb¿ù"0æ £1"£í¡N0ãsÐÑ3úc4Nc5ºÙä`#£h£^7î &‚™ÑåÉ8&E9ÆÎ9nR:6‡å±c ¢á Æ£çµa,…óä£>ö?24Váòu‡@A¤: c#1$¤.$!.£WDòÉN.¡K4!5–ˆ5^dOd#%ò¤'aa&~ã&†#‘Œ$(Æ �$¤ä`­ã)¶D*’ŸÃÑãùIQÔd¢Üdÿ<Eì¤.>ÅO¥P®%QåüTÈì Ÿ2ª×N8$c<¥‘Då"2!°T$LzF^‰FZ"GÂÛWj!8ráX^Æ[�£YšãIª¥.% 2Ð[®bWɤ!Ô‡]R ^îÎ#íŽH$OZ¡OzF/JO`eg#1¦þ#ç�–L‰RºáÄb6åCfQDÞeeFÛU\¦Ö!nãVEx†'ô�Rtè Y–¤` %j£2®&µæ ½¦\ dÌf…Ô¦îܦdä&uVbOv†o$p§`gQgzf *'ƒ2ço1殑ÐtŽY4Z§UZ¤efeFn¥wnYxŠçGz*�D@!ù,"*¼üÿHP €ƒ½(\Å0‡Ã‡G"JÌD1’E3æÙÈQˆÇ�±BŠ4E²ä©“(g©\É ¥Kg0cB™ISbÊ•�1ÚÉhØ0e@ƒÆ4B4ŒÑ£»’*MÆ´©«§PsI�4¨®«X…iݺ¨+ÃUrK¥ÅHÒªmĶ­K—"E¦šK·ÕJ•'y2b[µiS:€Lø«D»wQ:ZÜvjS`�…ýš<RÁ˜1'XXx•ш(OÝ͙фϪÈ�A¶•²ª×bš]Ø€íV¸ïªÌ©÷gÕÕ«)»~M¼ ñãÈ "LÈlØ'V¼XÚÇŽ=Æ YÒdhѺ߶ÿŒ)“æL›'Gëäyºª²¡E�UºÔo2¨Q§Ju¯ kÖ­ZuµÈWÏå@VY'�¥ÖZm±%ÛÅBW]ºåÅ_AÙ—L`‚uÖÙaž´˜#�IõXdÂýbA™iÖaŸšz¥µTj«µ6q±m0Û!µÝ–›n¼±çp�¥ø qÅ%礓ˤ�>]DerVuÖ]—GvÚm×Iß�w׃äÁdÞy ¥‡Óz;Ù(LD!ß|ôí¢!~Oé·Ÿ{þ]`€^5ôÜ�c™eÑ‚i5è xò!©¤© ¶’…;a”†æá‡YŠ—ˆŒ±åS9¦¸â@-°•�Åÿ8ã›5úv£j‘i5œ*=þ¤¸‰ºœ=‰¤’L¾öä²ÇE)À”U†uåYnY�—_‚aaeê6˃k† zfÎRdœ¶ÎéL�w†‘ç.\2:€Ÿ¹ð—Ú½È *Œ€ÑŠ…¨¢h1êh#F:)•†¨—¦ÊpÚé§…�˜©$šj"ª( ·ª@­¾ê¡¬7 [+j¸²¦ëްÉFa¶;¤z½ ²É2kó@ÎBk¨´WVK]iØ‚)Ķ„ÉbôÑÞN8—¸k’ 3{éŸ�w`õÕñ2Ê¥½øæ;(¿;û{ Àò\ðv#,,¦{5Ò—}JöØã§_Jq‰¹œÈšª—µÿèq¬a´é¦Èɉc®’¡Ì«Ê@²,¤°æ5’ÀÐÌäÍ7çÜ\�Óú —Ak»]aG#­›Ò©0mžÓoöõ{tÆ'ßÕXW'ïÖîuí5€`;¢�-°£gÇ•vÂ/ìv†p§(wlt‡â)#â­wâ”m @Ç/òà‘�Ôá&cÏ#ã¿ëí¹ÅþvlŠÉª‚¹ÍÎÆù•gY ´—B=XéFKšÒÂ1Á= ]ü™Z»hgµ¬-ˆKÄˆàøº¶+XÐ~‡JT‚ò° ,m|(ÌñÖv å½-ÁqÞó¢wR¯T�8 3–½¾eæo…ù^¹HS¸t‘OGÂéÕÊÿÓ2õIrî¹ÞɄӤù=©~„¹_t8ø¹kñLSÒÙÿ(À �0¬–ë;ªÍŽ�T %x+|Uð‚Žk™t *–ÍQ áÁ�g72o†•S¡ÜXèÂêY,oÛ›Ælè"Xå0p2 YøzH²-‘2B‡èÐèø“ƒè@ JЃ’N¡¥cèš ÉJnšEYšÛ “�ÊÐ]G•ifrÐ'x†IOš¶Â Ž„~´& Û97mJobÝ´^"Å©=î!Ô{=•$�êC¡^r2™4j�Z&¥&q±—uªü Ê1©N•¬äØY²ªÕZpµ«°ü*X�&Vóÿ�U²gMëD9XÑ‹ £Åäè1áHD9Î1¤TÌ«OöZR”~å¯ÓÌT5vMA6¦…„¡ SµÈœÞp§è¤•:oÅNAþH³œýŽg[:TÅ‘¶´˜Q„"þð‡T>0éi$Q¼Å¤¶…€‰“€b:¨�÷9˜`ñ.Tä“+Ä“ŒÈ«¢9Éð#F4¢Ñ« q�äH”d¸ŠQl2¶2ÕÆ ueÒ ºòJ9}QF¾Šhñ˜º£Z‹ Ì@2åâ‡ÊOukzW{†’—L9B8ùÉšÕ,¦Le OV-ôÒ�¾‚Áå.—r~-’/}íëü>`ü-�aàNØÿMŒj‹¼ ˜Á_i—·"Ì' ïÄΡ•Ëäa?ñgÄ-+ñINÜßC6e+¼ˆ´¤é\¦2)­ö±ñdpÜâÂx§\*½†\³‚ã[2ïv ¿=èïZ?å˹Óýˆu› ÝC'z¼�~ zgzP÷ÎqÓ³oÝô[?”S’Õ΂#–ëKözPÀ¾I±s)â2F{Ú+Îv›¹}ã¾ËAÇqóñÛÝm~sœáË÷(ùðw<Ë�âò³Hñ.û‚­á›»Dö@Ù¹ÿzþsã�)î~÷æ�îy¿húL×§§ŸêYœ~*©OÑêI×Ûí°‡p�ç´W¶w{Š—k¹§{M¡v½Ç,¿GfÂwg¶Aû¥lS!rʧwÌwrÎ×*Ðg`Ô6Dí’%.70Øâ[Õ.œ‡)Tá&õ“÷–‡yÂ@t¼ E¿rtg�Wdíõ ±r;6O�€7Û•$úprC_!tñŠÁaŽ~ÊP€ØVŒ¢kóƒ@ök¢åDwrgtwyÇ—|$g~×w X"}.V‚q‚Ž’‚À´} Ä‚-È/X1è35èhè—y旅qăáƒöÿ„¡5„ÒW„Gt„‡”„.Eû×#N8pÛ…Ü4…f…¢Yã[\è(^h `¸|(l'�Çlx†k†|xçŠmø�-‚�7‡wb‚…çcwè%*¸‡wÒ‚%´�˜ƒhNé'iŠX\Àˆ‘àˆ~‰M%‰.ö”¨–XS˜¨zLȉo· P8RH1#BŠöaŠŽ‚Š2Ö…�ø…l‹ë|³X|u·lw7ryWr{ç�Ëñ|p‡ F‡™`‡ ‚‡µ’W·p‘ɇœç‡ˆ%%ƒ‰†n48�6U�‘v�_Ñ2ÚÈ�Má�JŽó×Fˆ„à”BU—ޱÿщ­÷‰îŠð¸òÈ€ÉpŠy¨©Ø «ØŠøŠñ‹dX�úe‹i˜‹K¹‹ ù†‡#Œò!ŒFŒiŒÕqi™‘ÉØ‡ÌØ‘Îø‘‚’þD’BwƒD‡’ ¡’òÖƒ>±ŠA“N'“•H“6e“šˆ“ “ìÈ“©ðŽÝ�†öYBI”Z¸ GÙI¹�alMù�a�µH’¸†änØ‹ )‚Œu8Œ‘€‚bY‘xU–©‘GÇ‘õƒl �n9’@'C&™ƒ;µ vYix‰iÝd{yD8&3y‰5©„7I§f˜í˜˜>¹˜@Ù˜'Ä€�‰kFy�ª˜�¬h™®ÿøD¿¨G“%“Ã4Lòf�ðžãù^{æR>9ŽP”¿µžÔZµP(0bt¤‹±žµ©.!†Tÿ ^B :Aö–=��d%Vp5÷Â] S"RÙåÃôG:¼�˜‘o/¦4W•?“É“0£4Š}zÁ%T¤Œ°y möž� @ŠOPžÑ”6èi�êÉŸí)`>Ÿò¹=™AŸ�U—u<¸•Ÿ‘‰QüI þ  �ú&:L*50‘ òÄM zJ :TïI¡j¡è†¡úCªòž¢$1¢%*X'ú )Š+:zÏå¢4ÈA1Ú4ÿZ£^¢k8ÊA: ›=úž@* BJ¤)e¤=§?[º¤¶Ð¤Kù¤Ì'¥�aŸWªŸ&°¥]: ¦Ã2¦T¦°ã hzl Ú z+ZŠoÒוuúzVs§B•§ª Ú":S²j¢4„¢*,z¨ò¢sç� Ò¨3j£‰—9Ú‚;Z©?¤¦4¤rhž“r¤ú•¤ë ª¢Š�¤:ŸPŸUzŸ9�¥Ü¹ŸüÙª€¦!E $J¦e« ¦ jª«nÊ«pú«¢ŽƒJ¬š;xª1zª¬|j ~ Wד"ƒzš‡ëu³°¨Ü: Þš}¥®œ7®æ£—š©éZ¤çÿÙ©?ó©öážð9ª¤Ú"¦ú+!eVúª}ZÚ¯­å¥y& +¦;«{«f û¦—§À ±Ó7±ÿw5ƨ>º§ÌÚ§Îú´ÐªH”²lè*$ktß¡u¡10)»²gh2©eI®3{®šú Ä®žª¤;ˤ=+¯ó ¥˜´q4´ªª¬š´®:§°ŠŸOK ´Rû2T˦»W»CJXû°*±ÃÚµÅj±ÇбÉêË“«QÔuS¡¶}£•%[e"·ÜJ·\r·âJ©1k©æêDÀ¢41)÷À%X]æ£>z¸„¥õ:¥Ày¯©š¥üJ qÉ‘û¥“›¯•ÿ{¹gz°i: ›Ë\Ó«*â°+'¬ Æj§K2©Û¡bëºeû§±¨´›S¶ë¶÷Y�ºÛ¨t!¾û²9 ì¼ïù^Å;zÇ+)É˻ͫÀÐ+²Òk¯Ç…¯æ¸´½„ò¯ß»aáµä‹« {éÛ°rú¥¤û¾[¿Å¶˺ûºg+NûUý 1G†X(ÀŽzºFÀÏQ&³„‘< ¬=Äk¼3�¼Ä§¼o» ÈeM|Ák›¸Ó{ªÖ >ùêÁÚ{ˆ¼Ó½K °VJ´%\˜{ÂS› ^²ÂW˾Áz\ËM^‹º4¼º­Û—8 ¨Ñ*¨ÓÚÃFö¶ÓÄŽ2·�ÿ*cFH @JœÀLZ , ñÀ|Á(1ÁW Y¬ÅЦ¸ØÈ¸b*Æ ¼/f>krÿ Ù“]4TÙ–�ÙšÝ)(ןM_¡ý³Pí!R=´§]V�Õ;ÜÚñÚZÛ`ͲQÛ·�>¹Ý“j-«ÍøÛi×½=×Ä­/Ç= É�Ë­aÍ Ïí‚=Ó]Ý`pÝPc+÷²Ý¸Å™Þ‘MÙßaÙ­`Þ´Ùé]ëýíý¤£ ߥ-ßíŠÚú¡Ú]ÆÚø}úý+^ù&pÂ%n^°mºÍM¼m¹¾­ À-œÂ½àÐmÜÇážaŽ;ÙÉJ²á€qØà“Ø=a#!n ½ê¤ ùÝ&¾Ô&.*Îâ¥ãâ¼m„ã3.Ÿ5ÞñMÎó�õ½Ú÷ýãAGC>,Eÿ^GþRî´ßJNà»màOå/*×Un×Wz½&|­ú“ü¡!_žÊÔæÖ=æØ]æ ž"Î�Óêws&Þ¥óæo.çGCçW ëºNš4‹Yd³¦�ãô�ÚöýãÈQèØx葓襱èDÕèh éL.é´ å Ü‘`é>(Žåkc¡åžþ3 î˜M1ê�ÁážÝúÜê—é$»nç[4ë´Þ¶n4¸Žñ¾ï¢íëŠØç/ÚCÃ0÷Âã\æãÆNÈž’Æå`ˆžxKæì˜õ<–l\ã'Œ¢¨íùÖ’bU•¶¥dD›] áÂqbÄ%xõGz3ؤ®î¨þáüÿáîjÞ�°Žc86KõnïG=KÎ2šûÎëýÞ”¿¾©|ìúƒWŸ ßÚJ²ðT*G²Í²ÏBf]ÐóQ¶·M~àÊÀW| Œ _°11òÏQò'¯n)?–6¢!6 æt æåBæ+ï4ßÝkîw8/_:¿ó‘�Ù}¯?_çA�¼çæ‰ô?£ôRQðÅnìQ�À]m\UÏmWŸ YÏè×ÅðTÿÏ`/ödÏŸ!ö�BòœneÿT‘,_]¿ ÷tÿ•2�÷hÞØzoó|ß÷ø‚ß÷…Ÿë‡�øÐ«øÀŽãIïK� Mÿôïåw88ù£PùŸOޝdoÖ¬W½ÓéOÿúÍ%)£¿ž¥hÏ3Ñn«/ð­?Xþò¦Þá1ÏîA‘÷†Kâº>øƒø‘�ÿ¾$( ÀA„ "ÐÐáCˆ%6L¨HÑ*Œ3òáÈÁã)�!#�4QrØÉ\)‘­ÔÌ¥K^¼&Τ `aLœ¼~íä9Êç! 9„5PÔè,¤I-eÔ´¤‰gQ“M5VÏ�´nÕˆÑèѤHC:"KÌlÊ\ÊÔ®-Ö–#Ÿ�q嚥KlíZgyõÒáÛwèÐ#�/%ühäáHOŸž¶vêãdÀ$ó\´¨+ƾ`4‡ ;²)#ÆwÕVVZOU©kÚ\¨ÐâkدÅ̦]{vÿlÜŠ î6ØÚ÷ÁÕÁ!V¼xã[�äž:¼¥J–/aÊüfN�XùôÐ_¡_‹†EJøóÓ¨ÏW5vëV®]Å ?klÙ³)E+k[ìíòåê2k?½öê‹/ðrl°Â C,1ÅLM-Ȧ’̽_*3.³Í@ê,’Ï&¼‹4ÓPS­¦ßÊ-6ÛZcEØx+(Eߪ«!/r<ĸUŒÊ$ËcÈôÖ«J»_lœh¡›ôÂ(£”J_ª´ ,³œ@�Èr¤0ÑzìBÓL“äÌ×x챨VÚt3©ÃÀ”³óêãNSò䌼#AKÌ ÷«ePB 1ôÐUÿtÎ0ÿÌe*)­¼, Jó4åÍò–:`SN÷kI:H QrTi$õTT#ÂQG}r9!‰”Šª#µK•"…œÌ1Ë,§´ÅÊ+y…bK.½”ÐÈ$+³´3%I³U6ÝlΑ¥S4½îìÃÒ=?DÌÑG�PB‡47EÓ}ÊZp!�RÒ®( ÃRLg!ŒÓNEûô¥Po½u!þ÷ &w4ÎÕ G2·HZ�AÒ_&u _�­rbb4¶Ñp“fYaš}öàh¥¥6këtF[n=äóÁvŽ‹ÜAÏR]uÙuÔ]*«œ´Ò<ë½ß<•.˜~&`¥›¶qU/ ¾ aX–ÿU½†8!]½˜¸°Ã¶ØŒÅãò”�A–ÌeE¶HM£¤�©8U™e=]öö°˜!”f›ÑÅyQFcŽÔçx�¾tn{5%ÚhPEuzrÊ+g-€‚¡5àÇ„#YxÖdØÓ:Õ?J7=Á¯Ã{첿:;íµ•mÍ·5—»•“SÆÖN<ó>¥¾>û~l?kÜ„åtþ“ç_×H^z_Èù•Ürì³?j©å+Šóª=¿ÚH‡m½ÕôÓÁK]uÖ…Íx9ØSSö2Ý.ŽdnÏÝîÝWîÝ”n�Œo;“ÙZŠg³ã%¯p<œ/~6¯ IÏqÔÓ×Ñ’¦= f°T˜cþÀ'ÿ—Xå�a¡³Êdv‚“Qm}¥C�°T·:‹MŒ(EÑ Îf­ yÌLÍ¢Ýý¦V²úFN´ "^ ä KYª>À{P‰Ç(ã n9õ1Ü»œw™èáŽË©žK.(FPj�Œ|­&BЩф¿h£�Þˆ¾8fiŽu¼cŒRÃ2*‡~d }è½ü1®��8$-ŒX Eš¢‘{#Éà"i®IÆ¥’ËKFÕ¤IòÿpÒ‹Ö e7³7Ên®”gQo‹·Ö^÷®¾$=Å|ÿTß�- Iùmmlø+,Ùá¿] °Z 6ÝšBœqÿAp‚ ˆÖUþ¢Á~p„g1á?Uø/>[†±aÄtøÃMñvG\⇜X#eÖîŠGáb8/í ðÑJhiÜ Go* Ûq~÷ûÂþ.hÈ�ÛÏ‘ ð:˜‚4Ž‹€ˆA¾(óøÁ« 艶ܹþå2ÏI*<ýi0FÌàÁ.›eqfà G!ãe³›ãüêÍ™Îví)ð¬çdðYµ~ö1 �ìߢrŠÐ.FnwK‡E׺Ñ‚4†~ÁcÜ`q‘\ ¦ ” MsúÓŸîp·«;fy™ÕPÕªQÜê­¢Öë¦ Bè¼Z/çÖO~Œ®ñËkØü˜WA´Í ]lóa^atÿHÝì{³6Ú”�v6åbm½`»+œ>Ŷ=ímŒ{˜Ô fó¸Ë�V—ÙÕì&ùLÞý@yÉ»AŸAV½u¼kÖºlYq�¹hc¶É|0E®lƒ3»a‘Æ÷N)Ýð¬2™,hÑËJ�!ñ5ww9OEƽ½›R³™icTÈ»M�Ý’‡Ýä³NœFU^–˯BöæÉˆG,óÐü»x¾¹ÍÐ’óÜ@Ñ?îÁ‡îlhÇFÚI¤6Ú–ž’¦¯ê!ïÔ-nõM´ëçî”°u‡,ÄëZWˆØ=‘“—=årÁsÚ;æò2!Éíß…»Ü­@w¢áÜÈ:?tÏßRp�øÊ€/:_1ÿRé¤ßÇɹHüÓÁòí:~Û�—|A²^ù)cW Ù|™¥ÿù°‡þy[=»yšÒòNEõ«o=–F {|Éž?´ç¹nôÜ }÷ _íÂ5|ËÊ巈ϋÓdž|íº ªc¾Ú�…°<Ë»>Í£3!ˆëÃ>’{7Ã.ª+½ïS»ð{ @Ø@\=+(?(8¿©»s¹»ÙSJÑ-Ü;Ý .Q8Ác¸$¢:ø9<âë¿•ø¿sã.|<«k>TŒ¾ÎS5êcÀˆ„Àu“Àö¢@‹³@F¿ðãÀ$?¸R×C?a³;ý8Á°Ù»÷ë;ùsÁ�<Ø UëRÅò:UMUUmUbµÅWM€X•A+[ŽZU—[5�\]=QåÕö*R`ÝÐÉùÉbÝV<Öd½¿:Õ˜ ‰fM/î>ýCA­Ö,ÔEÐí1n�×°óVKͤpý‡‹‹rµÕ CWÆR×QeWBÕ®d‚W9sSz]Ø@´¼I[V¹è×D9×­Â ÿ„ÝO_í.ïÌVyeX�u±c-®í®ÂcÖrÍLì²X$ÕÏ‚°<òÚX§ÑÖ��Ùô Y*“M’Ý׳éW”­ØØ¸Ø–�²—]ÒU™¥Y¤)›MìÌÙà£8.¹�žÕ(•UÓšØ�T˜ ©ŽMZ¯¥¥%ÒvÕ.6„Ú³‘ZÈJÙŸ]Ù%ˆ¬Mˆ­]¯®ýZºÍ °=Ó±•…²5[A[©R[ØZ·%B¸%Ú‹”[…­[Å ¥…øÖ"íOŒÃ.p£„]\Ë½ÜÆ½Wœ-3È“\ð¨ÜË ÝÐÍÜ{ÜîêÜ­JÐ]Ö­[ÒmZε:ìŠÛÖ­]Ñ}Ý‘�ÝŒ›]õ]ß½ÝÿkÔ\þd3ÔÕ(Úý]äu]aNa^ana~aŽaža®a¾aÎaÞaîaþa b!b".b#>b$Nb%^b&nb'~b(Žb)žb*®b+¾b,Îb-Þb.îb/þb0c1c2.c3>c4Ncÿ5^c6nc7~c8Žc9žc:®c;¾c<Îc=Þc>îc?þc@dAdB.dC>dDNd%FFEEžàFŽdFî¥G~`I¾dž äJfÝ„ìà…±ñQž’>c­MVÜNÞŠO›9e))åÕ:eå=BOÆV~!WŽX>YöÚT֊ע’mÑ_ÙeUèå¯ýå æa.€b¾“c†¹XVæ¤efgæhîƒi¦?^¶æ™Åæ×zæmfIL®fpfØ…˜˜l&ÉrfÆsþætž×u–v®ÇwÎÄxNæy&Ö…h)vgmŽfs¾dtîgIýç è!g‚fF§sºRFèÿVUhôaè¾pèbfɈ^‰‰¦hI�<ìÒ(•Ð`EöÄ5�á±úi@鑦”’�“¦™”¦·=[–`—&J˜Žé™®ir¹ij‚Œ•ί–îiìû鑞ipAiäTi�FjžVêsdjìrjG�êÑ”ê2Ùi¶êŒˆ–Ši’.ip ¢¦Â£f­¤kv#ë2kyÑê?Qkä´'Ô3 °F3¸ÆH¹FE $ñ•´¶™²–&³2ªk‘¿¾ê‚lH(ì)yjšIlFYìLMŠÆ¶�Ç6ÇÝ�lÊ–Ë&̞͖&òèìÚØ�Ïþ¼ÐìÑŽ’Ò&”Ó–“Ô¶ÓY`mÚpíÿ[á1{mʉmE�m(©íA¹m0ÉmqE Þž ßNàÎ/áÖžÕÂd]Èî"{ Wènøî>)(±� òj©Ã%3nQþä^:Úênˆë¾äìօ힊îv…ïf++¼ò^¡óLÎe(ao@rï÷ŽoIžïúN†ûÎïýÖY�èoôùo% p'p2ðêFðHVðãnïþîÚS�pÓ¡pšÀdõö o nod·-ÇoßìF25ó®pÇ ·…?“ígä_пqÕ.(÷oïñ�øñ —„!ÿìô¾dBAò×o_¢&Ÿð'‡r_ æy)( ÇÿǾrIÎrâdð-ñ¤øòóó×*ó·â•ËHÓ4Ï/Lfóôtsçò%_&9/Ÿ (ç ;?e×_éz¯÷]¸w|_ЦE#èw_<Œð=¬êHývI÷œwº-wyŸ’sW u_wÿòh÷îúdx¯öƒŸ’z·w|¿w}Ï@~÷÷~øUøáJZƒ�d„Ç …ÿZ†÷q‡øˆOwv—ò²ø•�w˜—’�§÷Ž÷ø6ßwšù‘?¾®0ù@yÙ÷)Áù°žÞ—gô˜?÷™×„š—–±qzU×y©çùžoÐ�¿�y’Gz¥/n¦—­/Z¨$s—ù™¿z7ÉzqÏyŒWù)aO°z�z¢/{  ®³OT ·…îÏbûä�ú(ŸúLOt�û‰—ºOx»g­Â�½7ΰϡ±ÿw£×³çÖ­ˆˆ”odDüö‚Öˆˆ`ü_ð•�üˆ—û6©|–¿ü"WïÿÍͰw´D!z# yË›×øÐ`Ï�`Ž’ÃߪÄOôʼn¼�‘¿µ˜éÖ1 Ü� ‹6Œæ‹ Ëïüî}€R¬§p4PdöXû¥5þ:ëŠä_þ¦¯û§]é·�Ë þ¹�ýˆB)hЄ¾2äåða€ˆÿP¬hÐ �Œ�pìÈà#Èa"GÒ*i2Ê”&V²$æòe­˜2�Ѭù¢Äˆ vòàó'РB‡-jô(Ò¤J70]åôiލR§FÕ¨ÑÖ¬7挨ô+ذbÇ’5*ଘ´jŸ>måöí©¸r_¾Tf÷î@‚¡$TÈpáV^¿®hq¯ÕŒ=ÿ‚ü8’¤É’)U²\Iץ̙5iî€gϲ¢G“ø'Ó l�Rm�#1�¬Z·z.mû6îÑg¨]»ú-\¹q/»‹7oˆ½|ûø x+á†ÿ(‡½˜ccÇ�‡E–<9OeË—3ÇÜÌ™vWÐ;s³o/ô´ÏÔ«W¹¦ [6ÖÎ]ÝóïÏ~woiÍœ[ w™qv!—Ü^Ì5ç\`Ñ 6uˆ%vÝÙ1°wÝ}^xÄ‘W‹yÆè—“z øWš*-ºøb‹’È8#�2Žr#Žøéh‹s¾„ñ#�|9ä-EY ’IÒ “ÀöŒª¬8ePQÖ( $Yj¥P\åO@(ÿ†)ešià)‘¨I›Ï¸ù¦3qÊi¤‘Øygyê)§.}êˆ#ޱ:¨ƒ`z¨&‰*ž Œ8ú¨š‘Fòè£�Xú(qÈhºi“MÂG¥{QZye�€Þ¸#~­ä�BÒYd‚Ê,Ùä“�zk•0^©å–0véë—éídkfži`¤lð&œrÆùê-wâ©gž|ú‰lƒÊÜ¡‡2Ê(¥ŽJªæ,åšké#˜^¶é¦þ‚딢êJ*�¦Ž‚ªlª®F«®¾ë¬LÖÊ ¼ðŽJ#¯Yz ÔÂ?�9ì�Åk šÉ²™ Æ?ã쳯Jk'µÕÆÙ§.:f«m,…v Æ·á…Ëÿȸ‘˜{fÊ.2î쟼/Ò[¯©øf¥ïªýò-ÀÆt:ðη—Üå„Ç‹ŽY”»&æ…0 ™ [�¦Ú冿p\sÃèýˆ0"÷bDÌ•ÉzüZÆ&§'BQtR$�.¨˜+Æ‹–ÒbxºèÅ#‚q}b,¡2Ì¿<’%Jb£UÜ…ïGü“ e¥4Zá�ÿ”¢ Ì}ØÇRˆEÜ yÈì1²˜�ìÞ#¿×'Ij!ƒ²ä#0YMrñ‹e cºfWjŠ–h´¥Rv³›E�³œ§ì— _ÈÊ©é•q‰¥ñN±¦œå´>óiOrîò‡½ôÂ/WÌ®]ï�Ìr“1�EãL‘™¡$4¥Éj6Àš¦ÀfÞÊØM~sžGçYö¹ˆs¶*�÷[§TÚ9ÃþegqÞ”§G¿RÏ}æSŸûì'/{ÐËIåXÜœ²úŒ„s¡wi¨C!jI‰®„¢Ũ65Š oÆ£žQV³*ÒÖäÏ^ýêÇ °‹±’õs±‚�™Þ2³¸¨i2oÿ²!M„!WÂhɪ]IMj쥜°òõcFÓQMñÖàÁfD#aÉ«XF)6±ßj¬cÃ#T#i¤5BÓêL`Ìo> Q«¹Ø‰Êˆäq�ë`fdלd5«ÊájȾ Ö�‘µ¬;kbÒê–µ¦)nu\�!WaÐ5K«•^™¢Ê¾2·ÅO`­0Ø}–<‡] d³›ÝÇB–Q“-Re©rYev³äéìj>»ÛÐö–´Ã0­pQû ÕÎóª­UÄk©ÒUÙÚ ¬µ«Y„Ö2�¶\¢ýí3‚;ÜâBâ¸Iî–Û\¾>W6Ñ�›™ëš@»Žlx¶+ÙƒR6#–eÿf߯óf½lQo+x«&÷ÂwÁ©•‘ƒp_üî¶Ôâoiûß'IIÒmŒÙÛÖ”¼µŽ§%î`êZß»&WÂök¿ŒŒ¤ Œ°‰1¬Hûaír·±Þ%1xM,^“WÅ+a±L\üËx´,)­‚åK_pÚ·µù�Ê~e[6¢22VZ.’ëŒà'*Е!tS¼\àÇNpÝ—>ϦKëé�‹z‘µLõ.ïëêÞ¶¸ÖAœqÿKzýë(ûxUÆîò²»¹2O<¹Ú;±òµ¼ð3Žy�õopæ=*Ê!îsßw}wØN üà]oì£#;éï6øPpŠ@è•…ñwR删ù K>A š¸%+®í‹›š]÷:Ø­"v:ˆ<.f_u#P¯öÕ‡¡õD—u{a?sx×\‡;®}nŸ{Ü“ç=ï½ïß° ÜÁŸÑåÒÕÄñ—i@‡òùÑ‹ˆÅŽ9Ÿ�èßþEßãMŸàUŸq,�´‚åmÝöm[÷yuÞ&„_x½†èñÏù�^Ú¥û¹_ÂÜÜÉ\âÑ\Ýß>µ†æ^ÿùßß%”Ààð!`ñ)`Á1ÿ PDÈFÕ ÅNGÂíÅþá‚�n ‘ÅŠHj^Öe^ š ¥   ª ’ßÛ�\é•\úÅàú±ë¹ÝèÕ`üÝ`ìÙÝì5MŸAE+­ †€ÄjúP £<\’䉱 ÉËø_.t “ƒ%^¢½�&fNE H À=EX± †H⇜� |ˆ$ÆÊ횤ÜÄL̼ŒHð´´Æ|üEÌÇ* I*ü¢õÄnŠ|ý…ÌGæH$ú%Ã%^âúG ²Æ I!~Ä!b]£„Ë"J�–9¢OÉÅ2ò\3>£%fâ&jb'ÂÈ'†¢SŒ"Ê`È)¢bx¨¢ÿ±ÿâ½b¹Å¢,J -ƒ-¾ .®†.þ/ú"0”0JU1ãj$£pŒc¾•£9FcL#}Tã�\#dãå±ÄËtcä8’2†‹$Rä3¢c:âË:¾H; ‘(~ )^Ç<Ò#KØ#Ïácmé£pxP?úc¸Ôb¾Ý"Uäb/íâ| d*ã £¦4ät cõœ$¥¤$%šc0X$`äáläub~¸pcxpH¬”$Å4Ãi¥^í …ŒŽ¼¤‹Ä¤̤´ÔäbÜ$N¦âw¼Œ÷È D¡êÄ $%@¥@åj|¢R®S:¥ ŒC6ýÍÈ|°�OÊ…1½eE2ÿ•x¥F†Gz¤&â£0 Z&ˆZ¢I[^h>£*ù˜ž@‹]¶^êå�ðeGø%N~ˆ`&aV¥p  &&¥%¾åTxdäR É/6¥B>åeFÇ•l&Êtf\|fçh%Wºi²Ó¾œæXzXY*âYnGZöÁ#HlÒÅl^bmòµàf?y"H¹ã*À£¶ÈãwüeNf¸ fœf\ gç)ç£0g.8§T@'HE&[LæuV&Ý#fnçjp¦w‚'؈§hN‰Dø§ æ�ä�ÄL·e×ù…d{>Æ{ƧpÌçK0\+Þç\æç«ä¦*ìFEÌÇóDG ŠgeDÿ £ç�g‚§\0¨×9¨£@(É�Œ»P¨8YèS`èOÉ�er2£‡²ˆv¦ˆf ‰F ®œ¨L®FJý‹þˆ‹†˜‡Á šÀkº§kÂg8²¥%¹eçì¨Ùfžèç.ñ§ éj)© $逶L¤xç) 'CqŒ‚ž•rœ•2–f©.liWDçARgB†éB’©™Öwj ¦®)Æ´©‹À œæ¥œFÅŠâS‹ŽË‹B–žŸÎè˜ÇkÊç Êf¡þ�Ú[È(j1ª£²¤Jj,PêdÈÍ¥z§¦§Jé‚~ê&„ê¨f©©æªN'T'e+‡j'¬~hw†ÿh1Õ§%Žg{äê|ÌiÔiÜ)æi×° ì Ik"+ šä�.+}6km=«ÎEë«|N ©—þg)G iù()Ktkgþãc|ÎÖÈʦ,¹–«U>èbâ©–ª„p)Ʀj»®j½ž†Be™vè¼¢)ÊT§»­&ƒ­¶®FŠR£ŠÒ©¯Ú)°â)Á¾ÍžÚ Âú©Ân�±à¨K訳*~ÞfÅrL̺ ÆJ§µnl¤vì¤~l¥~‹Èú$ÉŽ„ÉNLʪ,¹Â¦%�«–Îì©V(Ú^¨ªZ'«b§«ú,�üÛ-Î~ç½vN3ŽÒh*mœ²…¿¬ÀzdÁÊÅÁHÂÞO…Zn ׃×F,Øö¨ØÒÉç”­„œ-‘ª-¶j+eÀ­š`êÜŠDÝËÝ¢ìÊê-ñmŸ¤«D¬«dî»nhT"îŒ(nÐ2.šmä¦X!ù,ÚÿH° ˆP¡Ã‡#JœH1bÊ3jÜȱ#C� CŠI²¤Ä‹Xù!Ê…_”‰‘&Í„&nž,ˆr倉:y…ÉèP…G&Ej0§É§P£J¹ôáÏ™‹ÆdÚÑæN’2¯¦ Ñ+ÙŒI«�ʶ­Û·s:=(W¨Ê¯Ö]¸Woܬ0÷Ò� ¸¯àÄ75—°@±‹õ"ΛØ1QÕ)kvˆy³RÏ8Ï´ ·´éÓ5±æÕj2ç—é}é·¥j®«Wÿ¼›µn¬]ç;vÓݹ‹Ç>Μ8ïå¬{ÿ~Žººõë°§ NÖ¥ó{ÿßþYºïÏÓåš…N]øsÝê‹Ç7>\râÆ¤ÉÃ?Œ½vµØ( HɽwWY·�žRâö}ÙÕ'asÿµÆ•„¿e8!†jg môym–hbTêwàƒ¶)¨àmÔiˆœy)Ê8â†í]èâ�Æ¡T#�ìq"�6Vxâ‘Hz”›bÔ=ÆÒ…åE)SmS⇞r}7ßv[úˆ™]øÄÙ\ûÝ7™BÕgÞ”eV]ö'ß—Ê%iç�UIž'Èç�~þ)èŸ6:¨TLzh¢Š6êhIDêŤTji˜Š¡é¦›žâé§Ž„*j¤–ZË©¨*£êª|´êj°ÆÿšË¬´>cë­Ðäª+¦¼æÐï¦ɰĪ—S#Èâ¢lÌ6ë,³­D+í,ÔVkíµÕ~úiÜv»©à& î¸P”k.覛ʺì>âî»ÈÆÛ­´:cï½Åä«/ª¨ë¯ ÒlÄÀVÌËÁ‹$¬°/ 7Ü+¦¿F܃¨¢úKÌÅ}dLÆÆ†tŒQŠ„Ü,¯“¬)Åþ«^Æ,÷±ÁË0G*sãNêÅþþZÃÎŒôì³±y ,´%ÇÂÎe²Û@ðjw³îõ`g5ÐÝîÔ´ÞýN„GKš¤&µŠÚyšÊ„w¾²°yϳ…ÿ‡8=>TÏz_Ëžö¶×@¦M.ãk[ùšu¾V`K…ŒðûÚ÷>â‹`ÄYýˆ�¿Gˆïp×óŸ3p&ÀЀC`¶@š0b4ÖÅ"8:2PЂ¨ ƒêLö=Bîƒ!„!íÄe³¢‹¼sáÆf'3Àf6¼¡ÓİC‚Ï_J â…XÄ#^O‰ÛƒF ùÄc%‹|æ«âù°Icmo]c6Æ2žQ^׫#H@€ ,Ž–›#Ø@ulQ…om[çPyaõZÕ-oWèºß>M¬ÂM×Y¡øÐ´æ¹U®ã˜ 9¹FwŽÔ-ádqW󿤝~å®wÁ^ESˆÍ®ÊÒ»Þ§µwRïí\|Y8_îÚWxv"žO?TþU.¤5-j¬ÚÖ>Ma Cm‚…¼`CºÒÁ¸…Ûù>7aËVxjÀÕe†Ñµá/çÂÿà Ž*yG W•™x®(>Ú]Üb+¶¯ô�±D²ç Ç Ûqc3Æ^ÈzÓ Až*Måk,ú¿KÖo“;Ù_(ÿ·´%•%aeNa9aZŽ-ĸ\ÛîÁ–™'\L s Ãd \›­ÚaþÅYÕm]n�ÿugºNWÏÕ峋McbZ°ƒ®±�Ç‹ãòúÙ_xx@ˆ~Cn–øx˜X.šÈsMH‹ŸŠÀóyGƒs¥x…˜€©È…¨â…`øŠÙ‹Ûd³¨2µ¨-Zçaµ¢‹¿Ç�Áç�¦‚邇þE‚·`‚(hR€xM-¸Œ?ƒÕ7ƒ×Wƒ1�ýø/Œè;ÚX~Ü(‰ßX„ÿâx—XC’WŽpŽþ˜ŽÓy븑3¸ÿÖ+›Ø ŸŽ[˜´‚*étl!‹gHFî2�™75µd·=ÊðAJ$q)i�F€3Â%kÏ”ÃЕ·2Œ&øƒˆŒ�¨Œ/x‘lãŒ=�ù(�ûèÔè‹TWU_’85~çf23.ççmŠG‰(´3¿w„Ý2Fnc7ÒB—O85÷‡)4)Bì839‰…ÒÒ“(9}¤”§2”MW”o �Õ8JinO=4[T‰mV‰•¹¦•3‚`©vb9‘qg‘âÖù�šY œIžRaž¡™ é)*ëi+P鞟ê!ŸôYŸÑòQÇ7›ûÉ�c),øŸÌH*»I mi o—ßw�ÁÙ 5— šCH¡®Ã=TPÚ,º¡KÙ¡ ø¡R¢×)™$J™Ü‰¢—Y*+Ú¢Eç™7È�Šžg¦žâtvÏp£°£šÃÆšrx�=š.öŒ¶"¤üi¤Éÿ肃˜¤y°¤‡Ø‘Oú›ƒ—�xY¥zY’Ƙ‚¹¥]Ú>¿h7Ú’˜ü†ŽdÊ+Õ™2“�§ø’mz ) §á¹™ã9§åù™–�4º§Ni£¨ù§ï¨ñÙš=*—Ãõ£[Ù�ŠJ¤¶Y‘g™›iˆé–uê›wJ Š�"™©ÖIœœ¡“è©5ð{¡Š7£Jªžbª£IšŒé¡Ô ¢�i{#•¢IRå*q3,Þ)´@ « oªUD›°Ød @ZLÿ • 3D9é*Zú/ͨ,Gô0-¸¡]¹M²cƒ•ãH4å“�&{²›²Zq° ‹°fcrËz�Æ2 cNÛÿ(‘OSPûã/=d7êC-�–׳?AG+¶ Ô¤§Q¯÷ZC§¯¦Ú¯9ñ°ª"° @°’`°!Ó²»° K@T›5+DÛ*K€Jбգ±ä:ëR!²#²DèUÇr²(«)*«,Û²/˰1ûe3›15»S$‰³œ¢³‡ƒ¶Uã³?´&0´‡S´³r´I{Lûø1Pûœ‘ µ&¶V‹µZ«\K^¸` °Ñ3¶¶P¶|p¶0È6 wm 9oÛ2‰$·V@·My·x )[°|»µ\û·_/ƒÛ…;3†‡¸›¢¸ò¸¥â¸ê¹’+/”› –‹9Jk™ÿ»¹¿Ò¹ú¹�#º+D{{}«°q÷µ®¶«âº°+»h©¶]ö+¥2¹ëXqK©²3U·$¼Â«·Ä›íë²Þ¸±Ù`ËÛ¼º©Ð«)Ò/ÔK*Ö›>;k,Ù/ÛÛ½—ó½¥¾N»j=@¾üz¾¬« £«¾ l Œºï«ºñÛÂóË0K¢û©›¶¸P»$s»ü;  3¼ë»¾ ¼x;¼Y[¼¦{¼ œ¼ÈÁ c³‡«‚‰Û>|‘¥â/¿ûeñ•Œ,!ŒUH뽘»7M TùÚ*ûj¾*ƒ¾W ÃO̾ÆÛ²©ûÀÅ4µ8¬*ôËÃfëÃŒK»kk»ûû/ýÿ;ÿk­Ü+/GÀ(Y²ÁëÄ+›Ç ‹¼ª«¼XE³Wl¸�hŒE½\¼¸� ÆK,ÆÈBÆ_C´Íc´h|¹ôÊÆš{ÂoÌq ºtLº×Ñ·ôu2˜7Ç-¼ ÄŒZã‚~˜B®œÐ̱¢¿ŽC—]ÙR ô±LËǃ‘\À•ü4Ñ·³Ìô·?d3 ®3“<Œ,ËŒÊv«Ê�ÀÊôâÊUË·�Æ#¼ÆàÒÆO ÇQË›¾©èáËÜ%ÎN¸º«BÌ»`Ìâ‚Ì9 Ì�ÚÌð̈ͧ*Ó,:}PD6ˆÍ·Í“¼?ÉóÍyÎ0›Ðä ;欩 Á{SPÔÎÆÿÆm8ÆÑs=¤FöŒÏCÂpaÂn̹þ칺ÜÂ/<Ðw\ºîûWÝÇþ:ÌŬTÇ,®Éì©ËLÑ=Ä$ÍÃ@Í}Íû\)!Íb$KÒÞ àÜ9O}‹ÈRΓrÎÚŽõ*2 ;4­6½?òL+;í?=-ËÕ!ÔýŒËÿ,Ì]ÇJ�íÔ) Õ~¼ÐS=JU šW�œḭ́ÍD¬ÍG===ÖÙœo•xÓñ’<6c3±ÖÓÖ»÷Ö,×.m¥t]¯õöAѰۼt|�Ó_ó׊Øj<Ëc-¾)\Ôå{Ô‰ÍËÖÑØ{ Ù¡+Õ MÕmÕí©XtZÿ½ÙÝÙýÕ]Dاtum¯d­Íf=Ò‡£Ú«í­}ÒlýØnÝpír=0 .¹ ;¼ÝÛÍóÛ—ÜYcµVKÜ÷bÜùŒÜê­Ü*,Çÿ²ËvÌØyüËö ÕaËÐ�M®ÝÝ<ß]œ�Èã ÖÓsÞª�ÞMcÚëÏ�ß«=ßQL(íÀ‰ß³­ßµMÁ2“ÞÿÝ2¾Û¾]Ó©ŒÚñ=.° n/ þÓû3•“=WŽåZN*\¾ ^þéaNæ/Ãg~4·¾æf© |þæ¾çK¾è!sçG�ç=·ç|þç€~1‚þ0„ž †~8ˆÎ-Š.æÒ†3Ž,�Â’ÎX”¾1–N¤˜ž~šîæœ. k¹ž.ì`êâ2êjWꦾ ©@«=©ôê _ ±>= x�Éþ4U¾ëzÐæp6]n‚üÞïÄnìÇ.3Ï)õÞì+r.íŠ@íÖÎsØîæÚîç�ÿn²ƒÞ-…n²‰¾1*Aèþ,�î.ô<é�Sé•ré(¥x%Ÿå÷n}ûÞñþž_ oêÏ8Ÿ5 ¿ðúÙð[óð­ñ#¿)¿ëÿììßñ{@ìò!/ñ/3åO³ôΞJ”òæ>íxþ0z^Íó0óPóÜró^•ó°ód@ç±ðø�ÿóÎôú3¹íÎïN–RœßùÕ”ô™¾ìÍÞôùôüõS_õ§~õù’õ«²õ\ë§ö´ïŠb?÷jNñºnñg�÷Ù³ñjÇömÿñf÷r¿tOò¢ßì½îûa£÷anç}_¢.øÙó„oø!€øáÿ¦øŒùàþ’ß,”?ôî^ôð^)�ïù�ô0a`÷¤? ¦/ì¨_&HûOð¬¯êWÊ„VÐ`%„ "\ÔÐ!$ˆ%BPÑâEŒ5nä¸1À�VDŠ!Y’ÏI”zT®DÒ2ÏËg1eîÚ¥pÏMœ9o‚äÙ³ãÏA… ÊS¤•’%M-ÕÔ´åS¨/óÈ” ÊêU�{m=Ò5ÇW°Ä¨QjKH¥%@Ì-¸_É€ Q7DªTŒôî5Ñ·Ñ_Àp!Ø%S8ÖaĉƒÆñ㥦M X*Ì=4o.LæÏç*¡EoUô˜qŽ0‘›j:‹Äíkb¸pmîѰgÿÖ¬=A&à�1áDH4…ï*VÜøñâµ”/HÐ`Á…Ñ+9||âOìÙµ[üRäé([�wTÞ¼T©2�ÓT¸Ý=P¢ñ�~?­ºi_ü&ÐÃŒyËÿÕˆ2"�4: k¬²öÚ+­µÒzM0¹è² ¯²jà+?*ûË.»ó0ð{l2ÁP¿ýhÓ¬³ÎDm+ÓK�©û0„Í-Ùh³�§÷²n8š�²˜å–³åH$QrÉ谳ܮ» ŽO<òÌ+o¿©bZ¯¦„¤€øäóÎ ðìÓäD.eòï)ÂhÀ­ ¤ã@±T�¶Øz0®Ó8¤POFNÔ°ëúÿP±E £ÄÉØÜoµÕX,ÌÅÐH‹±15O<1ÇÍviÌ�€[rI$‘Œ.UV“<õ—&zR"Rk͈J+Oò-·ÜO½âØ ÓV÷Ê$j>4ë£qM Ûìï?«œ“N;ñ$ËÂ=ûtð-@4• /ÌïÐDCX4±FE„ÔÄf'¥TKÉÀ´ M;mFSVóCP5ub/2õÕVWm•ÕWa]ÈÉYå ¸V\écl×^qö™/Û{X£C:ö8)’̬Rb°:m=7¡EÚ‹èT¤Ú¯ÆºvO>µýð¾ W/C5,÷\ÄÒRIÑ{^Kç­7Œ{MÞ·¯~k[ħ�>ÿµà…FøÕX;jØá�ÅŒ8Ù‰O�×^/Îx؇uÛÀã�Aöbnº‘MsÙ¢Ó{ÎhÁ®Èe˜s�™Ðmæç@'—О+ûhO;ûìuó~éèx•†Ñ^�~:êöUV ÖúÈ„»æèkHÂ&uì+ÍÎRKµƒ¡°Ý†»c�Å »î3ïηÆü.~3ÎÖ§0ðÁ±UPÛ¶ÏYñ� Å�ÜD!�œ±ÉÇ«üd©0OÓ¥›Æûi¨g uj«ž(a¬:ÝÕSU/õk×I`ºÁÛ ¯TDB€l\4 (œQ$bÇÒ xxšßÍí�9ˆLÅŠv ¢%ªà`1Bÿ¥’Ï–§%c2�õÍß�K?Mt½Îq z>C‰—’y¨Öwæõ±ÆìiAwÿÚ÷–Ú;ß‘ÃóWqD AGá ��£ó›ãÀíH¾¦{<æÃ�çÃŒGê�ø ¾{¼ÌÛ6šÙ>®ë>KÙ8° ?±?¡(?9? Q²èx=Ör¿^ó?g°½æÀ;*¢¢úÛ½ÞË�zÁ)’ø Àä!@Ôl¼å;‘„¾?r@¢€@»’@™¡À=±@ÏÃ@ÑÀF=‡(½[! ¤ ¬ \¼1dAçxä…¼?¿Ë¿�¨AÿÄÁÒÀÃÀ¬ÃŒØ·\¹¯D™·¾Â™‰«¥£ º¡ªÀý»p°ˆ—¤¢´F¿Žˆ�,ÜŒ-ŒõY„t»œ½ô?2ˆ„9Ã3Œ"6ì7$E*j•3´CWü <”˜ráCðÃ"D«D‘ D¡ClÂDˆElˆF´”GÌ0À�DŽ DK1?B?iˆMT¹N”»O$<>‹ŽQTE*2ÅSÁŽTäFV´ÁW,G�ˆE²™E]k¾üäÄ5D±(ÄSøEáE¬ F” c<,Gˆ6eô,lÆ|ÆŒFMôBNCOCP¬1m|nìFoTp ¦ÿ‰œ¢q|AsìH‹@G á�tÂv¼ÅwÌÅxÜÅyìEC DD�| �}ÌGôG€ìÀI$ŠyQ2†‹¶LŒÈSa­x¹F¢ËÆ…ØÆ‰¬H‹ü‰pTÅ�8�,G�üŠrI ±Eêxœ y4z´Ç½ÀGaÔGbäG9Fü8”€ÔˆøØIéIHüÉ£|¡´¢:_ÈK½Ê%ÉH^PÊ_¸H;ò˧„°¨4Ç©ÔC‘|5’|>w,‰­| ®üJ—F˜K™,KšìG0»ÉѳÂÒILáÉCóI„äK%©K¹KgÐ˽œËSñKÀÌ"LViÅÃ,Çø ›Î�«ŒüŠÿ2$Šâ$‚6‹¡m‹¶"Q¼ËÃx©�×È1ظ äÙŽšI°¨?>kÎZÀ;à�ñOÀ,O‰´ÁñÏÜ\ÏFÛ͹éÍÓøMÀÎá$Nã$Îäìžå„Dï|¥W‚NK‘N· ÎװξÙAÁÔίàÎóNàȈôOóœÐ_ÀMö¼Ðö$ Þ, ß4à„1áÄ‹ã¼OCÊÏÉÙOdü‹þôÏQPPb P·0Е¡Ã6ä Íõ/…’‹ˆPI Pó´P -ÒsO/€OÆ�Ï¿ OµOK9N=áúºÊXQÿtÑ΀Q%->ýÃQÍÜνëÎæ|ПÒò4Rÿ6ÍСØÐ¹ˆO�O­OC"ÑšÒñ¨ÒCÁÒÿ”˜è,‹é´‘ùRÕˆìÓ-Ó=SÝ5mSI]6$UR°`ÒFpÒTÑ(ÅÏ/‹!>Õ?M -- .%Ôê4P0½QUÈÑM®¥•÷ˆÔI­Õ"Ó´$µ°P"LÍ5F€ªã̾–Œ7Hä³P8Vd=Cðè %º*>ëi�VÁr�D]ðxUä:C4µUo½Pfd‘ýPô�ª‰ÖzÄ5¿ÐcEÖcUVmÖÂxÖ‰Öi•ÖjÅN1ÅÖÓ¨¿èàÖGýV�õÈpµÔ¯èU sV<[×ÊhWw…Wÿ”W2 Wÿذ×{ÍWí¸ÖlÝ»µÁnX‘ÕÍ�W9%×§1WjB׆µRÀ€ØdµÁe¥X‹} Œ¥VÝz�k•ž>\Õ‘ Úã+X=Y:-WUZØìkÙC�Ùw•Ùx…šu‹›ÅלµÖ}íÙžXYZ¯%@¢�Ó%�Ó&MXRÚÍcZv­1w}ÚœY©• h­±{µÚ÷ÒÙ¬ÕZéàZ ýZ¿U6$…SgU"Ùàúb¤‹‘ ïÄ» Í EÕѽsArÜZý[̵ÃÀ}OK!ÜÂÝ�ÃÕ¡Ä�‰Åµ¹ÆÅ£ €\~eŒú£\Ž´\¥Ì\Ù5ÇÍÍUñ\\0ÜÐ}šÑ}†Ò}ŽÿÓåŽÔ…ÜŽÍ9×…Jb™ÍÙ]ÞŽl£xÁ]ÝÝ]Oé]ïL�EÝÇ%Þ~Ý;¿d^ïý^Žˆ—Ü{éÝêmNë½Ú+ €Œ@J¿D^ð�_æ_úÛ»ò�Þ_™®ê}•ë^öÅ÷}_"“_fÞè_ÿ°»û=ß"Iß»u�~ßž`Ù=àúÍ9._»k°VqàƒÔóœH áåµ`©¿ –Þ ž®æ_õÕŽ&Rža¯5áÎ@ašã³P´;6úY’þMÓæF.â^¾»Óáºãa'F~`ŽÍŒ4b,Y. n&Ž¿'vâ(¶æ ‰áÊÍbÿ5ÙVé�x8ŽcÆbÃ\c;¾ãŽhc�yã8îã〢ÀÄcAä�Ðã¤àc?öc@&dFnäŒDNdãà[ˆ^G¾d;džÈ�ÅdO&dMÞdUìäO.åL~:åŸ=TSnåeUÙ€ueZ~eT¶âX~AR®e^.`XÎå9ìÚ^fþe`ÞebNæÙ5æ\Ffe~fhŽfižfj®fk¾flÎfmÞfnîfoþfpgqgr.gs>gtNgu^gvngw~gxŽgyžgz®g{¾g|Îg}Þg~îgþg€h�h‚.hƒ>h„Nh…^h†nh‡~hˆŽh‰žhÿŠ®h‹¾hŒÎh�ÞhŽîh�þh�i‘i’.i“>i”Ni•^i–ni—~i˜Ži™žiš®i›¾iœÎi�ÞižîiŸþi j¡j¢.j£>j¤Nj¥^j¦.R—17sÛ·¦®æ§†ê5“ê©6åÜ sƒÇºÚ�CÀê1q™¬žÝ­V„®FɯÞ±².ëÌ=ë´¾<ÆXk¸ik)yk¸þ[¹f5¯¶'°Æë(Ñë½þÚ³–¾}³k�¹©ã µÓ ìÂÚæ¼}Û7°flâtlÆ€ìÈöZé‹�ʶËƲÇhìn{ Òˆ�ÎÚÏ&ŠÐ&4ûr”00mCí­PíÕÙÖŠÄFIÿÌ6$Í�Ô&ŠÜÖíÝŠÞ¦ë ’mÚæ)ÛVÜ.îo=nä¶Èì´ÒÎìÓv á éXê€ä®¾åv”æÖ© ên¡øîïÝ·£�ãœ(´½¡b8”€_öÆ\÷.,ø&Nù^Y­ëû> üÎo¿Ýo1˜ øþozä<?´û®cÏ\Wpÿfp–Ô²p>(ð Ú  ÇpFâpÿð‘ qq/q'p Gñ¯45› ±Ø¶‰¢/™P°`?pÞ¨ñºñOkYFÚñëñÿ[ÿ ×<-3rBr#Pò%Ÿñ wò!‡r_T×F¢r+¿rÏò?xrì‹rÿ/?ò˜àq'¾YsImò2ßò3ïrb­*0osg†ó"u›º Ö"÷ò³»ß5ˆ÷@cÙ7·¡0—¡°}£0>·?·'@×ð)Ÿ.BoN×ʶE×®F×®G×®H¯•IŸ¥JÏ¡K§ŠL/’M—ÄötÝ`t:qôaƒôR“;�T¿!5gušóN"†õN'´SO£P/­Q/­\×õâuâDѧô`oÎa�’X'4(Øvn‡Gnçöe'¥f“]gŒ^?…_—‰V_Žk·¶©Û·oßvo�÷pߟq—’r ˆjißjoŽÂôqNŸººŠw(˜wƒÿv [ï{ߎÑ6÷CÿZ\aª˜Ÿ#‘al?£º²'ƒGø„ßö…ІwøÝéo"8›‰§9¶xŒwwºÚøYêx”üx…×.†yìxx}�øVHùæ¨ÛN°x[hù÷˜k˜_™Wyn7·›'fоu›'îKŽ�ÿŠ}÷ù�z¡'úŽ 0£‡ù¤'ï¥gz(pz‘Wæ¨'´�÷îª'Š«Ï�¬_Gü°;®gù4Þ°÷ë£G£±�@Æ0û³gµ§Ïâèö_¡h6lK£6rô·S•жЄfa¿�èŒèp›};üŠ�>Ò ù›º¾L}Ò/ýÑ?ï.ƒ /`vçzìM|íj#xt|GFÒbd‘ɯüØ»üÿÂÈ|ÝØ|×G|cùü�ýÌ3}äÏÔ�¹a},æ|2! Åß4¥ÏÚodÛ7ËŽú¢]²|�Àü…Ðüaƒ~Ïß Ð'mÇýä/ýåW}ç7bò—~íúû$dŒÀ~|\½ýí_¥âˆa*+Hæ`¥„ 70l˜à!Ä'¨hq"ÆŒŠ6BéèÑcŽ�"Ã�,ià$ÊL*W²TIä%LY2gŠéÅ‹€œ,òìéó'РB‡-jôèÑŒ|*Õ©ócÇUR§Ö yè*ÖH·ríêõ+X¡Jozyð,™Tj#±5áÖmž� "T˜°¡Cˆ•2Uª‘#T�UK–|døpËÄ™ÿžI³êM§a'S®lù'ßžM� <•jU¬Y/“.mšòØ›fѦ]Ûö­‰¸r‡TvÖî]¼ôîÍØ×ïÄ�Š ®I˜$cÊ[&äXfÕ‘už®n½zfžÉ‡z¶èË“hzÚlû¥:ë'Ë=d˲7B»à·ßœ»W_ÓïC/üѳ%nÿ|ÓOï ¹÷NÓ¼‰LoX� H½UlŽ0Ø“˜öBW¶|¥ŸR¢C²ÕÁ­u+CÝdǾ }mo|«‰ßv÷�©Œ�f‰Áß|œ!ÃOiücœÿ¢¦< šf€)घ@.°�%y`ö>'A³ñP, êü£Á·å n®ƒÝ[`£¤„{ƒŸüVÁE¡±†°™! õW¼ãå€M´ÌÀD3}gˆDVIn1Fð±e ø£ØÈ@6&¾3Oü˜øæH#+~PHé{YŒ�ˆ=n¢’"�ÔÔˆ5Jxµ© eXC£ÝyÿÛa!+G9~fX;ŽCàÊ<ªeÿ�}œÏÈA¦(J™+ƒ¹Š'UD)ŠÔ#_ÂØAÒ>’ì%-LîL“wë"Ä:™¸O$”ÎeÑJÙFTö2,«æ,aiÇt†A�ã##üÈŠ-±œâ¦0åHL“?®L&Ý¢¾gzg•ÜÄ%©iM+�“ë27•áMp¶LœŽ;e%ì9™s“�%‰%;Ýy xÊS—ôäÞ5 %Œà3ŸùŽpúÙÊat™Y”A'Ö¨ƒ&“ m]C³ùP¥EÔ›F8*R÷ÇÆ‹ê0£* Ž2åÒÞE§ŽëÄ#IDJR\Îs{‚ì^£z“ n°¥Se%L7bÖù™©¦Žÿ aÝr*±�J3Ô´ÂOÍ÷‡új>-j(‘šÔ5ö�©n|jý$Õ³z”$ Åj;kùÎ[Â&—»«÷Äê²’l­gåOZáÙzP™oef\å*Ôøðtš åÏ&W Ÿ–ý•›F¬”ZØä9±›q ô¢Ã,Á1‹Y*RÑ›ÚZý˜¢¹szdÝú Ýéîƒ # g�ªYUõ;Ç¡]thw9¶Zï8ÌúÚa”ö\3-îÝ|é ßùF§¹¦PÑ×*š‡ýî7¢‹ø/€£#8xnuiLC*Ô ¡`Ä3#Ù nU†´âòè¸îI®rJ#û®µ0›.uùÕ b—3ÛOÿw½[ðVE¼Òóç`ÌË#ô†½6n™{£ß]Ì—¾U±/~'¦_þæÁ¿þ¯€ƒF`ÊÂeqÞ™‚!Á`~:˜3®‰„iFaY¸V®™8\$è~Ä}¨nb=VšìžX4)VqX\ä˜ß9ïÄÒ{ã=› Ç;î±|ëÛÜ KlÈü5ò‘“L³%ÇóQN>j‚ÌàßêÄ•Y†É–QÒå//WЦèðM£kf4÷Imk6±në]9—eããݾÓ?‚Ï{ös|íiuõ6¹ø5°ઠxÉbz´"-åIg„»1&Ì¥÷šçät¹eÖ0s�;f¸–Ĥ^)/ÿ“];ÃYŬî ÌÞ»uyÖÓ®µ­·ÉM\óX×?t¯f;`»þþ÷‘‘Ll%Ûц4”%íÛf£øÙ&á‘àh}˜jÏçÚaÖv@]ö²ÆM×ÿvƒM]b§�»Üß9wï¦î³ÛÂî–˜žãMÔy¿7×=É�œï½…ß¿þ7À®èÃ0úØOv—½pƒ=ÄÙÆ‘±�û#‰F›°±ø°@-Ð�;­ã¿”DˆbºS ÀD%79aPNçâ´údíNNÑeNÛÚÖ†Þ÷…�s�s|¯h¨nñy.€îï€/j@{Éa4¡ø7ùèw•äŸ:ˆ8݈$Ñô…§þîÿÃX]i®¬èC]ŽK÷î`_ÊPÆ>r³ÃøéåÆW§ÖÞ‘uËì팉»ÜaC÷º×|wÏûÞï»sGùÚç‚ïD”£løÀ!Þ0Š×ãçxjB^’—åîú‡G=ó>¢ú#:o´Ï‡ôd~™™ûpz±“XÜ9aýL·¯bØÃIöP =ÊlOô‚çþ-»/ˆÝy\Þ‰„Îõ]¯õœñ ^ò)ØòùNÐ<_ôÝГaRõ]Ó%@å•´�„Ô}ßæU�ß Œ FGù™·¡Ÿ™­_êê�…NÀ_ï ýÑ_bàŸÛ¹ÜñŸ­ýß_ ÞÚ½ Ÿê[ññÛñ- $4 à@ÿ “I1L ÔT JM^ÓiŸå…æy™æÁ\rˆŸ’àšà ž_#¤ßé)EhÍ g‰�±€œ!aD ªÇÙ‘D Þ!‚Ü ËÕžÞÂàù`Dá†D‚!à%á2á.ÞJ ÂQ`äU!ö]¡›9Üåq ÷!ø�aˈáVÅ Ö€¢áMøÇŠG¾¡ˆUP••¶^â!ê᜵Üq5î™Q â'¢ÖÄ!†`"*à"îÌáÑŒ6š�Ea$Ná$¾‘nDàŒqYX~õ_Ѽ (B@MÄ(îâËà–lK²HÅÊMJ€„ÖÀEh)ÊYð�<Î#ýí¢Ñ|ÿM—=VM4 ‘í—úT”ÒDŽÑÛŽ�‚A¤-$¤BþC6d†@F�ˆI?ƒE^¤BDY›a…à€!IH"Õ<ªI–dM£"TãÉ\ãqe£6†P7~#„#Ž#n™#½T¸Ò:¦U;Å;î ZÌ#=ž=âO>^Õ>²H?æÁ?ŠI@Ã@ö^A¤A*äB6$C>dHä§P$‘]$F&D”ý†„GîHJƒHÊcIš$¡¤JöKZļä#ÅäjÐ$�19âäT¤£™ô$Lý¤P¥L%QòA=þ!RZ˜>Š?öãS>JTN¥Ží|YåUb¥-håVrÿV@da|å£T¤XCF*˜Y^âR \¨eHÕH¾%!eÖ_¤äüXc…a£�á%3éeH€#YÕ€869âG¦&�DfHfP æj(&Q6f_ÚXS:gÊÉLSªÏ3|'xæÁeN¥fÂ/œ'zzæg‚f†i"‡iºjŠåjBBkbEt¤e¬e[ò�mÞæòÈån®do¶äoçÖ gçgM"'n)ç9êäG¸’vΊ;¦<Äb2æ�¨ÏQ Ov*eÛõ@wÊx†çxdyîz¦§g‚æ/´çh–¦¾€%¥¦j’%k2œkJf~älAm¾åIææ\Ö¥{¸ÿ$‚¾ 0M îeqú!3=©3�„æ$sêÇ…ŠG†ÂÔ†’A‡¾ ˆ:¦ˆR&ÌÜÑ-r'šÖMŠ~§xŽT’gy¾èyª§Œ’Å9VD†�}†#àè~éh}¢$~¡Êç~é<I)Fä]¨ŠÈ°áÏË7†âpÎä”î3i*„b)k(K…K—ŠÆéü„tv*Z4™ÊÎQ„ µi#¨i‰z“޾é3ÄéðÌ)‹Ö©�ªgvyÁFìiœu¥Ÿ6  j訪¡%Ö×I$jl.*[Ò¦<:*€ŽŽL±ÐÝ(i+ÜXD]ªðdê¦z£”6(•Þ”¨"~ˆàX(‰Zÿ…x¬ªO´ê‚²†..Y™àÑ*)Ù*®¢Êèjjòª¯¶Œ@Ò©fÚ)/øD±+É|TDþ©aêi†ejF«FLë�U+Ï]+j+p+¤l…+¥º¹r“¹&NºFi§ò%ãÙ¤`Å+Ì+ªÖkÌ ¾ö„¾âG¿Ø¿ÂSÀ D­™vÒŠ¥Â®(Aš§�J,g´'IÔèDnlŽvìÞçUäg�Êf¶©[Úfyí|ÍQòªƬáÌ,§î«Í2ÎÂk©îlÐÐëY V¬ª±LYéŸa0šú”«Ï l8õcÓÞÍÓ^dÔÊ)í(!ÄZ­S`m²öÀÖ¾ÅZ®%áyÿ,K�eègÉš­¢mäd—ÚÞ Û:¦ÛþÜ*�ܪkÍžàq&gÞ~FÄMÌ›¤ê߆]EnU´!á>‚áÊâò›âÚ~ÅR:m(íê›.lþLîVnOdæ&ëæºEç‚äç~­�êkZkl�mþç訮xHjë^'l¼îîÅ®ÑÌ®LÖ-3j¼’ïþˆï^ஊànPñoÝ$/°-¯³:¯h:nô&ìôF¥õ&öò„örVÚ…@÷šÀ÷JCø&Ø‚ØÂæùbkú¢.X´Ì”µ° ¿0 Ÿ Ç0 ×° ß0QÌ0ï0÷ð”é°±ñò11'<±ž±7±?qu01O1W1RH±g±k1o±±w1�1ó°—1§± Ÿ±·±÷R@!ù,ÝÿH° €ˆP¡Ã‡#JœH1bÊ3jÜȱ#C� CŠI²dÅ‹?¨\Ér%—QžT(3cÍ…Üœ(s@ËŸ@]òÜ9ð&јG&-ºT©A�&£J�JդϠX³~hX³iÂ�^�>ÍYòªÖ MÓ~%»Q-ɰUãÊ�U'Ôƒv‘žÍʵ(û/ô‹gÞ¿wãåzx1Ó‹�ŸN¼x¯ÊÉ�3'Ž\óæÏ�)#e ú±iš˜ r¦Ëºµk��;Ç´ŒV1Ì�¢oŽÍ›¦mÙª Ç\û[5íÞŠ‹ßí7vðäŸ/t.Ü(qàÑ_kßÎý!ò iÿÿì­[7Ó帡;®Žž4õÅÖ•‡·ÜswfÕ÷¡;·ûžÿõâþ%`{ÙÁÕÝ�Jõ]OâµDžl]Õלzìé7¡rïUÞAÇH݇þ¢|^ˆ]†¢—àŠ,Ƶàl ^Lß™ØUˆ†IWÞ‰ޏ¡Yg½èã~:BØcv"Úxdжèä“e5·�âõTÚ†9b‰’gNfßfø�ùizíåå`nyæiûå‡X‚¡é&|Ñ™�Pæ©§wca¹§“xþ¹g ‚j(’xÚâjŠÊh£�F”VªÂ¥@d:æœÞá© †*ê¨B”jéS¤ª*¬¶z«°öÿ ë¬GÔjk¸æªªªôêkÀ ư8›Ä±È lÌÆàì³>D+í¨h`íµd«-ÜÚuÀ·„ûì³­¶*¹èrÊ)ì†zíµßÆ{À¸Îîšj )„ ï¾üÖPƒ¨Ö*!°ñ† Áo¡0(4ܰ !q"WlÀÅg¡qƒŠlÚ^ 2ô:ì0¬n¤¼B,³<0g*3èêa3£"ê <Ÿj¹¬šÜ0DÝÁќʬÃÒÂÁqïZªÈøì³Ð(ÀZtË-¯X©¥˜jªî žÞAíÙ –*„ÏöN�5¬±Î*«­·æŠkÛ¾þ,°Mÿ‹ÃÇÇ*K³ Ѓ´Ó޵ÚnÛ-·‹Ko¹¬¢›îØìâ êâò~kxÛøò+zþ¬�ÀJ n¸/¡ð › ± Q±Å_¬qO{ŒlÈ#—,4Ê*sÀË1ÏLó¹6ë¡y¨:ƒÊó >»ÉE�ô¦J3=ìÓ‹O-²Õ§¾ýêÖÆ{ý5—ª óØdŠ6µj³m¯ùpË=7ÝGØ}·½yëÕÞøF,cNp„3â¢E­Å5.[�ƒÜêH69ÊYî\ðËœ»¢Ö¹yÑ tùݾJ·AÔ©îkÝë®÷°ˆMìv‰È�î6Ö1 | x à³ð—27¬ŒkÈÀòÿ–'‚æ=ÏwIØYÏNe=¬e�hGë@Ò2µ44 |Q_Õȇ?ô1Aëc_Ø€¿²Í�~¦BÕý†·è¯üëŸÿðÀæ oü›E/¿ù­�Q{`"ÈŸÈéÐzæº`Ûµ9vÎpX �õEÂFšÐ�*\˜ÐfW;ÆP†»ë� —-ª2<,Þ3!*¯f7ËÙ±”H=&:«UN|b§„*^‘cáÕÈgƒ.ÍxÇãúÚ÷¾±™ñŒ¢ªŸw…?X­àšØŒ£ÿ @ǼÙ�;à²ø8.? �ï$!½5AÃQŽq\äó8÷Há™L’“¬dµN7ÿ0L&L“²sá¢Å!†²†7,eðÆ•J¦O ­",�'Ë$Jo‰?»eЄöD ì’{TôžÓ€™EaŽ�|­k�ÖŽùP…‘™bS×3¡™¶4Ú mÕ|6³É¿mvSo{'à’°ÇÂõÑœèÄÖשCº“rñÄ#÷‰:%t’Bçõ0ÔùÓuu'%FУ”†E@"ÈšC{žìU=üa× š¼™Môˆ£´¨¦W=�²phºÜÞ ºgÅï‘ô]Z$fJ¶R S}x€d‡¿ùEOTÄTÖÞz‚ÚíôšÚôþ€*¬âz�œ² gÎÓ"Ñ�Kej ö,ÿØö¶Q�ŸÙÇO�Å«¯1ÀeVC˜Ï•Ы\ìþ:Ö�–õ¬¼C()wJÍ6¬�'�«Ë "ÙÈ쮥åô°Š½'Âoˆ¿Lk#5€Æµ�J¹Ø­Ý\]J©îRvl–�å¨2›ªÍ^÷Užý¬€g7»ÑöªŠ¾4-j‰ªZP�j­]0lÇÔÌVr1¸-nù×)ù™®ª¿µep7zOâ†ÁKãjo­šÜÅ2W eítE™Pê~°¿ÿ…›v“Iûf ¼¢ºìôÆëVÀfï¼ÊKïÙK*›Â·�òÝ.}#;YåUm— Ýæ_XXÀ;%0Ä < Dbƒüà Døÿµ�Œí:/¬C Û6·3=nêBœÑÿZ5³Š/Ù┾˜vd}®òªÞk«º8ÎZwlшá½è�Éë°Ž"yfJ^o{}öd¸E™Çª”¥›©®üêUËä³îf½,10VÌ2 ³™Á¹à5·ÙÍH…s:¨6µu‹Îµµ3ž=¬çW¸%æ— �kÉ~ºu‡®]Œg,Ýc Ò\–´Ž[:KyÁâå™áˆÉ�v»ûÓ2 õ>™M'/6¾›oªë[噕-Ï%á¶ì_qÙÖ+Àµ®QÌk57ø×oÎë¯ WìR»s´u–�=°ìÝ~ØÚx6‰hä)ÿtñ&a¬è™1Z­ß¾q¸±KiîöûÜHL÷ ÖM>w¿{lè5¬zç=ê÷ÞÊù–ò¾©ì]åý›ÙxÞe×á×T8Oà«]+Øáª…x°%ÞfŠWüâòÊx†•ÍáMœª ùŸKŽà“ïùÚËv¢ ÊíFO÷Ñ2ç¬5É-s3/–AÖï^‡¼sz±Ûç€w¦ä}­¢Û Ô´þ‚¾»Ã‚ÎQfÓý’w-ªµ§[·æ5‚ÌÚÕ.°�ý×.¿8Ø~z >LÀûÞ'ÕZÄ4{±‡ªna´Ï18UH-Ô‰jd~]Áí@ýγÀÌ%Ⱦஅ:þ˜Š^ 3ÿÜRöµÎ»ofUôW 5dÙåø­s˜æOÿ àþ÷ãöß>øÿÿÙWÓs-ÈÂx7ÀgÄ4:�Ç€Ô2Tî§¿FL¾+4p�øXÚa}Ÿ—)¡7 £Gz`zƒzâ7i«·È4{ç73¶¸§VI°{½Ç{¿§ÁçxäC|`|µ$bÉgvÄ|£â|â£vÒç_Ôg¨<¸}]¥Þ·6à·'WnP~,Ђ!¥êÇ~ï�Spö‡`û·í?8€Ö"†ìrÄt* y ˜}�3AØ+°‚5øMøy‚¤G‚K`‚‚§S)ÿ¨+6Cô‚1˜Wºg5hƒ¼õ.98.Äă>h5ž(„D„¢b„&…„á§„ÕçyN¨}ÊÂ}3…È«˜c'@~•b~Ê“~þ†x‰cøƒ—W†þu†ø§†üG{có†<Œ}XHßR‡v(: ˜‡%°‡HH8�(4ƒè…8D‡¸^"8‚"szkt…ª·‰”2F2C‰<“{Ñø87؉Ïò‰£ŠÀ„CègƒŠ}:”„›µ„ã˜)O‹QH‹UÈŽºH)¼ˆ~)ö‹í'Œd¸fˆ†iXk؆͘}p¨rØTÓH�wèsب�CÅ�äS�¯"ˆ„Ç 93åÿ8o稈ç0ˆ�ØôŽÆÃ‚“x{õ(ƒëD-Ô(Š:h5 È-Ç7Š9�ó|9}·ˆ5 éŠ3Ó�ÀØ}vñ}ã’•ã—…»¸…½x‘뗑Ѹ‘‰†ÊĘ̑.ÎxЈvK¹’îL‰·�~“€8“àX“tq“ 'zæ(‚<Ù“(ð“”*8”’¨<ôxö˜”ûµ”@è,ü(*þ„§2•ÍW•Gˆ•VÈŠLÈ•2㕲(…aI…cyš¸8‘P‘„õ…lù~ÄÇè‘q)’tI’χÂ8‡yi��Ç—öø10i52y4¹J…©šÊ““K†,×B8ÊUpè˜ �bT”0ÿx”–x�Ý¢”ši4�¹`ºÉ”œIŠ{cŠ¡B�"ÃiBCÖw“¬ù�¯Y‹dI šòÿ,ô *öyF*ó—¤JúŠ%…MúŸ)x´i›]ˆ›Wš VÛ ê›]*—_:’8œ'jžV¦òr¦›Øš¨³¦ëÔ¦ú¦I‡js!§@`�ë…�wª¢yÊ¢|êà)�™R£ƒA ­ÒJL:@<šW‹Š|@:ŸBZ„¤iR“Ú0HºŸK ‹_9‹œú¤ž¥µ9¥·i¥:Œ¥º XÓ I! ¡›"¡cJ¡²zÊ™˜+¦¦€Saºê�‚i2pj“#z˜ ¸‰ÄªxšRzÚ¢Þ©¬1ž€:ž‚Zžë$­ÓJ>Õš7×*†Q¹�� ,�j‘®(0®üi®­é¤Ï Xÿ8 iY¥k9ªÙjªõŠªøê¥`Úªbúªd*««“Qˆ:R×kSn ¢½*¢—jˆt:¬v*±ÆJ±Èz±±¬3ê¬KH ­Ôz¨Öš¨}™­R¤TI¤âã²0;¢L –:!–5+›â–‹ì ªª³j´:á–[šŒ© œ¦ñ:‡ÿš´‹“¦JдOë^аª°S;1?ˆÐ¹žk€™“9¿f0óNørº)FÝU)&Ñ>í3mêW¡Ë.e[» @ºáò:¯³žeÃ)ÍcD³[qB`8¸ ±û‹ ö4O³eª‚ºøÒJ¥<ݵ„ ;»Å«\ïÚ»½NÐ�@@$ÿð»73»¿†½”S蛾Р3k˜¯® ¾ðK 䳋¶[¶™h*ùÛ´µ»fúè,XÓuKc­œë¹�[½¡;º¸kºÎ«º’ź%ẗ»êW¿÷ ²Å«» ûžâ»â[¿ÂK¼¸{¼ë—¼Ê[Ì{/λ¾®43ÓK} œ9×ëb”³½Üë½à+¾ÎC¾mf¾å’¾ê»¾í»¿à;¿¼ÁÑš¿û *ý+uÿÛ`ÛDÀ:`À0ƒÀc£À ÌxõëÀ¤ Á¨+Á@Á$aÁ*€ÁþÒÄNÜÁ Âw ¿KÂg¤‹Âk¶Â,köâ¼)ÃC4ÃvPÃìrÆÿ–Ã:ÝÛ�=<Â@ü`BÜ*DŒ¾0|Ä �ÄJÌijëÄOœ‰QlS,pU¬ZWœÅVÀeuÀ­ƈ€50Ë´¬ÇC-j�˺\ÈL)q!`XóÂ<̆c€‹ÓڼͼüKÌÎü†£\Ô¢ÌÊüÈŸ¾Ø…]Ê¥\‚äðÏN0ÏôÌÆ�L�Ïú̘(ÍGåGÔÒ¿5ا,8©ì?Zܮۮ̰,Ë´<˶.¸¬Ë¹ÜÍj<À,4á,ÎMé3Ç,*æœÌÌ< Í‹%Í FÍVlÍô‚ÍQ³ÍÜ,½’ÿõÍÎã¼Xå<Òèc×¢"8D0ÜW¼××Ò×Mð×Ô7ÛÄ<ØC8o}·�ذ²ØÓØòüØ‘M“ÍÔ–ÿ�Òÿœf¢¢Ù¼ÇÙ ›žµˆÅþcf Ý>°ž‹Ú`½Ú™ØÚýÚëÛ;ÅÜÂ\Û6pÛ ’Û»Î(�R(kÀ*ÂMÜ.=.Æm-È­ÜvÀß=.­Ý…mÎ=­ßôÂÚ£bÑ÷=3>Nií0k=änÿ>6¼í0¾}*MnOåC6å2]åAÞÜþÜÌÝɼá3ÓበæbNæf.hžÏ(¾äCNLÅÛ´qn¨ïT.2^çeuçòÑ9î{}îç=žß?¾ß—Þ߆^äZnÎHþÌs Þlþè‘Þàz-å1Må4íÍËìþ,¾éFÞéÓíå¢þ@E-âG]êpê•íÔÊ~àKÙêp.:gë­2ëfçÚßyŽë{^ß»^Öøý5ú�MV>ìüÁ麭èžì)¾ì+}×Ê2ÜPîìÎòàáÓØ„.Ø™ŽåÚ^ìÒÍå^þåB}Ýàî¤NâÜmâÞ�î ¯îÔÈî÷ê>ï²ÿNçó^믑)7�Ý+†ã,árÜò.Ó-ðFÿ2Ó]ïMàI))¸†]§«êlÞAí§ÌÛ ?ôG'8ÌTÿ,#8ó“9£Óó΢6èÄjôGÿÿ·M0/bÒjõ™¦ÈÍöF_EÏ +S�0ŽÇ,ªõ.ð¬öL@Ï3s).JÙ€]üìßÝè+otÉe€5¸¶õóŽÜ�ón óÏó=ÿóA/‹DÏöI/YK?M�OõmÔ÷KpàV†X¯ÍZ�ù]/Ì_ïóá"öhCö¢cö1€ö›Høxÿnïpïî >÷:1?w�÷zï¡|�/»o€¯©0øjÿoø2ƒøÁøŽÏ˜�˜y3ù—lùb†ù ùÛÁùžß0 ú& ôü!ôJPúGú $XÐàA„,dˆÀáC%Ê XñÄEŒ)4.áã �DŽÔP²d)›¬œÑÒ¥˜1QÌDqñÅMŽK<îŒÁ' „ŠÄh¤Iy.Ò”¨P“L¤>¡ZUÁU¬´nMšäW;ŒPö)Ñ•i›T­ªÃí¸3nìÈÓFƒ@�šÔàÂ…T&N! D… ;`ÜXîEš‘%/�ÖòW¸™'ôàܹÌgÐ’QT¬3&C†ŠU¯f�0�7r#ß„KÙ£ÿÏ euóU¢¤E ¶… ØÚ¸BÔB”‘4ÅÇ'4¦È¹óëH’|Qªdé²¥i˜‘mâ¬ËÓ'½g‹í¶ǦBÎF�Êö Ö¬[µ¶qY,Y³Ô³@­•ì{Â-2‹nºêìÂK/øò 0Áœ(Ì0ÄŽ¨1ÇM4Ê.»L3¸0ñÄæ"í9’ @Cc4èµØ0ší…ÚlÃM·²xó ¸ª„#NFÕ\\Ρ`qAºtú($ìàKƒí`HË»ïÀï„›^hмŸ‚Ð($ø{/†øæ+ 0ñ»J¿ýÚóÏ£±ÐM@ zÓS Tð1ËûèA½$üKª /<ÿ,1 ]ŒîCÉ¢Ñ2'8Å$SdÑE";=ŽFÙh¢m‚÷väÑÇß‚#l¸ŠóÔ #�LrI@›´J즬òJ,Á“`Ë.¿Üé¼ôÆd¯«3Ó|Š>&ÚtÎø›3†:ïpÏÞú|+®Z©´2B÷2iBD+lQõRš$�3/51SMŸãôU|]ƒ-Ô™F-‚ÜN5©·Tƒ\uÈ| Šu¹ sS&½uL²3iשzIËv¹ìò&ÊÎ;Ï¡Š0Ù+�ÎT“¯³†VZËꬖÇΖOûü„k žç’x©»ò*tÜC3—0tMîQvgŠŽE_i�zjy ÿ·9ïMxk@µQTIÕ`šQ’*![å9Ô@pûí†�x8baoóÉâ“R²2ã'66 Ø�_YdHÊä"P뽕MjùY8ù»`rÊe�G›±Õ6Á�{¾(ЉZÜ’È5ÚÂs3Tµª›vú1¨Á›šjy¯–(ëäÖÞÚkÈÀÎqð€wøGU�`ÕÕ„]|î†çî¶îžîIW½ÓªÊo™:\ð¥/ÜpÄWyÙ)Çïåö(¯Üršk~êæÍ3ãy ŸëBC)<CF�s±u×=í9Q› ªf»ˆà5ºKïNp£ßu�l+ ÁÎö„´!/_Ê[âöÿ°Ë€np›žvªÇ7—`@…+ÜÇFxž ÄP†g R¾r&õMnJ8K”€¾®äð–³Í2·§ß$±:›Àüê÷­û ­tEKTêúgœÿUM^_àbHÎî€T`jˆ/BPlÀ+Û𠆶ƒ©ÍS.êb;èÁæ¹)„¶’ ¥dBî¬Ec-Y! µ¸úD†3|J û“²÷q‡=ŒR ,yILZRˆDlßõ¤Äß0щŸã£uÂ!¢éuHS�ÿ’£Å-Öñ _,�ì 8FÛ•q!gDã¾¾Ö¯°ý+x=rã3ø*:ÊòŽÔ£eDØG¼Qé„‚ì! ‰�ÿv)‘Xd ix2BÒ6’,ßS|˜ItÖ`“ì3âû°Ê%n«‰ž“N)E‡¿T–k•üK×+ay"YÎv´¥kGF]ò_Íá¢"5—�„rgIBE÷jÎ`eM/µ=hu¦33@IM ­­ ‹pŠÞ¦™V±j3mŒhº4¿ˆÚà;ý&âŠà u›_ÑK7+àÉÞì°}í3AS�ºS¨ÞÀ‡;äÕ °²½`å„#xáj|è°º Š@hÉF9º6]fM¡kÕC¿àÐ-‘2§}JE“pQjfÔ¬õçGR‘ö€¤&-)Jµr&–¢’/jBÜfº�šJæÿ¦<Ë)T g�  õLO²AQ»‰T%(u©ý”?EåíÉiË?{j˜�VæZ½Lͱtó/kSç;ïyÃú-tÀç–è6g‡-’b+¹é.y:³ŸqYÙêWÏzJÿÅõ�{½ã`ç6ÈEŽ‚í‰Û2i'ÊÚ‘ÅòI±9îK�{NêÞ›ÃÚÆ8×;OvÎóöø×�ç½Bÿÿë›üðH|‚Žl§;!uvä¥ÛU¼\Ý$•?ì嵬ùx¼0 ßÀçC_òq;E@¦W êEôÞT·Wˆ­çÈë»ûyÇ:ï Û{¾û~¡¿÷^ÿ\û}=�nøƒC¼„S<†K>¨#æƒ<Ͱ2èkéÃ:Kª6ëë: øºÆê¼nó¾À½“?õ ?¤h»IA¿6{±õ/w£9Ø»;Ù㮜³½Û»¿ÂÈ¿ý«A9Àµ�²ìÁ阎J¹ "Â",B.ó;,¹& Ш˜‹K­)A'hñžô)“1-ܸ‰©áðÑð1CÊ",<ÃÄi�J©”s‹ÿ‘5ÔŒèØžD¨C;ôÂH@‰Žˆ™øC@ÄCDOÁA\€ôÁL� ŒË)B#Ü0$ô%dÂÏpB9±Œ(Œ/‹Ë¤*$œ+ÄÂ-ä†ÁC0”Œ1$Ã¥0C4ô)þˆCÍhïxCJ�En‘ :´Ã:Dƒx4>ì?Ä?äEB,F 1DLD\DF$!|DHÄ�#Ä¿$¼&K,LìŠËØÄhÒ*„+„¾3E-ìB/<ÅÈHE1,ÃjEWTC[\£3¹ Z‹xœ€9 ]ÜE/<_üEŸ Fa$Fc,ÈÕ@F\SF;`ÆF|ˆF�Aˆ·J´Ä³ ÿ2ÙÆÓò!3C§³ð‚#¸q$GsŒ©‡"uôÊØ–lIwt¤¤¸GY w±ÇxÌÇ�ÙÇD`�ÈzúAaüCƒÊc<’¸É¤LÊËò!‡ ‰$«j,¤ËÂH£¸Œ�¶ÈJ­ìÈLúH¹Ê)�€ÂA<<É¢J$XÉ–dÉè¨WŒÇ™´�èð•J� »¬\ œªa�ªñIRúÁ$!JÁd <ʤDÊ¥Œ’¦´�§¤ÈkšJª"°ÔÊ­/�|Š hŠóK±”%²ôB³T´|¯µdËÇpKx´Å¸œKð¨Ë»ÄKŒØž½\�¾ôKf ÌÁÌM„(̆9LÄ4¦lÊÿÆÄ´„LŒ”Ì«¤Ì¬4³Ë‚�ÚÌ«ìÌ:úÌ(ŒÐ¤œÑ<­ÒÜ‚¶”¥·TÍò Ö4�$yMØ��™MÕ¨MŸ¼ÍÑMø,Þ¼ßÌ‚ÄÄŽÅ|Jt*NÃAKä IåŒæ4ç¼è Iéì"ê´N7¢ìŒªíìÎ:Ê ­Ð{t�Ϙ(Ï׌Ž$QOÅ`O€tÜŒOøœÏ¨Ïû‰ü̽†ÙOª4ÎŒ´ŒÉTÎ%�ŒNÉË#aÅ¥Jµ\K í¢ µÐxÄPñ| _áлôÐQ×�¿<}O=Q£ìMß\Q‘hQþè ÅH­JMN¯ËÊQÿÝQÏìÑáøQ¬RŒÒ–,R.:R UR>´‹hÒ1Ï+m)E\ºšA•ˆ,…O<4ÌÃôÒÓ0EŠ1%“2E«DSʼQíS … 'µËD�ˆB=ˆC¥—Y€EÕÍFåÒGNÅÎIMŠJ5ŠKÍTMÓÌZÓ¯ÔÑÈàÑåðÑQÒR­ÓS-M<ý‚UmU>}U ˆUØÈÕZ�‘ƒÊ¥ä(Ñ]%ʇ`•xãÕk±üÎÌ0*»²«ò!!¢ Ñ`FA�#øWÄÙ¡÷ÒWɈ‰8؃ÀÁÃXXøW‡=‚ù™ŸËXR¹XUÿ[•td—è0ÏtíXÝ\×áh×öxW˜s×§ ×zM‚{�’|]Š}]Ä~u ‡ Ø)X—-X˜8Ø` †=Œ‡ý׈噉0Œ°ØFÓ¥$Ñ�]ÚÜÙÙ® Ùu3Y¢@Ùz]YìhYžxÙŒY˜Y“ØÓ"ØÈ0X„]�žmØŸ Ú1Ú"»£U®2JÚÜaZ»L§…Ú¤�ZT»,«µ×)ñ¡8ÃP~�Y°-‚\×1Û�EÛžýYˆ Z¦y[+­[¹U º] »ÝÜ‚Ì[,¡Ú—[=¿í¦”UÙÀ�ÅmšÂí×Ãå�ÔeÆ%Ì#�\¶�\?­\ͽ\ÜÉ\3â\ßµAÿÏõЊÕs’¹™ÒÅÚ‘x]HY]Xpê æý�Ø=ÈÙ][É]ÊUÚ‡CÚáÞß _ÀÃA½E ¾u³ËBÞ”5 ʹŒéåÚéðZÈu]ØÂÐêU ÔY�­]í½]ð=ˆ´âÝ]_ß#)ß8ß6K_liö�÷­_×) �ߟ¥_­²ßœ=[ü=ý=Xþåšøàø_Xñ^¬±Ü^a]#ßÏY¸‹»Ñ]$.‰öµŒ÷• ¶à‡ÅàœÐ` ÐYÙ]á_á6á¨CáÛQa~â ÃÁ§{:¨b+æ�â�aªa ¸a°ÈáÈ à)V¶ùm0¦‰ûUŒÿüý` ¶Ý™ a%V&N '†b;Þ-)c+¾âöÐ?þc¾Õââb/þŠ3ž 1ã2–^ nš4Nˆ5Öß6~ŒU…ã:à9€8¾cNÖ�<žâ=®bþøc@Žak!£"dÆáFf—DžâENŠCF�GÞMf㊎JNâK>á¹ýÞ^îdaέ‡Øc>æXFŠÄbªkæÒ"¢8ãL¢ýÅBe/ê__;â7þ`|y°yÁÒaç»-æc6æd�e¦g^gËhvÖÛE×î €kál¾yg}Þg!çr>çt&-vnfw†-i¦Ü|Ædzæ"78¹Hh~Žh‰†dÿ‡(gs¾àöè7hÊ(è  Ç€è%^h�²g‡Æ‘žh•–h|ˆs¾=˜Î�›–�ðèé‡gÇë"Bh�^i žè–vˆ—Žé�›iËè諜e(m'ãiy¡X”þé ®êˆÆÁ¢6j|ÁÅቃîSNé�ðf«fÔk«Në;FH³â­Î7®Vê6mÕ°¦j…fˆ[Õäsµkµîëµ>’Ctë·Î�¸^НæÓºvê£e�rmâ³æk¿Žìfë�"˾ìÁ&ló“ëOåÖÄVÔÅÆëÆ¦ãÇVlÉ>í'¦ì¸lÌìÂöjx†”€úìˆp2Ѿ´FmÞ^ZÿÕfmËÎì×®éØþ�Ùþ`´&ëÜÞíÞnîß5OˆnéÆªÀihZ¢ˆ€ÚdçÞnîV è–îè¦î�±î�"�î>oôÆ—ïoñîò– IoùžïN©šö¾‰÷žjÓ¦oþîï•—û~�üÆgÈöoŸoû¾ï?æ>poî¼Þžè¨š\}p §ï¼N+ ßëý¾pßî ×¥ /mÐþp‡ðÑÖë2q†hðñ‰ñ—— ‡q÷kW _¿qÿq r!r"/r#?r$Or%_r&or'r(�r)Ÿr*¯r+¿r,Ïr-ßr.ïr/ÿr0s1s2/s3?sÿ4Os5_s6os7s8�s9Ÿs:¯s;¿s<Ïs=ßs>ïs?ÿs@tAtB/tC?tDOtE_tFotGtH�tIŸtJ¯tK¿tLÏtMßtNïtOÿtPuQuR/uS?uTOuU_õ?ÃÁ„=VÿrW7ˆY�u.¯u‚Àu[Ïr]€^ßu+ïõ_v*vX'v^?vùTvdöÆ’aov(waïˆviwòx‹·¸IÛkWrøvpÏv,Ùöž=Änrpwqw rgXs?÷ cyñÚ!¸w|‡\+£à`xïmy�›z�Y|Ï÷ŸÝ÷[Jqíþ÷ªx�¿{/øÿ!Ðwéâw…f†Ok‡xˆø‚§ø ƒ“~‘ŒGí�çx�7ø‡­48qÏÎÝ’�ì“ø”¿w�?©–_ÄÜŽùÓ~º…åøÂ¨ù!€H–×—wìÞåù¾öùÃúŽ�ÙĂȂfŒŽ…Wúˆfzpz ðÚ¨�Æ©Ïù´zŒÇú‰Öz®?ï‡Ä°7úE${˜7û†W¶Ÿo¯U{–’ú)¡ú· –{µF{»�Y¼‡½ç ¾{¿çfÀjeãúi˜†ËZºŠR/Ýðž��nѰä¸oüp~|§�üÉ\¾hÌ÷Í— ÎOzÏÿ|z}É¿,Ò7 Ó'œÌ�îÍçåÎoýÿN} }Ù¯ü)©}‘¹}X{){Þgaßçxà7œÙ/ â?ãG~Ò¸úåß™/Œç'™è×€ö!"ãï™`‘Ùñ÷ìïý1žÄ©¨¡x±ð·œñO}óŸôOÿ;žy—ˆiÓ,,hAÂ$ šhèpĈ &RŒa‘ÆŒŠ™ÿ�A Y%KG¸$›34éä“QJÙ"b[Ú‰S–wêÙR—8BȘc’YæyBž€æJÌUÖæ’o>ù€œS"º'¥*åY)¦}•#˜ j¡…žY§‘­-Ê(~ŽÆ¥¤¤bú*J—ª§¦Eqê”BM ±ë… *a ;ì¤))*ª÷°,³Í.۴Ѷ*Ö¬ÕÊZí–µuëSºòJž¯ÇËհĺÚ~§bÇ»í†ð.¼ÎÊ[@´ÑÊ[,¶v^›¯•ÚÁm®í*D¯¾ŽÛU¹Ââ{RºÈ®Û.»ðÆ;o³õB{ï¹üê©î\ûjL›¿'á-ÁàL¨H"%œÀÂ&5lÿ~G,qWl±¼è¼óÊS—äË–aç±Ï�1gã›"“\°FæéFÊ!­Œè£A³Ì4×ló³8;»3Ï  Ð÷qŒÑc3v´’H%ýgo# üíxá:MdÔ4L�1U›íð\2s 5×]×›3Øô¬öÚͱ†[\ H>9~yç�㊭¦畉ð9¡K:é8¦•¯¨¾:­».çi§1 Ðù5yî¹û°;ïøþûSÝzG\x9/œ ‰;�Aåf¾˜ã�C^Ôä“kmyÔ˜?ÏÖæ�Çõ¹¤�^ºéV‰–úꪻþz”±#6;€µ»}{î¸Kø;ðÁËÝÿ�]Å/œy˜ç¼íµ%z«™õª§€ëaO$Ú#`ŒTÃ9xt¢óùÊWÔi$}ê[`ç¾°Àòsýêw?üU@ûkJÿÀc¼ /€Í¹g@ �( \ ÍÂu¹P‚Þ3 øÄ‡Aò�yŒCؾ’¤„'|Sýìç¶PŠá fXC‡DŒ k¬†›jMˆÙ;ãZºGÁïYã+]…óÄ(Š�ŠV¼Ú}ÞÔ)„pÑ…_\Šÿh@2ÞPXpD sÔX6ÑWC|$$�8G$ÖñŽ¤Ë£gV§ƒQòqŠ~l íɤ RJx%, é0Šqÿ‘])£#1¹œÖ¨±¾ü%%%.�„ä�ºìÉ'X”803ƒ�¥Hç— 9Qu£ÔA)WDE’¨?Î$,aI•qF„–ÿ³ÁhnÙȳ&¨ŠäߌòË_"¡žöl£¯ˆ9’v–%™Gdf¾ Miö…šz´æ( ÷µÄ�¦›÷ùf§ÂùJr’ÓœŠDç¯Ô9@~Æä�¼ŒgQæéK{Þ³’ѧ19Šn }e4C7MòT3} m–ò RU΢`â"EÇiQ¿¤“+¸d§JUÂRTù ;•iHZO|žÔ#LªOXºÌf’ï™0%¨ JÞ”Y9EŒõ ÖµúTG@ÿ j9)Ãs•#GMj’–ʨ¦Îå~ý+T¥Šªf¥X½É”´J—vÕ•_•iAizP›Ò q`“SZתֶNè­pÀPûRWÜU¥yõ'SŸ„Ÿ¿V¤‚%,F {Øš$ÖŸ[ hc Ù°Jv¬”•˜ew†Ù�A³›ml§< ×ÐbT\F]'ãÔ$ŸdÝçš×ÜñS‚íÚ³ ÂëÎ.à™%�7�8ïâ®t)æ<Šî}¯œvØœT5é‡vù.qÈ«ß%„·¿þí/ïx7Ãz À!‚ü&ð�OB²ìE(ò_ñö%<ÀNà™)L!CùÂ6Z4鯇ºØ±îÿ(7`ãY¬Û-Aw òݦ„w¼åÍèy%�^+­·5í}¯{ã+ß�®r?ö]Êw�³_òNØ.\q ì�ŒÐ¡ÊV^0ƒEà`/z'«…/,• o¸ÃçùpˆÍ86/ÀÄsA±T¼â¿8Ƙ1Bjìýš½bÓR�Yóc yÈ«¡ï‰Žl�$ïeÉüý¯“Ée)SÙÊUÆ2ƒ·< y™`�˜Ç¬a¿pØÃ2±ˆ}O7ãÎr0�¹[Oï ¼î ŸqìçTÏ(Ы4|£$_T½IÑ´Þ_¨rHƒçAŸç�ÞŸ-ˆ$Å\“N-àüЛàÇñÈ ØÅÀÕÝëݳIš³•_´±–_e�D)Á„©ß°_w<Åû•™©9^ÙQ ÍÝß äÍPÿÙ“ÿ¹˜æ=þ¤œôKBÇp9U½‰2`ý8`“@ I îÿœ†šøi Âq ¥yà€ D�`áMÜá�Gï™ÀâÉWÐ_ îÉ ~È ÄÐ ù\¬e»mžÉ%Açí™Øù ÔÉF:È& Ìá*ÐÞGòH¶ÞŠY–ΤQ¡•Y!†“†á�‡_ ^û%A ~Û Ÿž0Í�žàLX+¹PRÄédò@^ŒÌÞí�£AÝWk¬Å”„bÁYÃ!ò@Y/®Ø›€�0î]fd¢ =9936c§9íy€gTYT£�ÛSìJ™qãqÄ|#8¾Ø‹e� ¡¢UÄ"a<Í'¶."�à´Òà)Ä)ND*ZÄ*ŠÿT+jÀ+ê:ΟaÐâjØbˆ´ãôèb´ñ¢pøbBb^½##oã1&A2îÅ26#3>ã’Eã4ÒA5fÁ5Ò]6 Á6r£y€c8Šc �£þ˜#ô#W¨ã�€"¿‰¢ÌÀ£D&Á<2@=ÆÀ=ÎS>î#Àdaü#@:‡ZÜbMæ"Ší"Bú…BzÆ :$D~INºPEJÅEb¤FîGú5ZcÉa£Bhã·q£¢ä7ªäJ’O9Òã9.ÙÝtÈ:²ABÎ;âäÑÉ£D¹¤Xù+âŠ+î#QzÅ,¥@È]âœéeSD%T2d´P¥Þã êÏgA„2ŽF2££A#íuÿäG†äŽdIv# ¨å°%K�K¦Lê Ì!�qé�eê%VŽ“_ö`â£`ê#aÊ%r&@&¦|Œ^mÞ&Nfò|€s>'t:'e€rjÀf~p Ï…|æF†&Xz¤XÊ!Y&�YZž¤Z²¦[¶$\¾¤pvEln ¾MOrFdw„`i§ +Uê©"³Z�³î#´’ך–œ�ªð¶ä(]*”F)é|k•†ë6Ÿ>D¹ƹf¿¦«v(xºkšæ¬fH­’À½êé„辦jFùkJ)ȯ ,n«f1¨w ¬DxÙ²Ú@³zdz.ªÄ6ªaTlyT-ÒÖ’V*ÇB©·B§†ì§Éj&©~–©zF†î—ª¶¬ x(iº�š¢&WÔìÍæ¬¾N¿Žarü+° ëÐlÑ«Ž íŠ*m¡ZbÃØÃ¾bÄ.ÁÄN-ŠY,£¤�Jd,ähkàrk¦–ÈF¨È~ÿWÉNÅÉ^EÊZÄÊfÛºíXÂ+yÊ+‰ÒëØk\àªÎâ-ÏöëÞþìsÈIe`øˆ­wt¦ð¯ðª—ñoòÎÞµ"TÄÀ\ÈD¯ôj œýÐjÍd¯ö–÷v¯ììPï6‰¶’PGñŽ“Cô—� éSú…„H _P„]àݨì{š‰¡lH"ì/ÿ‚�@LÃX¥Þ iVH¯s¡€òRÅ5}*uêÏû5ÀxpXFf{è.FIøžÈ!â™/¯ñFò"nâ.¯`6¯šogfe 1ò1B±A$ñ�”Iëï'‚ÿ ÄwKgXGïk1pñ(9pijbOðT°³ï®«ñ~tp­5…ð^”ýpÒ’°�x†òÚq ãqýÚ£pðñ5ùqî²Är² ¡QVÇö°Tð2Ùš@#·0;‹OÄüþN1Ç_rzàÇ&°x 0Xq `qW�²)ëÿ*ƒ1‚ò·r{ÄÏHëp-³ñ-#D.“Ç./r²Êñ/ûE0À;ï8#2�’2ã3ËjN+/p\P3"¿â…`óñ8²p@2/JrAPryŠ¡LÇ4:G1'¯30>¿³(gqâD3Ÿ²W¦=»s �±?Ê@?ÃÈ?Å›Øò tgêòЉt§Í±1×±C3D Áú^õÓLõ*Ðõ^td´Q²4…G;¦P†4BqCl³#$J#�JDw59»´�Ä´LßG:wòS|²ëôŒrOo1GA¿b*G0+»2?Ãò‹ÈI*´~T Á6EéÆÿ”]'ôDXµO2ôî pð3W[±Dƒ5ŠqVi�Yg4ç°ZKUÇvö~1## 17?²7G28 ïìŠ^I½%Œ_ÃôL‹€Ûtðv(6O;€Hø4Q4ödç³d#5e/ÈeOOi6A¬oÓEÖx|¶U„6U|éBcõC¯°q³ö1ÓLÁ6ùȶZ–_-öm“T+µ¯zg…H“´I{F] ‡$?E^[1r·œ°,·4÷s[etãtaÃ3WìÌu+ö�06P;öPçtQëóQ'õ�Œ7ä”·zÃ_�[{C€{W…¹Æ7Óž¶0§öV±Öä·Ñ!DlÓÌlÿćx€ÛÓ€¸[cdo—ôoŸtp§ôpÏ!K/q†$w¹P¸…×4†çŠt_ñNdzÎ|x)/¶v 5w¯²wï3x»A,ëaüô�‹#"Œ£wg×ø�C|ÿeCÏwÓñWKŒ� Þ•£¤«q­5˜¸U ¯„ xKwp7Ë73€VÀ8G¸Ž)÷r¹:‡ù`¶sNs8GxxH`·ˆÓsP?p›ßsaŸøw«¸�°8PÛ�[ž¯ïž¯h3£ÜÉÝŸ'/�gµ�Ó·z…ñÈ¡+Qw¹Ä¹G$¹BúÜ Œë"ä“7c¥Çµoky™,¸g4øÉw³ƒÊ–Kxx9`Óät©?©'køt#¶u·:ˆÿ4¬“ø¬µQëmœÏylè:¯“�y[@Œû€ û{Ü»ºV3ûK`´_д﷑÷·a`»j»pûˆz;yPºwX:¹‰¹Çï•;¸8¯û^Ÿ— ¼cG`C·˜Û;™S·™ç; ¸úšË: º¹E¼‘âúL�Ól5½Ó?}K0=ÔO=Õ–ÔW=Ögý#]½Öw½×3×½Ø�}µ„=ÙŸ=ÚÛ‰Ù§=Û·½‚¬½ÛǽÜÏÜϽÝß}cÔ=Þï=ߣ…Þ÷=àþNü½à¾áÇD@!ù,*Ëüÿ¨ª Á_ÚZ­¡²‡sIœè¨¢ÅY3¶ÚÈq•Ç�^BI’$¤“(Ũ\ùñc˜—0+Éœ¹ÐVCh#J<Àó”ÏŸy‚N*1¨Ñ<&’*µh±‘Ó§P�þü™q“ÕX³úÚʵVNeCyFK5£ÏT©b©�3¤—™ ;ɽùUÏ»2šõ)«ïÇ?€KŽLH¡ÜNu![l±ì,Žk×þ# òÀË ¾I÷+ÞžS§®méqƒéÓ5kΜY¬uÝÅÄ”>šúTäÛn+뀹·ïß ,\³sN¢¹˜VÔ‹‘cGÒnI(8éU0aj.îðëÄ»µ�"ÿŸx4¨Ò¥Ê£ªoT»êÕ¬X¹võþýÀØHŽg�M»¶mH¸†ÍÕ]NŸåÅÜO}ÉòW`‚i—\‰=[c>i´Ñm±L¦p"ÄÙ€XÛO£‘vj©Ù²šL­óÚb²Ñ†kå¶oÓ则pmLj!§œ#Ì=æ\+×E7’ŽÕ]—ÝK>Ú$X;�6•xãåRRç™0äzQµ‡‘U›ÀŸ|¾xu\}÷å·_dþ½%Óƒ�âgE"è—G“U×á/‡E¨Ì„9ÙmZöÛŸâäÙg#úTbK'š–¢Š+¶øblIÍöHm4ªeãn:–*�ªDig�D Yä‘HBÿ'Ò’9VgkƒÄýèèš¹€–ãmYÛ—`>%æ,dš™šiÒWe›î…œ/¹  îz'^yòµç*}âê` ꈡ" ؆‹vØh]"F:éG•np銕húl1~:c¨£²kjލcðÁÜiËêPÇf”`‚IΓ·V¬ê”õÀÈÆ‹\¤S[,{¡¹W¦™·¤¬²š:=KV´½Ù_µÿÍ`�SØí)óÉ`I’›˜¹è¶‚a¢8úÆè‡ðB*¯Z×Õ{i‹T»¶/Œ�Ê(À!ݘôÀÀ|°Á ×õqÉÌ=ü-HS\±­+Le¯‘0»\Ø]NY›Tp•Yäb¹¼¨ÿ”fÆ®|d´ef “Ëxέ—õü¥ð$&ÌéhÆ\H)I¸LfÆ…)„¦•\8MBÆÐ{bÁfq¸ÍGî°0é›äúfÓ¾Ÿˆ“$åL'=i!v21^ë )‘IÏÐØ‹øÔçÐø™’¨�/ñZ@†K4ê™{ä™BƒI+‡>t0µÅDñX‹^Ô™�Põ6*ÈŽæ �ÖtY,IÒ8uS}ßdi/Ù’LöÈ]çDb:ÃÇ9›†2§· �7ç™”ªíŠ@]¥P7Õ%URH£R¿6U@âOÂ06›ŒÎ*ï‚EzLdAÚ‰ ´T’HmSƒ±Y`t6Êk¬ 6‰Ðÿ.ò¦È­²U—JîŒLÎ.oÁbÛÛNj2˜ÍlkõŒæ×a})ß ¦K]ÍdVÆÈ® nÀÝâêéa´¤lpîê ë¾ö�CªMÖËÞáÎ�w#lž«l{T1žÆ––MnkÏë,оj´¥=-jUKPƒí׳Β-mŸkÉÜšb·î}ˆo#w à —·¹`°%� ˜äjv³Ìu.ƒ$]êN׺™Í®1¶Û]úJ.AáíMLb^'æ)é {Û;\䈄ó m}Ëwß2æ·CÊå¬�[æ_%X¦ðtR+‰Õ¶ n삟ûC8¾­…�Ñc ×wAððr#ÔÜgh˜ÿÄŽ4ñ‰ s]³øÞ}q_blÆT!9³ü½±Sr<•¯×½>þ �•“gÛD¶ÈZ%¸dư™! 4«Älñsá\R9ÅØÕn„¸‹gK¼I­å©È ì@×ÇÊ‘m—M”Ë—ÑÆžåK ];I£øÊŸUçÅHZ(szÊ&ÌÁÀ�å.m¹Ñ¨†Ï¥æö�¹Ì >3ån Œ»yÄÑ�³œ�mça·¸Õdžq²Å;ã_Ô8ÔÏt´¥MqzÊSÖ¶[�w¦í0p»²—ý3»y…i�húÜÀÿñt�Y êØj™Ôù>µnÍ4ïÕ{®÷–uÌ]ë}ÿ™Òþ~sÀ{=p:§X؉!v£�ÇçË4üáè�8ÅGm·‹Ï&ãÛ8…;þñ�yÛè#g²¸�Lî£Ü7TV9aZÛZd¸½e9Ï»�ï¬\êx¿sqûëå¢Í�v©¬Nê ¶·ü!m<ƒ1ô‘êýºÂÀû1ôpY<) å&�P’Èg6 Ô�¦.m‹[½H‹fJ£—xù¥Nçë„Ir¥!~é±gºìæ>{oÒžî„nGÜ%"w˜›·3—wŠ$OùÐòýÂfS<Âß’óuè÷�N¼®‹Ëx�8>öžg¾ÿÁ‹½ë=?)óËçiìyЇBPÈ!=Õ9fõG ¾y¸È¿þWß¹Ö+[G°×y”ælµÇW¡eSŽTn›¦{Á{UV¿|× ÅWjð–|v·|y7~{—B}—·}F}ô'ØgcÚ÷oÏÕ}«ð}yâ—tW\ —è7^êw/x]îD!/Wu§Ç$¤ûgl¬÷$®6!7iaW€†€%¥€ ˆ¨øv„C|J1wWwXqw(ƒäW$ÏkÑ'‚·E‚ÀI×gxÙ§}Æ‚.È~08†u¡t•wy7ˆ*ëçpíz~÷ƒ@X|Bxq÷ãF˜ÀÓ>Iÿ˜KøÈ~O87%×'W…q…hx¸…Ø…Æw�¦°+!†“Ç�¶u†~'};Æ ExX‡((‡‹w�7gàw‡©H†BgyçGZš—ƒMèyÂЃƒ8…hˆô7„Ÿt$‹ˆ �8W�Øt¦2‰€X‰q‰¢…{ È€œ¸vž¨…ïŠIá…;ã`¦¨¨Ø|fè�Ðç®8‚>1²Ø‰l‡‰7‡¸è}º¸ƒ™ƒy8ƒ¶Uƒ0ч›§ƒvȃ‚‚„¸Œ³Õ<õ—ˆ�ÓhIÕ¸pó‡/ØZ+–köw|=ã3PF<š¨S?'�WC w¡aÙCa`V nj¨ ¾ÿcI<Æ[´Ð“¿x¾6‹l'(ÒP”9 %;6êÚ\ìz$îÊŸ¥¯¶³Y1³²Y³7«”9K›;›¤þê³A ´CZ¤;s¤«¤�µ‹ +(‘j[“ŠT±&;{OûŠ>�­R‹±Û:‘e•=©Ð±æ4: »";d$»«¸_‘²¸²Õ×6µƒ¶j‹lû§nû¶õâ5o[s‹¬?j·o)¤‡J¤ÅJ•}+`¨òNlIûƒZ…[© ¶' …ôx Ž;µŽ)¹ÒD¹xŠ§ï’¹Ä°¹´æµž›¸7)ºÿùª,k¶ÀKG©‘º9°º½º¯±ûº7»³[´sj» ë ˆ*´¼K·øÅ#åû–�!ÅËQÏ:¥û¹7¹�\;Ï ¹ÑëŒA¹hQ½ëx½Z«¹ ̹%õµNºb«²d;¾ ¯Y…¾ê›5[›®[)°û¶ñK¾¿�³ÚvÁçv)(½í“ u#Ž �/õ²B<Ä—"®Ìúa&Á©ÀtÛfšaÄÆPÃnGlÄ–¥Ž k˜Q+�î ¤üL/Xp¾Xy5˜l,eÈ pÇxzy;zv|Çåvƒ~ 6&¸YR,|H Ásõ›X`ãÃÄ•ÿ2ÄDœ"PLo¬æ©ÈæqN¼róÇnš©ísÅXŒ†X\|^Œ½aœ:£ÆægÆvˆÆY†©60ÁÆ ` ÕAÇùyÇw̳{|¶o|RÜ[‚lI„¼ †<0ˆü Š|"Œ,ÄElÄ�¬·ERƧ±Z—üË­¢?ÁÉX¬< <¡£|Á`ÜX§ì¥5xÆGœzhΩ,Ë´,¶L›¸lǺ¼Ë£Ô˘ȈHaÃ\̦ò'?¼"ˆEÊÒÌâúÌ¿XƒÓlÉ“ÏZŒÍ�‹­�ìÉ ÊGÒÅ‹øÅ`üJJQÎ’|ΫœÎ±ÎÝÎmLœW•ÒòkÏ—ÑǾ\ÃÀ¼Ï·ÕÏ<ÿ|º�Ì�X¼š�ls‘üÊ“¼ÐMÛÐÖüК¥6³Mµ½ÛŸÑXêq£§`ÛxÑÛ{øÛžÜ#=ÜÑ\Ü/ñØÈ�ÜÄ´ÜXÙÛÙÚú̸§à$Ô­ÖÖýÙÚÜ3ÚÑÝß}�á�¸ã�YŽ¿¯ 3±� ë=í}ßQ!ßô}öí¥—Ü£ÚÊþßÇÍ€>àþzî{~\Þ Þ¼ .Yâ…’7½IÒÖÙ=áÛmá÷ ÞŠ ÚCÞÏmÞà;Wß%âVSŽ%ÞÑïÝ%ñÝš¡±â!e�’üâùãXÍßgzØÆÍÕ~ãÆ“ã:îg…×ãSþãkX�Ó-äÿ‹¶�‚ä~ªÝ÷Ëä.ŒO.Þ«ÿÍá>îáç âé-ÛYNÛQ!æ¦äå)æSáU¼=30žµ2Þäm~’pîArn;t.”NÖ™-݃Ùà.û'QtäØèJ>è¦-ê/QnP Rž»�~=!Þ#>[nÊ]~_>Ÿ¡¡éŸÑâeŽß�§ß‹­æríßaà6^êosê9¢vÉ{©µø Y*N^#Ãtª9A£µÐGÀò>益 q�rǺ�µÔÎè˜6Hð1Ñ›$”zѼ°‚O}0ïónÑÎqy3Aeëz…Äðò>ìlNã °ÒÞÞñ:îâ-î¡&º"kî7‚î¶«î_îÞGEbñ!Pï÷ÿŽùnÇûÎÐÐéoÿnVY!ð+Ið¯qØ–ç§�ðøóÏ/ ÿ oñy²Ìñ_õh×{!ï”#ÿÁGmI&¿(_äÿ~_Ñò)ôò/ó™]$57_×ý^åÆËóXáó ôA¿1Z§Ù>aô«„ô¡+K_ Mÿô õO2õ0lõŒŸrX¯á"oÞåŽIëròè.ö+_ö4ªa0¯öÐÌmÿö½÷\/©tŸ ?ð‹‘÷Y7ô-Õ÷G¢ð0¿£ƒ_øÜøSQÆmNõ�ÏøMϦú8ù,zî—Óîåöª6ó³ú•AÍä©ó¶ðY‘ú?¿ú¬Ï°¢à×ÿ!ûOûOñ�oøó~º¯ñ¼ßûUÿû«Ú¦ˆÇõ%Où”aù2\äÇ¿ù ÖùË¿ö ± „5Û¶oßέXú™åË0Cêì#ÆõëDZ ´d´Éöÿm˜1ïÖºŠu§<{÷¦*ôèqI‚™6 Þ[êÔâž=£¥^ÝúuìÕý‚vøPò\”(ã%^üïZÁ�)O4\ ñ�ËóŒY.eÔ‹3äÜ+w·D†4ÓN³K¿—VÓé5Ød+$�nÃ-·V{.ªÞ~ .„á‚*9¤;’ �»°¸0¤Ë*;[tñE°¶K¨­áºo¢ðN�7©1=õÖ‹¨½÷âÓh¾ê‹è;üTl¿Xúóï³ipÀ’ 4ð”øTûè7]sðAs�Ð6 +”éBY2d­ÄqBÄäD<ΟØDQÅ`ôóO@Ï’ñƒy‹IsÜÿ±¦ò¨*êÑJƒfRJ…ò°ÄŒdì"Ç [òƹò{ò%Íúó @C$Ð4Qeò20óL3ÏLs �ØtS'/zõ5NœªvX:ñd“5ñ¹ šu–Ï@£•VÚA =T“Ý�щ‚´N—ÒJ-%2S#‘TRDCuÒURùãìÔ*CS5Ë[ÝèÕXœµÌ37¹×XtjØa}ýØU¶X;ÿJVY &FÖÙgUœvcŽ[¬ÖJï°U&Gb¥©Qo!w\r¡±T™sáÓT]OÙY"}5‚RJz Y´UK˳¿d-L1þ…0à�q5ø'‡«P¸W†vÿ⤎µ¸7‹ÿÀ¸Yh;{l²BLªPÉÚ�ȶq¯ŽâN…Ö1ɰûîöÚ/ÇFúö/ÅÞepÂÓŽKKW/òvXÈ{4Ê+ŸKÌ3ÇëiœöðüóAB·btZ{+�a»æÓ*Öèúë Zlݪ¨Ã&ûvÜÍ2UÃ'+‰mÜvn¹ç.³î»íÎÛ°½Ãóûïº?“ð G\ñÄçêÇ#lòÊ)¿¹BjTcWGP†òvs„`ÛöÚQ�±ácÞü˜#@&R�ß*äD´„HEò…‘ü^Q ©Å.‚�’Q±äúTø>–‰“Tô¤EùLhF‹”N, É€<Úÿ¨²LZje{^žX¢h��"ÜŸ�Ëâ¨q—Xü%‚I¾aÊ¢˜'Ÿ–yON63šûä§‹¦YÎjæèšl£ mhqP„r³@5mI°Xˆsœ„Ü\Òd¡¥s‘]¹b/³øK<Åiv ˜ç í‰O”DŸýdiKÏòÏŠ4< -hKšP…–†¦-y(Á$:N€Nä¢kÊ(UÔÉÑF*ä‘ mÃFZÒÐ�4¥ø\©K­zÕ®Àt‡2EÉNkª’›4§:¨C·Eˆþt�A•ÈP7¢'�ꩼt¤/™ê”ª=u~\¡gTU4U”V«ƒu©VMyͯ®$¬´kE¼º’žâJÿ­´Œ©P)„Ñçär/ëôh;CÚ!½Æ°+}­ç_{OÁVµû4,W{XÖÄ2b±�}ÆcUÙ�LRl�ˆ[5W£n”+­ëG!ùÙá„v:£í«TOÛIO®VºýŒ/¬{ÝbdW»¹ànw›ð†—¡ã…-K„@@ŽpŠ`ïV³øÆ—ó¥/D«–¬å¢…N)L!ŠPÄ^+bº&° «{]ëjw»Ýåîwà ^òF¸¡-9/*+¨^»70ñ•/}çk_†á÷“Øá“ã'Ú§XÅ;0‚œ]78¬†°„ÇK› ßQ‰n¯VÞËáExøÃ»/²òKb™˜*bÿ\q“� ¨ ò7~°�oLá Ç’Ç �„ÌKÄÎD2Š·’Ú'§YÍÙ‰ò·¦w¿¥›îu|$^|7ÿ ã­°y{ÅØ(½·üòmæ}7Ûß0Àp‚¼‚÷U³Zo†ÏŽßf!7¾)~r�ÁÖý2­hQ˜ƒÛÏ“5Êm~sºš¾./SÌ}‹"O¬æ8'zÑY»g!óB?�yÐÇ|d£G]ê¢Ôù|•¦Ã¼jCŸz×½ž¿ªóáêÉ:²%þu´§�~a{Ê.ó›Œ\ís§»ŸΗ¶¿WЭuÝýþ÷?Ý}/#}9ÓGÊ÷r^ñ‹¿ŽàBøž~vˆ79ã-ùVƒœ/#i€=àÃ3óì˜'=æ/ÎÏîóŸ=_ä^zØÏýô©oÝê=ßú½¼>ö»ç}ï}ÿÿ{à_øÃ'~ñ�|ä'_ùËg~ó�ÿ|èG_úÓ§~õ­}ìg_ûÛç~÷½ÿ}ð‡_üã'ùÍ~ô§_ýëgûÝÿ~øÇ_þó§ýíüç_ÿûçÿýÿ @@,@<@L@\@l@|@Œ@ œ@ ¬@ ¼@ Ì@ Ü@ì@ü@ AA,Aú´<ûüü”ˆå|JxñÍþüO÷dMå02®ÞKCH C¬ ¼\\<,Œ …Ë’yÕáškŹ:ÂóàÝQ,Z*H¥Qº¨‰šØQ ½DÆKÑÀXÑ}Ñ}—Y˜Q½ÑË ÃÝQíQ»úQ •�¶‹K„)Ò4<Ò$õÂú|Bí ÿ'Í}-ŽÞHаˆÃ¿ÐÒ-õ(Ý¢/Ó±S°„=#çR)êÄ<&M '�1(…S)EØ¡S°°S¿ÀS^àRãâÓ>}Œ0Ì@-=]Ã9½ñ,½…Œ’hÑ7]Õ(=àŠHµÒ² Tµ°ÔåXŠhÈU]m§MåÔ?õT¹T94 Qu½C½¼SMˆÕŒ1V]UšxU¡ˆU¹BL,½S<½Õ[ÐÕ]ý¥^%“«Ô`½ÃˆÑBQ­Ò|BSÒKÖ_XVkV0‚Ž0€g‘Ô¯ UH°Õ[ÕÖ\mÓðRž‹“aÙ,À3–ó E»©È0È=tÅß�Hß�Ààÿ§h_yߤ0¢#¶&¶±å…ÑæõNþEáè•bä b-µbõ5 ,Ž-�·îõbN×ð߈(_b0cŽâ@Nž!vß¿ 8ŽY“c%^ &¶cýÅã¶=^á)¦^ä4äR2$¡18‚I„T» ÊÛdEKFVG†äŒ@ãPcáÐà×…ÈäÞd�šc «ãG¸cöÌcRVa ®Õ*NÄ fej²¥-V"ˆ’åq¤»Zî uÅå1nä2öá3.žnt†­dªfôxcÒäî"™QÉ�OnæP~æQNá(V-j>åNel¾â»de(dXÆpN¿笽eÿæá Ž„ –›v~gö Çxv bNc&cd�|†‰}vf ƒf€^X~zÜôðEUþ僞ä„nenf•†ˆ‡Žè¤_4ç&ãÚ�Õ’�Ž1x y†´DË‘^›�j Î�vöª&&š'Öci~&˜þ1›i±ÖfÞZènÞ¸XF–Y–^‚CB-M ®… êŠ&ê‹6êH@ênlQ¼Æ iꧾʨV†¢êæ´ênœ fVéçåꀆ¦¯Þ0 kJÌf,Æi-ÖioNë?Xk>>Ž$|kÚä¬S¥k1jt.j¼Ökhäk£öëâìÀìÂŽž …‰vVlüeÞêÿh~ì7JÔåÄ0¹8‘0"-I“ ØÍm©·Y”´Gˆhø�”ëF؉ÖÒABgÌ›¹X F°²v³#}�¨×x”•ó…ñ^ HS"Zqne@(ô⢲\wôl~n %n1î>@îQîà`î×¥o;’nŸ¢îÕÂTLEš áîëÅÓï.îm¬ç‰°68ïSÒ1ÅPo×x”—!oDÒ$� oûF%̂׾*ÿfH 'pÓ0p§@p|d÷.ÚY²öò]å÷o¥À‚j�ë0åż.ùÿÊœùó1äÈ&S–dùrÑ¢¶6s.æù³Ü’]s‰-mšêÔjWoj á5ìÐÊžÑnd{5îSÿêí›ðà‡Weüø†äÊ0o®“råË–3åÌyà@Ù²msodZbêÔwïòåÛçþÝúÿ6Ž)X°v%=Y¸•·Wa× ƒ ÊFÛ3Üáæ’Kûýq!e‘i¸!t“I7uÖmöh¡�öŠ&„‡ZnÑ[l¡A(a‹íçÛoÄé(ÜqÈ)—\sÎåÔaJBÝ/"Ú‚�@ÊÕ�m(®ÈÈxv( zé…¶-í½G`$óÕgÿ~÷í·_‚ÿæä€x`‚ 6ÈàƒµÝ¶…Yˆádúù‘F"©$‰žÉvbŠßMYã‹0BPg„wÖ¨›~8ö¶#¦¼ôhÜ�@)Às ¢ˆLîâ¤IPz÷Þ”U>re–ç©·ž—ß�)f}ešyæniªÉ¦C·®veœÃÍI§Œv62až{þ‘áŸÑî臃ŠXh1²1°-·‰*º"£®9 )�“Þhi¦;ò±.»�nð)¨CŠZ-©Ö™ŠjIªJ¹¢«²¨…e¬³ÒU«iª5&™eòÚkjV,-sDlrÎI®¤åÙŠ³ÐJû±MÔJg­uØjËí¶Þžn‹�ˆÿñ²“Rº›¥†¤ËËUì¶Û)¼¡B7jfJr)Û”ú²Êo•þNkC–{¶ºÉÚ˜ºš²0 ÿ`›ñ½Y^±ÂÛ ÌÌRØqŸ ƒ,2fõvVèÉ(«\Ú¢-‹ûr²‘Æln¥è¦›³Î|8ûs>G7²Û› ZÑPî^¿ÿ2í4{P9õÁU늵_29 ×Áb>1œ{lÙx6«ß…Ϧ­¶ŸÍ± bfÒØ~»É¡¡œòÜqWwæõ9úhÞÊ|ÊU5wà:^¸M²Ï‹xí·Û¾¸\�w÷¸xIKð–ëáuÁ£»¨¹Â¬·~áç[ËÅ¥ÄQFs;X„0ëÙ[aÙ¶1ÓüŽeÁsYŒä!ã­†yV©™3˜ƒÀ N}‚x¸Ë �€\ ‹ö¸Ã=ÔDnb‹JT6>°pÉ6¼!®ècµ*ð°‡ë»�çsƒ!‘r´0Õ×c:áh¢‰N„„Lµ±ýôÏ¡‡8&JÀ`A óÄ@Û�#óWA æƒllÞÎ~Ô³è1gv’(¡õN–Féh�KÚ�^ÃÈp5ä‹H ohöf‡=äáÿ� "1|tAâ°J×â8ñ‰ø{†W·›*Z12ÍIR©J<ÞE`ÓKÃ�„$¤ÿ¶¼e!Õ’‡]òr‚´1ÕƒÉFºkŽ!dN‚®ÂÊëÑj�HŠF’iâáJ‚„a.9rH$R‘ÄyÌ#!ùÃIRòaá’©„"x%¨-±èdyÙK_š I†{])sÊþ¨r•[$ +wF áÆw¶¡%Bn‰Ë1áFž»ô%(™$̉2�˜<ûÔMöÙeþ3�ÍüJ«ªTP°H“šÕ ä˜IH†’†ëQ¤ ¿ù“pV!’ä¤ä9דNuB‚�ýq'<5áÐ<@´žÔ¹gòiJdò³ŸdX¦4в�ºd¤&˜%BjËlnd¨E•(EÃ:‹Ê£t@2­U=‚ô™wÿ±ªDJJMk¦t�\=Å6»yC™ú„¦6íO9ÍéÒK2‰§=ýT;ÛT¯Ò“Iö”t”Š"ýµ1AEÌ6M€@˜á�Û1B+Zƒd?“ª¶2wªÔ©dhlc›;¹ ´¦R¼¬ Û¿¸6¨Sªª†w¾œ–@ªŠr“ËÁý¼ñJS•l8!Ýé^D¢Id²Ÿ�a6® Á–ì;™Ö%Èj®RUm}¡ÞõV÷S¤”,eÇÙŸË"总ã¬g?K!ÑŽ¶ ¥½Oqã“ZÕ²v�®�mlÃ"›ÚÞVD¹Ý­_z Ïß:4¸Žî^\–ã&¹ËÕOsô\(EwºÒmoÿ�®Kíꇻõ�CÀ«&ñ€¼ý1o•ЋÐõ²—§4ö|;TY™Ð7%öE~Ù¨ßýò—¤µ i7‚Z(©Ö†á�܇†ÁLÂí§tkÞ:Õ·+.”„kâJÙ¸Pê°‡Ç\6:7OÐ �‰Oìc÷v»,Þ�‹� ãï*¼|®1o¬«óB)½<öб˜TɆLÈòµ,<»ûÅûÂ4¿KnE“�ì_(¸Í¦2�ÛÒZ§†E^Ƙƒ$f2÷ÓÌáAswÔ\6ŸbÊÝ�s4>¼›—gÄÝ)±‰#]Ç>¯8&ÛÍ“¦MãBÏøÐ6n ŽÇ£cZ>Ò{Nq‡(ÿ]iè 9&EFÉ‘¹•d ~:#®}2ó¢Ük7w§ÊWŽ D[ýžW$ÖÍ™u„Ë<á3;4¨º¦ ¯Á4` ;k]³ˆíLb<çYÙPqv�Ýbh¿XÚ„&‘¡Á�hI*ºLŒîŽ£ylñ÷*•2‘¼6‘3Ýq‰l¶ÓJn÷»GïRÏûÔõN5[Tšï&»¡ ¶ÎƒÇðZüÖ»|ˆÁ/ q¥õ¼, ‡sÃ;× [âǦx²¿-i?kдÇs!ãÿÐæ1Éö]¶��n¯<ÜâvùËIŽéNböišÝ–K8{¥gÚµo´˜dê{Ceèü-:-�ΫýEÌî$…óuÿx|*WRxW.gý¤u×§Ð�•!Ú#y¼~ ë0Ã[e?VK¾òCjÜÕñ¢í]7By¿ˆYIØG¾lx¹ùNâ†ë|9?4Fs€ùÓ?/hê¼HÆ'‰ÖU¸q'ÆaÐüÉýÍ_^¤‚.`$åuŒM•%Dÿ‰Ôj ÝQ‘uÀßòE·¸ÄóÈ~HŸšP_UXŸ®p ö5÷Á“÷…ø9GŒß*”Ÿˆ¨ \ UPµßÔ½ßùàÚéáß§èßfð_hù_¶EÒÿÄEvÅ" Z, þ�fª–&!ª… vˆfF—x`óµB–ÇòÔô9ÕU `™œaIlßjtŸ/é›Ê„ß)Р Z‡*ƒÂS]É^D¡SLá(Fž$Hj†ˆ !1(!2!³ÁÞþ‚"2#& ¦BáK"ÄŽÇÿa¢t”!ž_þ€ Z@ßn�à˜ UÐ!~ "ª…Nz‹¢n™Ÿ,†F!²_&!¢bÖZl $’bÐLb€¤â[-![Dì9!½˜áJá‚¢Žb� ÉnEVâ®[$Ë­ ògÔñ-ãûT-ÚâYàâ_è¢`ðâTøâ}# æ¡ î!ÑÍÍ1nù%ã ê£I4£""vâB|b5>"®câØ%Z¢<~8†ã&jd.päY„¢(b!6E;jÅ;’äF¸=^àŸ!ùG, Âÿ …Á#*\Ȱ¡Ã‡#JœH±bBƒ-,jÜȱ£Ç� CŠI²¤I†Oª\É2%Ë—0cÊœI³&I—6sÚÄ©³§ÏŸ@ƒöä)´(H¢F“*]Ê´(Ò¦P>�JµªÕ«§beªu«×¯`…v t,Ù³hÓÞ<¨V,Û¶pãÊ�K·®Ý»xóêÝË·oB‚€.x@˜ƒáˆ_XÌx€ãÇ "KfÌXŽåË_2k̹ó@ C­¢´ˆÓDR_°Àºµ…ÇLȦL¶ã¸sãØÍÛˆïß¼ykÐP¡xÙ&(·Á¼ù˜çÐ HŸ¾ÚµqãÈ•7ðÁ½;t à5kÿ^@~†ùÓ"R©ÞÚö€Üâ3Oœã„ýàèßO°Cóæa�EaàpÄ[d 4Çܾ ¡ þ`¡g‘·@i* G`Áív]qÙ-ç ƒ<¤ˆÂŠ,Þw}ˆu×݈¸'Y 8žhƒ„<¾@¡ þ€á�‚ö€aÀ˜�6J™’—]¶_EDIši¨©æZ{�!ט{¶å–[d–ùp!w]‰ žtÄ)'{¬¹Ç¦œr~—ß~úi zêÑùZ˜¸ÅÁ|‰¹¸'Ÿýý €X‚Æ-È@›ÍAø�?I¤†zH`ˆ8ÐȦŽÍ¥È‹,â§’2rÿ¦m7æxb�Vxa•ž VØa02I«“ @¥SRÄ+†Wv˜åz[ÖÙål‹Í ›˜¸•iæ™F�ª&v²i§ã›Ï¹Z€ v†«œ¹zJÀgŸå�÷,º„`(¢ˆ)êî»�8¤øm��]z¢¦œê*ä� b)‡¤šª.¦:ªÊêŠæÂ«µ3€c :âê£ÂËvæë‘ÀÒ'¬¥Ne²•ÜY³€j-l^VËñ{ØjK&·Ý¦™ ‰�K®¹ôâ<1»Ï�·/Ÿ~Ê›žÍ\^[¨|6Чï»ôûè€O:°¥Û€p®@îŠaÃÎ>˜ªL�Ìœ;™è<ÞT;†RàñTºtž‹úäç%‡ú˜¢Ö?Ih×rÇT^ô© }�TƵÀ°Í˜UæV»ÊÕ¯º šb‚MíÜÓ¬ µPgK–Vnÿ®õ:âs+bà:ÉqVr};g5™7N²Ó“4¥MÁuºÀbm°s®a_›§U:°•¯\ìei/Ú1©J%(ew×K6*cûƒÙä³Åj2)š7Ò–6§§Íè]³Úá´Öµ¨ó({ÝûP -žŽs!PµÑ !1ˆ°„í@aX˜œ†ì@S£HÌn”X‹³ Füµ3!t8M ¬Q•”ÆÔ“¸Œù„# /I&0¾ò—zˆ@Ãþj€V8Qb,¶¢ ™kt­A V›Ižu—–‰yŽ‹¾À/ªr@HRd‡ûëû aÁ^¦ÆLæ2�™T¤‚¦’D&Ée˜ÿ<�‚�ÛàêuuÆŽ…í`a`؇.‡{üË�/¥Ç1Jü›ÿxX*f1}\¼S/Fƈ‰p�Ûü^ÂèX=„^-�…Œ"£ÀÈ@2pÛ¦%39�ÞEŒ”ïCeFY¹4X6Œ–C� ÷Ðè×À6Ž™‡M4‡HÍ0bóÝüæ8Ï9°u®/Wñ<á _øÏÜ 4«}÷ÐoM4‰Óhb.Cú^’VÌb^l9Lç@Ó ´1Ž=  óÅ ²ƒ†¬¢"ù]I^2‚šìØ(�aÊU>^UU�kìºÛæ†M°'>"b›ÙØÁA6}”}c^½ùÀ –΂£�œ;g:Ïzÿ¶¶Ÿ±ý8m¿nË 5´â %E3Ú7ŽN1ºÓÝâuWºÝ8šñ¦—Ýé|zÐ>õ¾KÝïSÿ›OµÕž ÐYÛ§ÖfœãÂþð¤Û†â`¯€ÅËŒqÞh<1g¶��-�a“\6&7Ê÷Üg–·|Ã<u9¶9%Ùx‡6'w£#^°HóœÒÒ2]Œƒ~ò¡w¼{GÏ»×!£ïæð{UþN5ÀWý:WÖP–õÁi�ð_Ù˪�þê¥×úég�z-¯Þ1­Ÿøë}{$?1µÇiU¢!;P€Ó1Ö.ñ³J"aNÓgu'|ÇwÆw^¹å3‰1¸|ãÖ|ƒ~…·sJ2'>—x†µx1 tñ&€Ebt݇t„Ç7•‡/ä÷tûuŸ7u DVwX'^ 7Òu>Ö_ùlû§-`°„LH*ÉgPX{ƒC€x€ºgf È a�+'�¼B|íS�ƒWŽ„�ˆ¡�#À�‹&x8ƒ�dx#'ˆ×d@—‚�·‚DÇ}æaoß×kù&~5¨yPÇyÏ¢~À~TgT=øƒ“ÿ„¸æ/3@„E¨LG8"›³9LØ„!ò„QøwSH¸Vx…e–… #^ø…`H$bè}ßw|&•|jȆ7g9}‡"i$H}ðƒ‚*¨},xHôÖ‡Þw 0ƒa4ˆæ‡wˆ¨ˆ;hpgk�Èp’H‰•ø9—h™è3›¸„Nˆ†9…V …2C…¤h… X} x[]�¯†¨wX‹äx‹Ç|â|€h)r#¿ÈnÖ‡}4¦‡�ׂ‘wo�~K7~MW~›w~Û–~·~ ç~Õ˜uœÁ6’8‰ª·�OÔz÷�JŽ;–žxŽ ˜Ž¢X…ØŽÁ˜Šô±ŠÿЊõX%±ÈmÞ¦�Ú’�Ø�ø�h‰ÅIùsÉxrçxóæ‚È8h’")JgyL‡yN‡j^‰ƒ©ƒ±–�IG!9Š£HàcÝx’(I&á+I-‰Ž´“ë8“XèŽZ¨Š\ÈŠ^¸“°x�³˜�mµ�CicþˆY’ ”"H�tX‚vø”x• 9• yWi YIƒé•_iˆí�ɈïçƒféYh)‰jY€lé–——q9—uy—/9|þ1Šu‰N�…Ú¡$)Pœå­X{­h$F¢Îi(¤";¸Áæ2Ö騉—2ŠuÐ�L8pUÄ:ÿ’n’-'´`(Ó•¨¦†r²9‹Q\~¹:"aª‚�øé°ŸüY8†¡CE9^u"v¸„KƒÃœÇ ÝÙ u dZlÉ–±âuYŠÆ’!iL,Ð¡Øæà›+ œÜ5œ0Rœ)pœ/‘œ·œ êœ �!"�@�®b�€ŸÚYÜé�Kž§$žâ§$å¹%çé\鹞¤™î'ðyòY“Ìhö™"ù‰�üÙŸÞ Œåê jJF ª !é Ý¡J6¡´Q¡j…ª¡þ¡úg *¢;F¢Nf¢ô�¢*Ê,jc.Êœ0*£ÁA£6Š'8ª£»ÿ¹�Ø ß¹~áIŸC #EêGXIz1KÚ¤ð¤Qªx” ¦vŸWš¥ûéŸÀ¥Û5_ÚazcJeÊœgЦj*¡lÊnº’ Jr:§ Ô¡,ð¡½Y€¿)]{ªÄiœG†œ^¨œ^¨ P¨ñ�õ’¨r²¨ÙÙ¨<ú¨> @Z5B‘Dj æY=è‰rëÉ?ž ªE$¥õYªVzª¨ªª¬ŠN¯Ê±:«ä’Ô Z»º½ºc¿ºDÁš]èA¬Æ¢È:¢Êš|š~ú¬+­-:­/úœ×:£ÙºÕy�ݺ}Žº�ú£’¤£ª•,v©­‘©†²©¬â®øž>ÿŸñ*ªSZ¥äE^&Gn�I„‡Þëv—诌3’Áéô±ž÷<8X”÷ÝLš¢)Jb(è”»,+' ”“ÁGYL…¦u @j:‚•nHDã«>î²1rÂ]ç2'xžÜ’ØÀþç èº>èVîëö>8À±ì6ìñ¡$Æ.Yƒs?ðãÍQêåì0íþ„-Ó'Õ��’íhÊí)ëíÏîô->FîänîïNà±~ܳ îî瀎ë‚.„Îë÷Þò´¼Ôxš¯%ÿüÒ’ þ~1Ç.3OðYŽ¿PÍþìñí �/ÔŽTÖîŠð­Ü JñÍmñ`´bôî[²ñ¿êoò=.'ëÞ:$/Åçïv®¨ó®òõîòhïùž§ŒÎï6#ÿžK,\3«;/ð›M?¯YAŸðC¿ðbÒððð×¾ôzÞô‘Ñí†õí’Fõ®aõW/Ñ¢#Yïêbë ëìî/%où}�ò+ÿˆi?úU²ö2o‡nó¬’óQ÷cz÷W�÷zOV!BÏ`€Ÿ‚OøJ_æLß�NmŒÏbH¤�Xù’¿%”ï\lÙà>ò>òæ1—ÍÿêNï“NúÚ90ÿÿä§@©÷8ð€áú û²?ûTüFO JÒnô�ô�í¿¿í‰_ñ‹ñ�! ¼QР„ M,dØÐáC†$N´QÑ"Œ/läHÀ#Ç!EF éÀä—)SÎ`ÙÌK˜;~Ü(Räœtþг' A…%ZÔèQ¤I•.eÚ”(¨*¤Š sãD‰´8ÐõÀF+æ ËÃ, ´iu®•°Âí[œq'�¥›ÃÈ]¼Eôî}ÈÀoÆ�èÃða¬r$ÙØ± Èo‰ªT¹Ãòå™qlN¨A±C�!“4PÚtK©enÜÜÚuëÄ^ã8|¸.ÿÙ:¹u_¾LÄ÷oÓ¦ç '.Àøñ ”aÞœêsÁK§¦Î�8qŸG´oçÞÝûwðáÅ�'_Þüù£PHUñÜê…Ä[¹z+Ö]³<ÒªeÛö­[¹pºÍ.¼î’O«¾þÂH°Á ¡6Ãb[l£Ñ‹Ì­É([€7Ë2+¡µÎ>k(´*”ÎÔT[m¶Ùb› BÔm7Nºë†;J9 šsºè¤«.5õÔsêH$“TrÉ%ÕcϽ—8Šo+¯¾º ,±ð;k?úóï¿çº­@L�ÀìÁÁ!”4 +$ 2$Jà 9ôÄ„DdˆD¥K‘ƒÕ.`ñ5_ƒÿQÆëàp};1Ç9v\ÎG € 2¸!9(*&CuTR•rrªª¢¼ +ùª¬/˲¶ÜÏË0Ã�L#àÌ4 ¡º6k{sÄ8å¤ÓN¡ð|tOÎú´` FíÄA =ÔµD][ô6ºõöÑH‰8ñS,íSMOì”ÜRÛu÷]$Om/U0¤d•Jú®´OKý¸¤µV¹ÔUW^TóWê‚=¬††VÎ9/\!CÊ–Õ¬Y„ü\ÐÑðøãjW¼v³!J6Y”S†‘G½ý–C—»í`fšÙ5ŠGL32fð´^ ƒZ^(ë]u¢VóÅÒ"~¹ì²?€¾m`3òÿ Mƒ}Ɔ†óˆ#8Ã;5´øCŒ={ökiûd–¨³vdL>9e”Wfž噿š?57gMyöYp¡WŠð�c>¼ÈÅ£—¾©ÆQ&È-Hzr}a­ëðÃW³‡Ìqª²+ηòüsÆG8µf#½‚ê·¿B/SŸ¸ìZ·ìõ‹ÅÎY©]¾p@â.wº›ïz<àõN{£ ßbæ·ã!OyFÁSᜧÿ¡ NO„#@õæu½—do{VZÚXn>ñ©©|8ßÒ‡ ‡°¯}s�üHg¿û�&©£˜ÿv@´ 0c³cH˜@Ü1°�@’ 'Á î­x¼ù›‡”6ÏeÏ3 Í(BM…’cá¾^ÃŒ/LB ckxðI‡ àcÙäî±~øë�þŠ(ו v²ƒ‘ŸøJÑ�x³¢Ý°˜Å–ÅŒ\]\)¦¢„_ð™C¸¤4yVM—!¯Þì'(‡"Ênbœ•J$I{ae~ó³OIïsöRW#%�A r"+ÄT¦R„ L:ƒ�Žï ;Í@O)ðÓ2‚q%,yTM_rL›P*Ke*QØÃ)Jñ©Sež8zU¬f5(E¨B:–vͤn¬‹²Ò°2l|'ÂM�zS äTM;½BO3ðS õ(\�AQ�ŠT‘P IQe UµzXÄ"–¯»éÑÀšÖ ŒÕÿ{t1«CКֵJ§­ 4*à*WÑÕ®xÕk6пְ!ì‘«;Ã&V¶³5åbYòœ¯J²¨aITÙ†\6¬™ Îfu×ÙÏžO§<õ)PA•¾¦&«-@ki{]ìfw¯CÕn«[Èö–¬t�ˆe4¿B×4ÆuÉ[o ZÁˆ¶¹y}®POKTuF ¤¨výû߬ÚvŠ^ý®v+ÞÉ’¥¼Á=/éÒ«&¶jÈ­5Mn•–[×ù–¶(ÑÍï_!Ä_�XÄ#æèG¡›×ð| ^°pö`™&3f/K�û^åΕ¹è/P”Å!)> ÄÐ#q‘�ŒUM/Å*ÿö ‹Ëëâ ÀX02¦±†(˜3àÁ70òåqˆù‡' w=>r™Í,´$ÿnÉL>€“!e)†ÊAÀÓ•1•å‡vÇd³„(æ·‘ù̃&´¨Òl·53ÙÍgmp×â܃9×yoXþã¨c w™Èöíó}uè� ºÐ£&5Sm²B¹´ lnò¢2¿Ù<:ÒVžô�+ G1äZ×\&—4•Óé0shÈ.u±�­”S—,ÕªfuW\ýjÒÅz5Ä�1�iÍ2JÛÍÒºÞõž?åk ›»¨ö˜½|lt§>ñ‰—èD'§å'?,ÔÕ®×ìaÅûæ7 üýo€û;g9£*ÿ ~p»Úõ8ÇymKr&Eb«[âžÞ ™xË›Ÿ½ý‚ï|K„ßýxÉŽ©Ø …Ý?JÃYòpFœâ3§9“,~ñŒË›ãjò8@ò‘ï»ä&?ysR”•€(.ŸÌu'óšG]êJ¹ù»s>ïÚuÜã?ÏwÐ]0ô€ÝèS%JÒ•"E§·êSg{Û}¬¡‹ËàêfÙùøÄõìy½ä<;s”bö¤ SO©¯Û øªÃ›KßxÖí~÷›†\äAß{Ìú„¿¯üì ÌáËuxлOT�{¿Ð’Ç3ÈC’¼ôp¾÷=óì}ím/ªÑOU»ç=|ÿÿûº§~õ™i½Dñ„Q•�ð·g~ó—’û§ò¾÷¿÷}ð?üyÇçfòÏ�tÍ;_üãÿ2ët/}P¿úŽO}°¯)‰_CÈO‰òÃO~ü;úìAúÕo}»{? ‰¿í›¿î«¿ïŠåË?¬½ý“ŠþS?:Àñ@è @Àá¾1¥M;Šl@= ¹¼ {ä )²ª\A4£´Ã¯ìC?üC@ DADB,DC”\I“˜É–, ˜äž<�š„Ç›lÀœÔÉ ôÉÑ�IžJÚ+Ê<Ê•, ¥tŒ’ J§ô ¨ŒJ�ÔI ÊÚ©ɲˆ ´É­=©TI°´ ±K(K¢<ËñCÉ Y˶i ·|Kž\ ­”Ëü£ËѰKÛ±J· J¾d9¿$?Àt Á,‘ÑÈKÃÔ‰¾LÌñ“˼̶̺ËÈ”€É¤ÌÐCÉËÄÌÀÌ½Ø ÈÜKÉDLÐDK�MËÌL»õS@MA�BBÕÏ0<Ô5ň6}S†xÔÚˆT™ÔQ©Ô‰¼TÈÔMÝÓNý�O…ÂP-Š1µBRMTS]TT]U= Vý Qs Xe*Yg}V¯Li�V¬ôÔhÔp¼Ò^­Â_5 E%FU‡À9�”‡JÀ$YÖ¥zVvm×h�Vi­V\½VPÍÖmU@3�Ânõ�o Wjr…TsÕ$tEuM€vMØ1xWx•×·ÈU& Õ˜X•ËWÿ(ÜW=ÕFX2)W9פT�TX’…V�„×xåÉËщwÕ"”F¯œØ¨ØB�BŒÍXpVØÚ  �]»tÙ’%ÙAÙÊ••€–�ØhŒYŠÛÍXÝ•qíXñY‚ ÙWÚ¡MØ¢EY¤õ–­ÇšeA¯t§�Y0LS¶eÛÚÀÙœ••j«6¬¥¦‚M /1NãìZ…ýÚ†UY±UZ²uÙ”Y™=[.IÛ-Ä“¶mÛ·ÅÙ©�[2©Û»[oIÖ @ɽå[ð[¯½ £ ÛY[~,[üC܉UÜý`\-tÜÇMÓÈ•Ú¡Ü±Ü ÀÜnÑ\ àÜþðÜÿÏ]v\jÜÒ%ÜÓ5Ü™KºƒÝç}ÞdúI‘D:A ¸B Ò”B†Ð¡0I&ýÉT”ÌGýQݰ´ñ) ’Šömß¼,©ÆH :Á«äE]tc^u}^è}¤Ó! §©Þº^+Ì^ ÙÞÄXŸÏùÞG _NõHòMóE_5Q_ûh_÷}_±ˆ_´˜ßŸª_åU7ü]VýuÞèíßÿ… ëÅÞ½ÑÞÕàÞ…ðÞßÔ_fÇòU] f  f_ Î`ÿÝ`È ß+á•kޮʰ9aHáÞ›p™ Έš€¸â˜€db<žÈþ�ÊaÁØa‹èáøa‹Ð`ÿêâ.ât aXá Pbˆab'®B ŠâטbŒ¨b,Îâ„e<§_N�0~¥-]1'CãŠPc¦Ž:8®T9¦c9±ãVa–Ñc×àcðc,ž€@Ö¸A®árÔŸC^§D®7cdpd6†d7¾ß#Îß$Ëþ¥ ùEáL~b xNn Oå+åvd.‰;o<8T®1 .m±ÉKX–"¾W‰[H.AÉ0èfo¶ä Ñe!nâ^ÆcåæH‘âbbäc&åd¾¸e6¸ôuf8zˆh~²é9ø â5¶æ6ÆfuÓæýàfoîfp qþç;¦BAgQç†Ð¡ÿ*�Q–7&¦“y¦�z¶ KÃgEf1]ágû¨æk¶X£ÆŒ$è´уFh\>�…à/`sþeªæÍæÚ “‹Î�Œ†Œ�îh‘è9�fe•’âØe€–e�±¤ÓŸ•¶Èýpé—. w‚p& §nè)|èœNç=^çÏ©h¹øiYqj:1_Ÿ88¢ £vÔ�–f¥ö82é€FéÿšêÔ©ê�¼jô|é0Ðjwêêøêrvèsëˆ.ë‰fçž¶èwÆèx~7·î ¸žàÚ™k8­k}¾k{Ëk~äH–-hŒÆŒôÊ?¾b¯ìgÇp›ÀiYšð‘Öw; …´ÿI¾Ó}DÉ}”ÆdÂ]ºàˆ˜’­ÀšÏÉËÉKœ˜Éd’ãax’�l��rj¿à‹�ø�%�žÔ^¸ÕÖÉÖ~2näÒKŒ˜ Ûfn‹ÈíØí/èí3ûmá¦ÇýîãH&K;î�Hî{YnrîÛ€î �îG"ì¹nÎÉîÍÈ7q]ˆîÞˆï�ðFì*ïã8ï•Lïõ~åö¦Ê÷~�øÎˆùÝ`ü63ýöÈà–qÿþïG p²@nåÖ æVq·|n·Œn—L&¿ § Ç ÿW¸ð Èp¹ØpÕéplTm‡díÖqÙ4q€ï}¾íÿ€çå/³ŸÈÿGó7‡#¿G¥>ðOð _ð!oð—~pZº¡$_rªµpðîŠï/ÙŸìòpãq•,)-/ñ:q×HqŒó1'ç2?²3gªôNïþ®ñ6‡¡7�óÈ1pöAðºPp¢"¯‹#˜?ßn†pr(� )Gt*ÿF+O¸×¶�Gg̵”ôÖ tÜfñúvqäÈïZ^ÖNoíO÷ïPŸQßñèñJ¯óT¿óUG V§‹WוXW%&§õB×ðC÷¯vÓ‰„Åñl‹_o »öÍ vK?v2Ov#cªßnv~§Ysã¨v×ñçq: ê\n�+)!oI2Âî¹ÿo?�ñ!lÄPnîf†oø[G÷žX‹uws;w÷Ú�mxö.Gñ/—oûÎô£ÈþÊ~oö –i„M9x‘Ï‚—sSÿœ"åñ…·�†?�‡/™ˆ÷¸W4‹�ŒŸu�7zŽ?wíJw yQy‹xw’ˆ÷”Ÿô•÷qpyd7Ž2“y¶ ùšOï›ÏyØäù­÷ù§vk‡€¡¯ö¢‹£Oú!Xz{kúiS“§÷�بð&Ÿz¾¯úÿðøùvewºpôÎö¸-�ô°ö±¿ö²7ö—Ç÷"Sûµ`û¶ÿã·�F�—{iÏñº/øj6ò\ù«ÙøU‡ø—–ø>—§éÿ‹/ðŒßxï€b‚„ÐÒµvŒw]�˜¢‹Û|}ôI(>é›IòeßVSË!K©Èîf7¼ç»sd֛ʰò±`-÷{#ÿþ²�=ð2ßúÌi6ÕšSÜfäâÂî­V¡Çý)`F8ûE4Þ•:yüÏk4ÃUW”g;î`yS\îí”øK«à¦�’¤›ÛF[v2t¨€Å3žŽü»s½LuK%~%M‰~‘^ ÿ·ç¥;áèe�Ú–ÔºàU?øÕ “u’GØÍ¿öºJ$vôŒ,eÕÙ��öÈy…í¤þ8ÚÆ2r¹?„îAôñÝr!5º%}gèßÉ7€À/dðJ¦¡á›n!Å3~ñ�‡<Ð%Ͼ&�º3–¿fK2�ï¤�óbñ¼@@ÏÑS€ôíé.~Õ/\ë­çú›ÁÈC‰Ýø¸ÔíYIîíÞ™lR†´´]šÈÁ�ÿ_ßÊYWÊ Ä¶1_· œJ<Ÿ/EßDM_y ’€ù!Ï­G÷yß÷q@äQ^œ_pÀ„ú©Z¾¹_VÀŸ ÈýÙÕÅ–Õ%Öõë5œë=ÿBIœ…ðÇÁÑÞvEk$`|, ELÍ}܇ï�˜†ÜðYàÜeˆê€Çµ DfG£Iœ¿H! ’VœÅY¨ V€ fZ(Ì *@ Ê`øÑàäiÎà pèàfi�üY;áÆç…À¡­!ê!!ÿíÚG8œA!tH¡ŠE‘]᪘Úmá¯t¡}C D�tGjŒ‡ €v‡üÉŸve€~Á–:Bd&iÔ] 2ýáã1D‰]š Œ�ŠùD[¥[¾¥\E„š]uÆuˆÄ„Õ„¶D4�€”åBàÀR6å�XGVÆk-&H|0Ä\.Yw@EGÄOŒäÒLÂGMšÅMÊ"ìdOnÿÖ[�P¾QâF�åâ%eafÝSâFTRÚéXåUò@Vnå[t¥ïä”]ˆåEõY:žYæcZ‚ë][’ÄhŽf\ž^dŠ]BG^†Ä^Ö„Lüeñ&qfk*¡@\Gbc²–cÂdN�M&eZ¦q`æóÐ$tØäx��a h€O¾eiÁiŽFjª&k¢[¶¦kdTÚÅ’LeUâÆmâ¦véæðæWŽj'³çp'�’‡Z–œu,ç4'\J�\ª']Àtâ¥uèå¯ñevf€æf‡2åê…'bj—b–çyÖAzÚ¨dâe~€{¾\ eflÿ¦tæ?âgpöOê§~U騖f©Âåg¨¦ h´±“�¾æhÄ&Íõ¦‡á@…„Rè:ùæ`h� 'ph˜'ŸøŸröD[ Gü) >'%FgÚ¨([Qg‹Zç‹bgLhçpg�zç�hu„(Pô(cþh�x´†»°˜À'ÈggÐ'�ÙgWèd”N©•Vi–jé®p©_4P!¥Y(夺&‚¦‚zÈTЇš ›nWv"1¾i¡†¥l ­�ž% y(r®%Ÿ’„ŸêŸ ꦦèŠFŒ‹òe_²„£B*d~§§ZêO`êbjê`¢è’uêa ¨Š*©rÿ†©Ž�ªf¨”†f«^髪À–¢f†4ëتàj˜âhÿ‘©F˜é`Íæx« ëkgÜ!]è²F)Á>«q~hìé ô©p`k¶š(tº«t*‹ŽÁ·Âh£Ê¨Ш�^šÂžë…ºšg€oá>êô–+ãlP@“ˆ0÷"/Ðò›Ðêhøª0£ ¿ ÒÒ‡ÒrE �Ø ·ïûNmüê~©êޱ@Äa}fÅÔÀnê}ˆô¯°þ¯Pð  ÓîþÞ7P£å‹è*ʪÿ-Ëzëà®°_Ê,Íz°—14�jGð÷m Õ)×È[I×ÀðçÊ0èÒp�Iéî@×jê¬õò©"ò¯(²%2²#O,$[¬çÓWTòˆ]²³Êm›Ê&Wq'Ÿìœèoñ(îËÆñKlp*2ø²²¹2 w ¯ä’ÎβÔrJ!ù_, Ýÿ¿H° Á/L\Ȱ¡Ã‡#Jœ¸0!Š3jÜȱ£Ç� CŠI2ãÅ’(S’<©²¥Ë—0cÊœI“ Ëš8_ÞÌɳ§ÏŸ@ƒVJ”ã΢H“*]ÊÔfÓ§�B�JµªU£W›JÍʵ«×©[¿ö +¶¬Ù³3-¢å©v­Û·pãÊ�K·®Ý»xóêÝëR…¿'wAA˜p—ÈOYl£±ã"GvA™‹åË—ŸÙ¼y†çψMº´éÓ ¨^]ØpâÃ1bˆ@›�í¸sãØÍ[²ä$Àƒkî£x„ãÈe˾Á¼¹ïç¼iK‡ {‹uå1lÐ&À�Àp -ÂcÿnÒD3g :Ò�Xÿ:1�÷Øc÷Ñ;røTòë?ßÙs†ÿíxØbS8vÁ�ß}g‘EO4è  FˆÀ„Ê`á…íµFX|ŽÙÆÀs$HÜ|Åå`â‰:¦¢ŠB´˜[0ÆøœJÔh@< ãŽ ôèãi@ ¤_€¦! vAàŠ6@æe.`&¥yœ}š�X¢¶k­Ÿtæ–›ˆ€œp#ú€\rØ5爑E7u±Y·vÚAÐ�wÃÝ7^yü¥§Ãz#$ùñÍWŸ÷é·Ÿý—A’í-ÙØ��¹`B>!„Vx¡…j˜¢ ‚H&‰%žhâ©L:ÿÖ¢/ÆãŒ5*q#;òèc�Y{‘v’] h©ŠNJ¥”˜QÙŸ•¡ lj[:Ð%’¯}YÛmb@¦™g&ñÝ|kŸ›ÌÁçnsÒƒ�xn×Ýw~^Fž´è©Çž€‡&ZÜ¢�:JŽ‘HibËbªé¦�6ø)¨¡"0*©¯yjª3ŠÈª®¾Šg¬,ºˆ›­·JVf®»ž×«Ž¿kíÌÄ‹laI.ûØsÏBk¿VzVíÌBb»å¶íy A˜áŽû\¹æ¦™n°6æ®rNWÝuÊå¹'¾âé èy‚z$bc§èn’ì(Âþ)¼ð€Œ]Š ˆ›21¿@TÿlñÅ¥¶¶±mªzÌjÈ9T묵ÚêÛÊ6&„#Ž1/@´µ5y3·êÜX³“Uæ3@=ôåZf‹³k‰)Í´˜Nûf0ç—®âWg-ÝÖwvm/w`·ð'¿e¯wöai+·6m‡7;Ü3H:·buÛà0ÞGŒ£ß tï}à… þásá`Âùè#®8“ŒŸŒ²Ê‘±œyô7Ay̨›ù±›ç\ýÎO�ÏJG­üÉh\ºYÒ°&pÁND š]íÔt»‘©(wðšïꥧ{õ)l–ÙW ü5‚ãu!y²Y^óðc0èI¯T•ªÞõ”·½m¯bÞû^ÆLeAŽù¦|èK_ÈÿÖ·¢ö e€ŸäÇ„ú‘ç~¿2 –ö·:ÎŰ@+�z6@H™NЦÉ!—Ã:´Á'6ñ*_ì$3»�MMqo‚SÖâÃÁ¯}Pxb# MhFDÅæc r›Y¥ Ià�ˆÁ™€˜TƒF>Œ ™iŽ$4¡vC‡9RøbÃ$LIˆA4�ú,H2”‰‘)Sü"×D'BïG`Ò_Š¥9*ëŸã™¡EÀ+År4bT�aéž3Æ �MƒàsÚȪ©ÙÉNLŠ#ˆæHGÙx̓à!DH¶=j¨=ÉäsIÈi}æ�Hd_ÃHGb’?“$(‰K&“dÔ¤5WäÿÉÈ€2”¡T™Nù¾I†‰N´ŸgË_–†Š«ó™¥Ë(�®—Bs¨h‚©­o¾&yÈ|`‚"h07¦ë™Ö‰f»ÜEÍjfçw|Ê&C86ί„-¦åê@:/?ƒtB!­„Îé¦�5xd$ùFO{âS“â$?ôÉp A§ÊUêj~®\hC5*ˆS¢Ó"ƒT~uà­p=],9º9+"Ϙñ* 7ÅL9¥*½q°;—¾´ƒÀ»ãðF8(ãå´�)ìé8J… õœˆ4*R•O¦R¬ž–|*T÷©¢~ZàŸWM-™.Tvu‰¬Lè+eFÖ²ÿÎÒfɺåÒZÑ˰u�n…ë[å Fº>ö®;ÍkÇöº ¾Î'Ð�.J·ØÁÖ¥×L¬LÛÍÆâ4·�ý£d}CN¡šÓ3EÕlÝÉÜ¥Nò³NÅX>5&ÕÒRÕŸVM­~W«ÕpyÈCÃñ BÃzžÏŒ•¬f]çkÄÛZ” ¿uBp…K\)rt¾v=!^ç¤Wñµ¤¬Š®t»"iB'ƒòªfvcš/šêÑ»|DndIäSV¶œ@Ú Ò;½Í¾Ó½ó„ohå U�Ö@÷=m~õ{Uþ&¨|ÿµÍkaûÕVÖo¶–s¨¶Ìecknñé�˜‹@æ\劗Óñ�Éê#/¸9ÿÆ]˜®r'"hÑoGˆ;”ž÷¯=qçj 4“”Ö¨=�? H´¢á,gOö>-Ø›Ž½,˜¶¦Ï~†”ddPÈ4èD'¥O …R›:^Ž!süL€«©L™®F‚¬g‚ZÛúc³³!¯tT[p¹Ë”3vÄÜU›¹FhiÛë6¿ù¸qFéœ_� ;“Ï!Û³¶y€é=ZÐ+"4w ÝBD+:ÑŒ–¶£É éH§9h£aºÝMS†Óç¡'¨C-�Q›úÔsJ5™YíêTÂúj³¦µ­k�kƒéÚe¼®í¯·ï……yÌe>v²´ì,÷ÎöBºŸ9mƒW[JwÿÖQž·­gzÿÙ]�nÀ ø;r¿ÍÜç¹�JΨvKÞÁ¶ta\N{»ßœÑwiøÝoJÿ»Ô¨nŒª ^ð5º+á²^8ÃY•kííú½ž¸*N©‹;ãfÞxƒ:þqÑ„\çÖá9™¬Ýl»Šå-ŸÕáó™+G:….סÏsntC»ÑÓ©ñ}~n%²«óÒzÏ´½‘¾¥“†éþ~zÔm0u?7{ŸQ}Ö'tó6'Ú'fÜG`I÷Y¦!~ãçtšpR7pž—~#Upìç~¬^q`G@>Hze 0‚=@(„H˜„m73!gNø„1Â0…TH„Rp…X(v/óÕw"¬öOÒ�80†ds’�DTH…ñòtZÀt?ð†px�¤Çjå!ÒA†døz¸‡³4KÂõVH}ª¦j`HD(bÐeO¦á7£W*ÿ~£6ˆdF&’¸j1èƒ8X°‰œ(žø‰�8¤çƒ¤H•³„YÂe¤„!„Dh„ë‘„JˆŠÁÒ„Oè„Q¸i8…Vˆ…W¨…/Ó…&ò…K†!ƒ‡ch†‘�†»¸†Oç†pø†r¨utJvHÈX{ȇ}HØ¡X‰…‡ˆˆŠXŒX�È;ÐŽîȆñR‰{'™2œØ‰Ÿè‰¡8Š¥hŠøC‹A¢Š?¨uAe¯‹²ˆ„™%¶x‹¹x»x½è‹ÀØ+˜Ä(&ècŒ®’�Êh̘†ÎøoÐ�Ó¸pÕD×Ù¸�zØ�Þø‡á(‰ãXŽ"vޤÿ‘ޤ±ŽîøŽ-8òx‰ôx8öx�X��úˆüXЧ¸�òe«H�­h�#‹#��à”BÒ�P#R¸‹™…·…™‘¹±‘´!†Èø‘!©†s†% ‡V9‡~V‡¶q‡Èè’/“ß8“ƒX“#ˆˆ)€“£¡“à÷ˆ=ÙŽð8'A¹'S�®b”G‰”û¨uýè�Q¤••¹pù_i„X©™@•¸è•º–#è‹¿8–ÁH}^èg㨖xÈ–(‘#ijqù†sI�ui�w‰�yé’|)“�(ŽÅhˆ�iŽ–´ˆ“‚ˆ™˜‹ ”’/�I”‘i”H)¡¨c—Ù”¤YVœÿI¬Ø®X•™�ái¦ii–­ùkd ›Ã(›É ´Y†�v†·ÙŒoùŒü�¼ ‹t¹'vÉx‰‡zYœÂå—„˜Ÿ6]„)†)<)�?)•h�×9š¨�”ˆÞÙ�ài-p59›‘P,úDüñ‰„²€Ûöxˆq!ÿñk—S9:¶7³3;:&(X¨—ÚæR¦ÅF—ƒ‚BJº¤ q–çƒ)¤7R:¥£65Ls¹Q‰ìrCzG¢mK¦b*1'(S‰‰¹œAŠ_º€EVrªc*Z`AS§œ!™‚©—Ss~ú§VY9•ó�ßx¡¨“¢*J?tG?8ÿ£Ž%€”BL6š8J4:4<Ú£Žò£é¤.¹@tT¤‘Ñu�bS鱤LºNjPªuSJ¥”f¥+‚¥îã8ÏÑ¥Zצz&¦ceZP¾‘¦kêƒp67G§sz§xšcÊŠ§zŠˆ|š.ú§£¹žB‚¨“£¨(g‚›á¨ßELÆÊ:“Z©L3;1šº©A¤W¨!/ªñ!ª@ªbª:€ªJÚ¤¸�>­ºp¯*¥Uš.Wh�##·Ê*^z\<À«aJ¦�f¦¶¬‰9¬$P¬ s¬"§A@§ËʱÎj”{ê’}:­WP­Ö $ØŠ#Úú'Wö¢žh6Ж$’j!7Êe9ÿj®˜1NöœªXè®ðŠòJ¯òÔ/÷Нúj>Oz Qú¯Ù(«*B«G¬CI" +€ ˰Ûk°Û“k±‘ª!Ⱥ±ÍZ§[§ß(vziObg²'k)Ë+;:\Ш/û¨àz±âJ³”j³–гV²7;;�t¸5À®R´òjtÐb¯øJóOýjkÿ:O+°³J°µêµWCzññQô¿±’Q‰a³|Ûe‹•ËʬV»k;qXé¶¶«žq{pÕ+tKvë[–Þ*¶�S£~K®Ör©ƒ«³…‹¸�¤¸Œ{1ð¸ö¹›‘¤øZ¹Kv¹µ–¹›ÿ»&Û›2®&ºØAºà,×+%8âŽKʽ œÿ¾ÈµŽ±U ë.Íak£ë¥+]k¾©+‰8"¿®õ;*Xé7Ðó´û‡,‹¸Û¿,À¦AÀœaÀ>ƒÀÄ«ÀÆkiíñÀ`±;¨oõ%ÐÅ^\¸½5€Áé¡Á®§6ÅáÁš†½ç!ÂJJ«Š>BˆÂx¨Â�ÁÂ6ìÂÌÃé+ÃëKÃîkð{:lT‰�±>œ�~ÿüö�¤Á¿\æ¿9Tij¨ÄXœ¨À¼wë²"³�ÚÀfÅ—Œ§ZÜ\ìÅ] ÆbLÆ:`Æ^‚Æ:k ÂüáÆ”Ë*¨u>sì´)̹*‚ÇITp/\k1Œ635̾1È«»Ã­ §óÃÃÈžq¢¢É[&ÉÞCÉ iÉ£¬²™¼xÛÉzËÀ²·]`Å[˜Å13Áž�Ê©lÁˆËÊ®´<Ë[ôÁ˜Âí8¸¼dretL†S‘ÀüyÃÅŒ<ÇÉ "Ì¿ÄjÎô ͉,‹‹ìÈ£à͠ÍÝÃÍYéÍ¥Q§NÌÆœQ¼ó{¼¯¡Î/»8âÎ3Ï%ÿ Ê|…‚¢—¦Õ�.×2Ù­Ý8ÀÝAãÝàm \ãÍ-�Þ“Úë�˜­í̇¬!±ífò�#ô}nö=ˆømú�üÍátÜŽ1ÜuVÜ¿uÜZ§Bž ^ä .¾¯¡ák2á®RáÚ�áV¢áQÞ ˆâ)!â�Bâ«mâíýÌ„±â³­¿óý2${1®j3Î5~ã^vEËÂã''à?NàA>0Ê=äPä ~äI®´Ô='ÖMiØÍ.ÿ~á’ØÝ:òÝUŽãr$Y®å/á7„ú‡•“¦°éœ^‰yäLBæ:Ä_·#i¾ædÖæoîÛ”‘¹ã¶³&0™éx¾pBÎçÙ7‚4�à€Ž_Ó�–ÓQè^vèn’è•è7T>j:œÎé“Né-aé—W´Þ“;鞾‹ ¾"¢n:ãâhN²ˆƒª©nÂù­ßpn,®¾‹°NA²Þ�ÕçCžëÚ·ëÎÝëJöëçÃjˆ{N¾¥Íaì’ˆì�¾á^¶ìÅqíðìОÒ>í ¨=⎠Ÿíi¸í*¢m’")~C ?°…§2ä^ ZãˆÃØë>…óáS3ë1C!îÿø‰·¦çÌsàn9DHÓâ¤à¹lþ~¸ÇqD_ô'"ð�½p²-Ûß+’©ð>Àðÿð%ñÓNñ `ñ׎ñT¨ñŽÁñŸO "/î$¿¤å®’4Žò®¢ò+ßò�ñòðó2óžXóÉ}óË�óÒ±óðÜó þóAßHC_ôDôÌA„¤·ônÖô;òô /õ°HÞT¯VéX¯õÍÎõSèõ�ö?öÑXöÓŠê&oÂlßöлòT÷6 ÷}X92ߎ4¿uy¿ïáÂ÷Êyï?^�ÐNèébø‡2НuŒïޝ#�¿ì’o„”_ù(qù„šùíxñ’øé ê{ÿöb_1 φiŽ)˜R‰'Ÿú&âöëîú°?K²_÷´÷¶oà{?…öNl<ïûÎM&ŒPÐà„ s,dØÃáÃ%z¡XÁEŒ4nÄÒÑ£�!E‚4PÒ¤”)|aÙÒåK˜1eΤYÓæMœ9qbÄØÁçO > %JtÇQ“&‹,ezÀéS!Q¥Ú Z•ÇU¬´nåyñÇW°ZÄŽ½RÖì´i™25ÑÖ-¸ åÎeXÃîݧyõ†¬jÐ À�‹Åxt‡ÄCâ`laÀcÈ�Ÿøða Ì™GúX»ÔÂgС?k ]:mZÊýL¨p®e‡'V¤ØÁÿFŽ;nÞœ´dJ•:…'^Üøñ/¶ƒ.ï0¸¨aß:Ñ{@êÔªT±fݪÕ6ذcÅš={úÂt·oãÒeŸã.Þê{Aö]XðàÂG‹P ’1Ç"ƒl²Ô`ë!3ÍFšN4-(Í4óRƒ`µZCˆ.e‹ˆ¶ÚºÂM#ÝvãM¤è€Ci%äRTqE[d‰ ã`F#jdª´ rи¨ ƒÄj¦Š4’Béê±ÇêÜÒP6 �xò=»Òk«Ç�²£ÊȺLàK0SL`4l‡!†¨±Fÿûï)‰ �sN+ê´s<óŒîÉEZsÍè¢ÔaPB�0ôÐ3�ÿ”ÐAmsL#eáPD ‹xtSN;õôSPCuTRK5õTSÍþPLHSã–æ¸¦=æi=Šå´d¹Õøêz’Ñ ×‚pÁý$D"HààçÚ"ÿ¡ªŒ@„¥+]ÙR7²Õ…fmOz]ûð>øµ«]ûÙO¦˜ó»G9jSö»—5<QˆF#`«–×<È-izÌý"A+M¬‚»`2ˆ� vÐ{V!UD8>‹|fYµXç&²¯}Î�íd˜("Ɔ7ü ïºÂ)¢Ê‡câýøÇ|Q`Ìcšóœ¶$¸,1HŠ… ˜)æÅ‚DŒ#ÂA$xÐ]´ÁÃhºO¡nZ(<ßÿ“Æm¹��m|ã™â(‚9Ò±vä q˜¯=Š©�€äe/C%È#2‰=bdЉH<Ò-ÀÚÌ$­XI,^R‹¡ñ'=FÿŽÒŒ*¼*ç¤ÊÁ´Q­4Ì+cIGZbÄ–úÞ7µK_ÆSž¦ ‰@C*™Å<&"•ÙfŽÄ™W”’43)dZs„Øã ÿ´™ª=É9à,Š8É©Ÿ8žó†é¼È:ëØÎZ¾Óó$i<ëÙ¸Ç=‘ü| Â�ùÏ_ ¨™T¤¤,L2(¡© áBI˜Í³‘¢ “è`(J‹^Ôœ’¥O8Š�:¤êiQJzÕx"Õ�ŠBHfðUE’@¢LÌzÖ à«keëZ‰ðV¸>©ŠcúI9ó*ÕàA¤�+\?ðWÀ–�TËç+éò$$V±XelcD­Ž“ÿ«Gð*XE¬X¥42ò•MÚúYôõ­r½ ]}bWà•J{Õ€h‰ØÀŠñ^…�ãa5¤ØÅ>V·»åíÐ"k˜„T–aPføÎZɳ e«kIÓvµª}k] Û¿ v¶m4ì\‹[ôV¼ã%ï¨~;Yá72ÆÍ'°¨Üš0·¹¢}nt§ë�¼ZW´Øý€vQE[ò,�å%p�É{Þ3kU/dØë^ ç³tq­mæ*¦ºb4µø¥R”\k"ø÷TÞ�€oi`§X·Vp |Ùâ‘‘p[),Z —çÕ0uïâaÑ‚XĦ"1bLÌN'YÉ%ÿuN»„™?æÁ3~L�Ùzã¾æËye^�ÜWó«È"8òG—|f4ÿ±É‰zr ÄÚ)SÙÊkÅ2\µÌå8ÚìËp 3ÑlSf©¦YЃ>ÞšÏÔæ7ï5Î3žóWëüÖ;å•z¶Ð‡MT´?ÇkÀ„æt§ûehôÙ<€³Œ©<˜®­=rÉT¤�2étE)S}Z¦%µiOçZ×¥õQDmžRgöÔ¨¶kU½ê…´Ú��Â3 )ÝšY_ÚÏ]ô,w}ml“ª×;øõi‚­ÙûÊØ×Bv²?äêŸÀšQ²þ­…fëHá:Ûó¦÷¦"5/V±j3¬MôƒÖ–×»ÑÅf xÿÁQµJøÍKÞõfxÃÿxïuå{FûÞk¿Kóo*|.6+š8µìp�‡œ—§”Ä9@ñYœ4�ÆåÂq¢y|Ù"§y̓HòC™å¥Q¹X~—»-Ó3·yÑ�~8œJç#ÉBÓ�Π(™<¯µöñ>~t¬g}_IÂÒEâô§‹&êŸ:SOL¼«k]ík7ռ䶰7ÝäcÏwÙq#ôi‡”í{çû¨l#7¹Å= s·�ÉÛEu¦½ï‹çûßÿ-Á¾5†Oâÿ§xÆg^ëŽ<ž"/qº³êðfG²ñ0¯yÔ�ó�ÿ|¾C?£Ñßýìˆ;}êmòÕ?¾õ¬z=bÿ¿¼×šè·'>ß ÛÆÎw>øÅg~ó�'ÎäãÉùÓ§>I¡ýêg_ûÛç~÷½ÿ}ð‡_üã'ùÍ~ô§_ýëgûÝÿ~øÇ_þó§ýíüç_ÿûçÿýÿ @@,@<@L@\@l@|@Œ@ œ@ ¬@ ¼@ Ì@ Ü@ì@ü@ AA,AƒDH}ìÇ…lÈÿìHi‹È‚ÄǪ±HÄȪÐHààÈí3È�TÈ…ˆ4ÉæCI…ÉbÉ�tÉéƒI[‘Éèa–´ÀHŠt€”°IçÃÉ ÑÉ ·èɆüÉ Jæ#J 1J¤l ¥H¦D §|J�ŒIìB¦©4�ªd–«€n,K³ÅâÖ»x¤´øÖ�×q¥ª{‰ÄöYV-@× PWƒˆÖÕð‡}X_ Œ?0ùÉÿ¸XŒ¥WJ½×éËW Y~E‹»á/±€í(|�C 1X„UØ‚`X¿xXˆME‰ÕVký‹ÅØ‹ÕX;åXçóØÖY(ê×r!Y“ ŠUå•] –EW—�˜5™u؈Œ_¿Š¥H�ÝÙx¬WŸm> M¡• ¢ý£5‘“…ª”E Ó�•=W§uÙ¨-ˆ©õ€ª¥€«¥XœÕÚ­åY*5Èñ [„ÛÁÙ¢å�£Š¤Ý””hÛ·�–•[vmØ©½Û¼ ¿¬EÈ­M¿�RÀ?Á=•KÃ5[ÄE[¤EÖQi\Ó|ܱˆ\…�Û¨[˵٢ëCÚÔk­ˆU+&+ÕGÿû€ï«¢#•¦h¯°a€ h�‡E_ü]ŠÌÖø¤M5NªŠQCБ(¦‚ÐY­ˆ�£ÃÝöÑ]^åÝöðÝxÞÀ^ï#Þ41Þ¥@^õX^öh^‡yÞô�Þ1UÃOªžH.H¶SãÞð^�×ÛÄñíÒÝ¥ˆÞm)[�ÞàÞ *Þˆ8Þ™_æuXçMEèEHéí_ˆ� ^&¦26`ð5:ñ�òýTóeô%Gõ öí>÷ø-ù½åÝ`è`Tüà} á0òߨž±ÆØïE`›ka0ÙTPt¡¦ ö‹¦€æ¾Þá>ú¥ ûÕ•§Ý\¯uCÿö ëM�´Zb§±Ra(®9)þ*v+vàó…à ¡�-îâíûâ Žß öá1ž‹2>—Eã�Uã#aËH☂c`ñ•9vâþQ¹;N€ÍÅÍ-·Èbƒd   6 &e¹8ã­­W0ÃÒ1‹«é˜²d÷ò•³úãÖäØéä�ëCQÞÚcÖYºÎêp¢Sv€ nß ~ßBæáCcXŽåFžeJ­e1¼å²Èe¸Øe^¾æ¶øåF æ‹}bN¾Ü†3f‡ åxÞÚežÍf¦žÕ@eiVejfeCveDÎf†�e�¥åvžÞ.ÁeIÖå*gs6t¶uNÿvN€ð5_LfŒÕè‹­çÑ¬Ž³:+@†æõMåUnå8h�΂ÆXƒN[Nèp^èqnhIœÎi�ÆéK¶’ˆî^a®c†3Èi=ŽN�£öèÉé�n€‘Žfê3HBögkhl^閾ؗŽéPh6v†V&`Ùi²N‚žN�ŸžèŠ9¢žÖ£Nê¹`f½hj§Îg’¶áì“êiÖájc¸HdXÎêØêo–é+çd²éÈ(ë�>k·Hk:þ’]±ÅÓKeº¨šÌŽž�ø,`‘�ª¹Q/2Hƒ¼ÑHíCkkT¬šàœ1bÒ Ù ‘¤ ùÉ(Èmݦ‹59ÐÿSû,¹Y´õÐfuÞÔÉ6‘ʎǪÁì¹Ðìçæl�ðlm…í E±Ò6mû@í9UmamNtíÙ„íD’íÔØ _a–Û¦HÝÞí¹èm ýí¶zá âfº0ŒEn]£ìµÒæÖ’Ͷ•¯šÎn«ÏN�ÐÑÑî­íænÀðn(oàïM$ïÑ4o`–Ù‰õÖ’öFÈ÷ÎmÞ®ߦ²Ï²ïrnS{Œâh NÿÎ5ŸG–ÊŽ’·•g+±rŠª1Øç­ ƒ½ÑÍÝÜ>4H£|m‹íì d˜2„-ñ(8q#Hñ[q ¹›ÍÈïýžñ÷´?Çÿ¯Šïñ ùñµ òòe-òÝ:rÀHò]ò­%É”pr•´(w¯°FÔ4µrtÅr-çrórÙó‘ó¹àï‹-óN;ssLsªXóèžœ�� Ëú Ê 9„”ì³s ÀóyÔs�ås”ðsØ‚n¹X tBÿ§ëpˆ+/ñDŸo¯ï//—Íp“B¦…�ôÀÕð´Ò1 Át ‹êè†XÈðôá�PŠQ‹R·èÞjÊGq¡º5X auŒõÅŸ„uÀ’u† õ^¾õ4ÍõØõ÷fˆ�ÀÏZ‡ F—G bÏ'cgéWvfïs_ h¿Ž¨˜öâ¶vl�ÿmr…1Øo¯”Pò­-÷e=wtOöTüIf1Jº€wÇ–÷G¢w„�| }� jçÏFö‘x˜G¤c/xNüŠƒ_�„_×&’-ax!pxý^k§nÍÑ‹n :Ÿ§ŒÏó�ŸÚŸGvVWwŠù?’@7”ÿ'CoV–_ˆ|ÿÎ(�ñ…`ñ‡zô´'øãîÒž¯ú—õc†z†7új_H¥ÇQ¯ø9ÏîÝŠúUŸz™¥û‰Ös¬GH­�u…ézûz°‡�•÷�–÷�—‡Œ˜_P ±™0oû·GvJ´ÒAüb N¢×ûö¨š¾Ÿø k"|Ý"üsÜ\Ž�G÷ÅßÇÿƬ̀üx—|( ûXû({ö<û£ç|Ùð|¶6Í_~�{ðøÚÞ*ýŽWx»/ÔÏ{½Øüoý`™ë¦Žýæ-Ú7GÛ§úì÷‹�yTy-á¯ß/ïSþG"~X5~äˆ,X� †hèPĈ>&R¬`ñ¢Á„ Fè˜âã��"�, à$Ê”*W²léò%L—+fÒ¤`󦑜:7*¤H±Р‡-Jðž 0íáôi R¥š¨j!Z;r� á+ØbÇ (kölÙ±jײ-i2¦Jš5oÚü`÷®Rz÷òí»7àÀZCðëá0b¥>'ÿbÅjôñ«V§R®l¹æÌBéìYh"¢ khú€äªAƒzölå5ì²g‹®M$*e¢Bv/ôûâw†àà/nüx\¹+èÚÔ¹“çb�§?Fª4ÓO¡VNmëà®Á†]‹ö¼¶ê׺%‰\ùræwñòôk¿o`Á¤ýfÏ®xñEQ7”w–XYfšmBk��¦@m¤A@”w«Õ °Å6›l¶‰†ÛTºñ¦�oÀ ‡Š)ªx|ÌQà\Nÿù4 �Y§TvÛ9"U©�·•xä}Åzh­wdíðžr.ÎgW^÷I™`ò×_2V`5Tà�a&ˆÿÙ‚ 6ø`„¤Q˜š…E`¨ákvè!�ˆ(Do}ýöBp ·" �¾Ô"s0¡”w^Òx#O9êX§w?B žWBY¤YH®§$“r9ùd”|%J`jVö…e–<á°*«\v©(˜a8f ebˆæhj’*Y›oÂ)çÞVÙ�yòµgŸ º,³ð)e¨w£*:£9º¤>"^�–š‡ÖGáŠîž{¶Õ^§4)õäˆF+Ùš’™ÊªJ±Ú*—ÓÆ:U™øû/­e‚00Á¸A Çk•R* ¬°uK¢ž&úÉ,Æ‚:Ë´ïZ5-uÕ.t-«ÙJ&)W{‚•é·g�ûÿr åþv®[éδ.¨= �+éL„λ‰KûåÚŽët’]ôP¨¿>é™ó´ù¿"È?¿çŸ‡.zû¦óäÿYêíÍÆúm\—¯�(%âÓír§Àìí®3isNâ€W�¤àˆ)_¸ ¿pþ0ˆò«ŸÓŒ85ƒX…‡ûëŒKÂDÛHŒ€`3`ÅHE+.>Xt ÎøÈ¶ôy1Œb¤­eÆ3¦‘ÿqkäJßÂ8J�ŽÁ)ÉÏhÊ™n…©Tå÷’8Ò��çã"½¨È�ÀˆŽ„$Á$9ººo#ü³‰êhÓÄŠ ›(ÉFJÜ sY\2MÐÅVº2 cŒÛ,3XKHˆR¹Ôåžâ(Çr•°z¿$I03ØÎbº+ž}¤dø9>È)¤†ø P4s8M†0RiŽ6Aç!Ñ`£ ù&Â9'N:‘ æ<`²Ö™1%U¡¦6ÕQƒ�ÄMŽVÑ‘•THŠSC  F%Êi2˜½PŠR¨’’”P…Ä8 ªVUÒ²ªU/pµ«ÑÑ)¬’PËÒ2HMjé,¹‘°µ­nÿekt¢ã*ï”.�ÙéjW; ×½" ¯~ÕªV± ØÁÒ꬧I+æŠYLøøÕ¯3xì`åÊ%ºbn/S=LŸúÔØ¾ÊP4µiMq Vžͧ‹ª„ª#¢jŨH0¬i–ª—¦Šç©Pµ�T/kÕ«¶°YÅ+W¿ªS±“¬^4ëP’zÄêo­o}n\4ÙÔÔu¢ý®öÊ×Íúvƒ%ì˜`+¥(¶pŒÝìcgY鈲 °ìe3œÍ" ³+ú,hE;ܵõtL?ªj·ÃZ¸V¼�­ hÛÛÞöTXº¬v[U¬ú»Âm qïhÜ"× Êe®Rž Ýèn©½Ô­¬ÿuï \íꕾÝý®` ›Ü¤’·¼çmlz×듹žø½z�°|3@_ûªHI/Ó/†ù[ZÿžÀ¢{ NŠzÔŸÁ æ ƒlW¦@X 0`µÄ˜ýš`¬•)kKa—T¿„XÄn%q‰/âÞ-»,} c,ÈØÃ4æIy'pcÇBV°’5±dªk ËwÈDF‘‘Ç…d¬�ö^¦õ jI åœHùµTŽ­V˜zådYË3|°n% f­ŠÙ£­Š™)ƒfrD¹læ‰›ß gð8Ñ(>õuWÌâ<vÏ}®õŸ7èA÷5džf¯œ{ ß©ÙÑ�>N¤Å5é�®-:—¦H¦ŸÿÜ;çtÚÀVu©µœÛ©zyÕYmõ«Ë\\©P¤qo“Š�oíÜ\—`×¼ž®¯} lãõÎÄ,Œ�MåÖX±ÌF€³±pèh|Úˆ©öf¯�œ’ÜäÈ:Š·Ç¼ÍdŸd¡ä&·Œ¦Ç­×øÓñ˨I�¥½¼ ¬WêO—UÝ[ß¶:¡ �޽‘‚o—@ß á7\wÝk«ÜüN·ó°¹«ç„‡—è _¬rè›ÞôNÜ"Þ1L|�q�‡ã6yYÒ®öµ§} n»„¢ã‚¹Ó� v¿»ÉMN¾ë(ÄP,7ª„¨¿´É2_ûš©ù¢Ü ¯Žü"/y¥°½ò]xûÛßvoÿzO$è�ŠRï’¶ ô¦oêS„Õ³NV`×b/û¦;½žI¸ûÝYÏz`‰D$­<‚/|¥�Þô¥O}ê·þØ0¿ù¿g»_4�ÛãÞîº_=°Èž³Sí–_;æÝ.¡ÉѽîÕÏ{É÷Îw¿ÿ=ðT"¼… x!$~/‹?³yÉGžòßW{øM�ô}þqXe„ÞûõEñò¡Þõ�ëÁžìÅíÝõUßò^ïýÀó­�ð O,àé5 òÍ@ó9_ U^ôIßâ^ʉö¡÷yßÿ]^ø�ßДßÜU _¨ßu°˹_~À×TÆüÑ_ýÙÀýÉÿZþé ð_ÿñD ¶]ø ã©�e `* èßñ5àFà“L :X8�Ö¾ ‡l ¦ Û}`ðß‚a6A ž óu Ú­ æµ`î]_öÅ Ìà¸T¡ bÞ‹ºú *Åžýa`¡QF6X5áTF¡ú_  àúl!OˆžJ ¶@Ž!œHàV  Z!Ê úaÚÑ!Ø!,â! *Ž€/v ¾M.R�Ά!"It\"Va6"«fdJæ—^æZô‰€²�àh „‘[^eš’æšJa›¢Å›²æ‚T…Zh�Îæ�.œ†ê)aRŸbÔŸê ꎦ(¸UF³rA;:j@ªzÊ褮ÿ¨¥b*Žê¨§f§pò*�’êwšjx:A¦®žª²ª«R“º�¬¶g`Ú*ÿÅgX^©bÚ§¯ni~ë+€+FŽéÚ%«™.+µë³.¨äMëYT+ÿ• ¶V(�Ö€�¾ÊMn¨Vˆknúénjoލ ”hlÁ‰ªëDXF»¾«r>*sFªsÖ+�Jç¥R§îmª¾~*vúk�jÀ�¾%ÁŽç‘–g’ž'ÈZ!îç“:ì{F,®N¬®úk–^lq©Æ^dž©X€…fZmÚ‰,aØžÉN¤î±i{¸)‹Á©Ct lÆ…n“Ÿå©HHF�χêlˆÖÓ¹2Å^íÚ™áP«ÿm³¶#¥–-½Rê½J­¦ZgXî(�î+Ö¬� ,‘v­‘Î’ €’fäÂÆªÙÎj4¥­äIl¾nÚ¹­–F©~îçê�ig�Þæ­ñv߆ß6k^_w©¬YÜ|&Û*ìñÂdÌâ•Ù,D®2¥ˆò¦+]nd.Ûq®ç® 躥èŠ<šn ̨¢V*ÔâëÔ²îXî«ñúhÅfíÖ¢ªÁ~íª†m«Ž-¬6lFi@›(ñR¬~¼mdd2oókDoÞV^õjÅõZª j¯oqoYx¯r€oñ"&ùÆæ¶Nž¢¯úFûR®û†üÊïæšaýâÀýbeþvÿÅþúîéÚk«îêQm§ê-w§ìj-írmÁÁÁBpñòkéò/{VðóD·-–&ï¯Î­d:¯LAïW$ãËÞä¤0V‚ðêmïàR+‹}/ø"n +î 3nOÄäì°w@n¹Z.‰'æê…æªýòªÄâÑJ!¥,±¤¢îßèsjë°vÆ.”ê©Únª:0ÂJð¼ÆÀgToñ*"òÂí㱯K€� �_%�»áj—[©A&n ,nI�/%ßËû…"ï¬í1$Ï/G³%‡.&ëï÷5iÓr²³F­'¯.(0oç�*p30«²³‘²8Æ+GS,/Ä,kóÖr£-.‹0 ëmÌ1•Ôq=µë0sIó^%s®Šï®r3ò37n³Ê4÷E5Wîû62¡>² DrÚM²°J7ãï7+q8ó¯ÿJEt–³£sÕ‚ñÕ¶ó/0*70î‚­îŠ-ï‚_=»òÙ’±…`ðÚð÷sÛ2Æv)ç²J!ùV,*àÿH° ÁƒY(\¸£á›‡"J@±"ƒ‹mh$ñã‹�'BRù£¤I„(S"ìðˆK—Obº˜)Ñ‚ *êÜI±�Ï @ƒ~J4�Ñ£ w´Xªä¦Óšn\ˆAµ*ÕX³æZªS‹5Ú°Z ÀÐ�Q¨E!A…páªx SæL§Nè…À×*ՀѮU{¢íŠÃ+Ò}¹´ES¼7uõ[Õƒ‡ƒQÈØL£³€”fˆ½¦tcÈ’¨†j!(e±°c j¢¶mž¨Y_ˆ]µl�™×º. ¸q•È“\ÈÐ!D¨<1fÜØ‘#Ú�'FRPÎ9ËÅ1ŸÌÿtQófNžè}6Њ•hÑ£F“6~ü´¦TÊWÙo½Ðµ|dŠÓ�Õ›Y …ÙZm½×sÑÞx¨éu_PX‚ V˜ˆ%ÆÂb.͇š’M…Ÿe®µ™ �ÑðJ¡�&Zikœ™jIè6™_±õhO¶Ý¶SnPíÛ€¿§Öpntç$wÌ)”ÔCo°�t ˆU�u ‰4Ò“`ô�ƒv‘ÑSè¥ç“~î _| ‰ˆT÷á§ß~ýIô€aiD�–à‚ ‚Wf„{õå×…®µa‡Š�('d%⊙­Øâ‹+É8£iK¡†£Ž&Zåcl@in�éÆU¾ÿ§$“aÖz�§3Lù\M<�jÖd\çåv¶>9æKÒt&N祩“zl¶ùfò1Õª}¥úu'W^ý7@€žÕ([nÚ ²‡B&!…––††!éb“âU鉗eÊ™g áJ£�x�Z䎦¢ê,Eª®:äµ5)’²Gk±ãªk•Ðíä+°Âf÷%ÅÝ[—xÊÚÄìÁÏ®É^›L[­c GT'eÛò×-‰|féç€â¾«Ö  ž;2„ê&Zá¢î¦HX¼‡ÍKW½{RD°_˜¦)¿0ú j ¢®6ð(‡=@¬ÎYä«1Ī$ ƒ\«ÅÎa̫ƧrÜ¥Çĺ�œÈ@$ÿk¦y‰=´+KûæËô.ÑÌÚêÇ­8Û§€°:.Ðq Ýwºx­«¨UŒú¼4‡ò~(©µ¨ÝKYÕ*îëb¿žþê�^7 ”à“½°Ù £­ö¬Ãéml1ÊH%•VæÜ£Ýj§�ð{·D&É3Ûlšê®QØ%Â÷ˆÇU¶V՜粑ƒËs�——´¡Ô#:áçU…®4 �–"P{;ÀÔVa�Z®öº¬ÅŽF¥!kæ†;ôèN' ”ˆÃ4â›ß ‡IÁƒwˆW¼ÑoWQ^l˜‡ç}Lƒ0’º¨g2b/{ë)ܺg”ï‰ |¼“ùªb¾›�Eg”K›åÿD‡9¹À�h�3Z»0$:ü1ÍCûë_äþ·CªP3®ãÔA:ø)Fp�×k NF„2šñ‹­‰M˱%a°I(ÜñpõA¹…Pr@ÔÒ– ôæ-Žá›ßZxÇf/Z3 ‰÷À'ÔÕgqUŒA!÷Ç­/Pr_æŽx—¢Íïh KZfò×4ÓÑË‘öª+“/«ev2B`Å·@1:PUf<#-'hƒ5&i0o„# A3GOÕ1yx\ÞùèÇanQ…Cë¤õÂÈÆp{C¡alˆÃGêÐR“Ô“·ÔW¹ž)­ˆ…šó¢D¤1ñ~¤„âé`–:UFòŠÔb £ÄÿY®A (]hK„á2—D¨�Bê*Øø²�l{£3‰ÉÅ3cÉá2›g‰D�é¨AƒdMDj“›�¤§7ÇNÇÙŒ’" bYÌ)(MQ�Òdç'—8.'’®”QDeÔ¨h)|¾Füôg@:ÐÀT'�jBªÐ"Xõª¼|hf‚éÑ•ÓxDf€ôX>¾ ™]Hã7Í0&¬¤2<)#•"T:E2œè«äÎÊÉ>"Ú4�+\çM<Êú‰^?•ç)UšJ©Ý³•­cÖV’TY. MuêS)"U„RµªWµjV×Q®¦õ£ÄQi”ÀZúRB(¬$³bˆÿ>1Î €nw‹�ÞúDãk*@Ü èejÀÃj*�ß.¦µ­­çà|B™X÷º>È.¶«@Ø ¡GUQî°ƒ� ºÁ·¾µ¡ Gt“â‚×/ä Ip‚@ßú‚È øÍ¯tÕC™ ø·¼jq€€;tƒj¸ºo~ñ›Y“áe»Æ&Láë^×—Ȱ†7œaý@áà ^ÑŠ@âÓzµª]t©ØÊV+µÍÌms»[Ý¢··À ®™jR\ã¹[R.s�Kè²v¿Ôõ‹…­›]@¸»°}o Äߘ÷ÆPï÷Ø«÷¢­*Užo}é«à#¹ýý¯|<`#'ÿÁ‹Y0ƒ3‹šo—Â^2†9ÌgƒøÃ"Þ ‰`â-¦v1«�®âZÛÆa%Æ5ín‡Ycß8ÇÁnq�›­ä.7“ÍÅñs�|æê.¹ÉOf˜w¥Låø^ùÆZ—½|$øº:3c&sœå\j¿øwF�€@à¼ÙSeÎoƒëlg2¤Û{ºhæQl˜îtVG=áLÂ2ÁÙ»é¬kÝ/]÷ú(ãöËó××j¶2›‰íf'©ÝSl¿™S6w <Ãu·ûÝw�÷½g»ïYÈÊÿíÁ‡»Ñ1ôÌe\stóöÒ;×±ã} äêÔm‘ÿˆÂcùÆVä5›orvÑxpªH}0)ˆ¿üõÓd§ôøñ¦ßzê—ðuÖïÚÌ—w~°÷kg{‹±vZ Ø€|�½warÇaÁGw÷ü´wÈ—óÂr,ö|…'}‡‡6G8·x/ÑxíVzÝ×ßGtá'~ðS~CEèê·~´Ô~1ð~k!óÇõ×^÷gz§gûÇ«G^­g~88€¿f€µ×·'#±Ö€Èa(�Ø$†bx`¨¸�&×�¡|.‚àF0ÇC†G}ˆwsЇ}Œ§}-ˆ/È1H.38~ä÷Ò%€£ƒ;È~_æ~ „Bÿ˜ôǃ]v„ù‡zû×Nøú€QqX€™q€V˜€¸·€ZØ…að…`(†aH†x†QÂ�j˜|È|-w=q˜$H‡&h}–†^U0ŒÄèO8‚#?75=ò‡3Xt76ˆÔ3˜ƒb‘�z6݉%>ˆ‰ã)åyžŠVêéì{î ŸÐsŸGŠ::ü©mþy.± ³ùtµy›®“›Ü±  ê ƒ¡ä'¡@D¡'`*\Z¢ì�!0�{Hk–T“؉‚¢Pá�+*žäiž/1™6!£z±ž±ÑžØñžñ©7=*W¨£?ZhA  j  =F d…¤’EJªLÿÚ›¾œä5À"¥cZœ±·Š¡Y*XÖ³jÏÙ¥z>蓘ÅE˜1P¦9p¦(Óv�±¦-ú¢ojd„d3Ú5Z¡ñ…§ÎTŸ/�+úù§&¨.1¤xQ¤>b ùØ"‹š�Ê›¾t!¢«' ©[B©à9v—:{WŠ+ÂÙoFZ©Tá¥` 9¤J\¦Šªªz0¬šDYG¡Æ«nêp§q«¹Ze'À«¬¬ÂšVÄ Æz®`¨Ôa›š¤ ê$ϺÑ*­@­ÖZØDÚª«˜j¥šê)ßÊ;žZkVA® ª{FØcéú©©z¢«J²€„ð{ò £¬µ,÷:§4ÿZ§6z§8Ú¯œù¯K<¯Y¬…D>G\ ˆº"ÍŠqaCª+­ ,AÁeÞù²øjËɱÚƒÖé¥^Ú®ë²~�„Hè,"¶ƒU‰žH€U&«#ÓZzR³@§°a§!Á¯aé¯>;QPDÅu´w™°™¹°º N«ŠQ;­‘Jµ@aµX‚µÁ~[+#»Ràƒ`�j;‰Š©�ªb¶¦‡¶zñ¹dÛ¶x ·›ór{&tk·b�·ûº³{Û³}ë·@ûŸB«�kƒ®%™�J‹¸Kª¸ßó´� ÷¹ ¹ÒA¹Ô'—;™«8Á¹�û¹æˆ„ CºYÿgº€ºlk©n_¬¯ »øŠ³Ôª³yÚ�|›»€ô·C+ME[°ÂI»K«M›¼Œ»F±Ÿè¼Ð‹ÒË\ÆÁO*©‡ö‘Ž”Ñ¹!°ƒ:I¤<)ºA¾ëÊi˲©k¾«;¯­»¾qÚ¾w›³yk»ò‹»ô[¿»+¤÷ë�¼¾bý+nù м" ¼ ±Í»%UË^jê¾S8½ %œit"Á~AÁL¨¥—ußËÁ ¾Hù¼ž$!FðÅ`|�oKÂê;³ât«OK»zÛÂOùÂÃd¿¾‹¿‚k´û‹´†»";Üà °¸]¸¼L€lÄ*ŠÄþU¹m±ÄÌÑÄìÿÁÙ8Á�;źzqŬÅH)?^ Æ_,ÆèKÆ1aÂ6�ƪ¨Æ,\‹óëÆÐÖ»—r\Äy±kQt¥ú©•`p˸L!‚„2¦YmE<"!ükȰ[ªÌ§‹Åe¶Á.ãv'9àlH𹬱qÝkzQm¡eUÌ2âpØMÝVÒ¬É_Ì2l�ÎêÌ‘»…ÊîL1É<M¬¹¯I <³Œ¡µl�¸ŒËlz½¼W¿¼dÁŒÉz±DbÌÈ £1OÌ\Î}ÐÍÎFÍPaͬټdÛ\ÝÜ&ßüyä%ÎË·ålÎè¬ÎéÌκõÎ.&ñ<ÏØõÿ|ÏóF´Ì™¶ÜÏ`ðÏYД3ÐVÐ]|Ðî”ÐӻЦÌO3;#ÒÌôs–Ð,Í]-ɰÑÖÑí!=^ñEÒmHÎÎfÎF�Ò*ÍÒlùÒl À -2ÝVPÓ…¼6Á”ÓO¹ÓýìÓ„åËXÌ‘Ë^ìкÏÍ^P-[³5Ñ�gU-W]\ЦÕ×ÅÕ;èÍ!�sb ‘d�gf�ÖêŒsíÜÖ¦íÖK-ϬLÃ3=×:€±|×ú¬ÓüÌÓ|m4~�€ÍÅÂ\¾Ä,­†ˆ½ÌŠ ÑQÝØMÕ,[ÍvfŽ•�PVIš:ÐÕDñÕœ½?ž½Úm¢ÒéÿLÚ-}Úâ}1½ÚôüÚmÛ8=Ûy]Û{½¼Ì¹½Û\6Ø…�Ô‡ýÖ3�ØOmÜŒíØX¡ÜæÚÚ“M\Ï�KÑMšÔ=Ö]i�M#Û�ÒÝíÝà½ÖãÝ־孟Ü|�d�Pg’˜)ÛÊIÁ6â+úq]öÐ& eDËÚ�sõ 0ҥ˟Ó�•.N9çKnF±&ÝÓ�Ùmr¥×�Ý.ášÌ2^Úåε®ËáŠãá ž±,ËL2-$¾Í&®(Î*>a,îâCã#!ãÈ"N]ã6y‘ãW™�‘¾äKUC.ÝÌ ¼‰ä®äK~Šf-èOÿåŠ>嘻á‰såÔèªê�A^Þ¹%Ž2'~*)n]+^Ü-Ž6/¾61^i3þæ—gã „ãÐŒ•v¾ÜP‘çkäeÔç ¾ƒ€¾ˆ¾[�ýLƹÞŠ.å½¥áUþèÖƒåâ[®fUé`{é“é>²é=Ðéýýé êJ2ê5Vê\Ã^�êrN÷˜¬>|�îê®=ë$ëD@ëXùô^ï·þë°ë…®…õ^ïøþ¿ÁîÒŒ¾ÊÅ®@Èž­Ê¾ìÍþ&_Za~c®eŽgêi.êkNêmÎ?¦ÞXâNQîXqîw§îëÎíîîem¢§eDÞïô~ïÿšäJ�0ÿÿn¼�áÃNå‚×á‘n�ËŽ  UñBmí¨ahþjNl¾£ÿí#îqò!ò9@òIaòéÎîj¤òÀòU§^/ó2¯œ4�Ý6ó9_c;ßÖ§IwáP!™<ññ5YÀznaÛ™&Þå]·F-Ú¢4‚÷!9“ÜØ#,Seá·šQŸNPù“ “~|m±"k`o|6¢?úqYó‰ŸxÊÉÁO rósÿú¨�9x÷•÷{Ÿõ}±]��ƒ[…_A‡?ž‰_û‹ÏøŽß&�ß’/”oùF†ùA,­š¯eœ?|žö¡?ú¢ÿÿ$ùé°þ§U÷*@ûj`û;Á÷ßè÷±¾d½Ï¿/ÁïÃ/ÅþÇ?“ÉïË PÐà „ �,tÒPÉCˆ7$N,PÑbŒelä(ÂãÇ…!�ì YòãG)Ur`ÙrÈK˜eΤ©ÂæM9uÒäÙÓçO A…%ZÔèQ¤I‰.`ÚôæÍ'QÕLMRÕê¬Y!låÃëW°^3f´h‘ÁY´&Ô®ÍÚÖ­¸q{Ì¥[¶¢¼y×ì�ªÆªU�Û \øÃaÄ'/–Ðx`š 2tñáDŠvÇbäØñ¤‘ KšüÌÂôiÔ¦›6UÚÚõkرeϦ½tõÿ‚§6£>éû·ªàÁÝ[<Ææv  M»VíðáqåÒ�«<¯^¾T} \˜0âÄ‹7Hp&ôéC6tbù2æÊ‘wÞ(ÀþýÐ#Gïø,"õn[ 6 4ð@ôIÀÜTØ­7ß‚Î-ãÂBN9æÎrî9èÚ’.ꪳë:¼öZ¿¸ Ì»ïÀû@¼ñ3O¦ôÔ£¬=÷à‹O³Íè“á>üBÛ�¿ÒDM@“TrI&›4ˆÁÜvÛ­*­’¸áÐrËâ.´+C64¡C? ±ëH4ÑDß’P‘€-hÑÅðÈ{Œ¦ÑË/?åë‘> í£iÈþŒ<ò6'UÿtQFm[­A)£¢²+¯Ì2뼆 ÓÀ“̬è<3ÍëÖÜ«Í7Y´�NO°sFƒòÄ`ÏÐŽ°õV?Çò1P‚ÒI'COC²Qb‹5–I(ŸŠô‰I+•ðÒ85‹SO7+QC$»5QUQUVa|²óò¤U¤[qåQW@õõW‚U Ñcëµ÷^Ø’…*Òf³Ô-NxËj�Î„Ζº2vxYS×ð–;p]lu\<Í=w¡tmÍ5#^y}÷Wy¤_”SV¹ ZvÒeù­Òßgøæ8ÁüPˆzö9a…]œ`h¢~8Òˆ/PzéšvZU¢–úbxÿàj¬eݘãŽGðúk Â;dw�‚7^y‡]ym¶‰uùå(c–²ß$®ÔZœoÖùCŸÚ:‰.Úè2 6ui¦�nj©£¦º<«±¾Zë­;>âk°Å›l G6í“Û}t%Ï– ¡ü¨P}uÖUwO »¯…®ÚkçTñ¦¥Í¨ÕVûÛˆ8‚žÎÆ‹—š¼ûPÞ ÿNŸ!?çÿûazêyUþúH×~{îƒr>õÖÃ=vÙݪÝvLqÏAwŒx‡Ñ÷­…ÞEã�GÞ¾ë}ú>4ç»÷ÿ&e" ŸøÜC¾òeå|´»îØ÷‰~“_ðˆW¿ÆÝOùëÉCÒÿ¿†P„#<ÈéÀWÀÕ�ÏnÿÕ+Ð@õ)9\Ì’ b0jä O<¸’PˆCÔÞÙòÓ Zf…,$“ aæÍ�†'°á �Я1É[ÞPÎFD0†‘tF [§Â%béZNL�&EVñ†XÌ" xØE¡|QŒ{ä#¾Î¦/›œ "iLãpØ'Ì@Ž‹yÌcþx›ßõ'“¤$çîs=öQ“›\Ô#•A>„�£ Î!·äÆ7n¦U�ˆ'›ÉÏP²’–ì•Q2ÉI\æ2A®dJƒB ;RŽÒ”ZBeU #V&€— €åId9IZÖ²(·Ôe5­›eÿú’Vƒ &!]p†³˜9@¯’¹Ìf~ä™Aˆ&&áuMxÆS)Ùå6R|æ³›BœÒÂ)ÎbFA 5'+—ù¶–åG’Ïl§-ß)OˆFÔlð¤ ~™O}î8ý¼À?Á9Î�4Pç¤èmÚ…Æ’¡´tç¯$úR˜*Åy3=Ýßlê#äT§ãT‰J,W {xœçÙS¤&õX4eê nú7�î´˜=M‰å”zU¬ê²©4}*ТšSžRÕªY%kYÃhº­ɦ_5BX{ª6³ÆU®ÿCkS‡ä<¶ºU%p�k_ýʶº2õ®§ËëT©Ê׿&V±Ç ,M+B}FÿrWb{YÌ6ɨðrÞcÙ“Lö• ]fM{ZmöW�ÝkGÓÑ’v5¨¥mmk£ZÕz! ýHleËÛW¸EÅíÙt;ÞzÄ·¿ns�ë¹âêä¸ÉÁreû\ìfW6¢¦v½û]ð†W¼ã%oyÍ{^ô¦W½ëeo{Ýû^øÆW¾ó¥o}í{_üæW¿ûåoýû_XÀ&p� |`'XÁ fpƒü`GX¦p…-|a gXÃæp‡=üa‡XÄ#&q‰M|b§XÅ+fq‹]übÇXÆ3¦q�m|cçXÇ;æq�}üc YÈC&r‘�|d$'YÉKÿfr“�üd(GYÊS¦r•­|e,gYË[ær—½üe0‡YÌc&s™ÍL[^Q�zä!��Üðf8§YÍ?8ó{å¬f67ÆÍp~ó�©Wg÷úyzy–Àžù,h:š½ˆ&´�ꈂ9'ZÑêetž]ÇHOz½•f󥳘iM§—W‚L}jä$Š_<ãùî¿s<,”Ÿºy]f¾žˆç< �ƒÏ¯%ô÷ éénzË£—'ÍO|ÿÿ{ÅòZ;Sß Œ|™sDݰù÷¿­×|è+ïùv×=lxšß?ñÂñqw|äÏ]ùÛ–Mô¯7}óýf¯¾R®/’ìû>øK”�÷~ã'#ËMú°~ÿû¿@9½ök�÷ ‰øk‚ù[!ÙQŽâÃ?ý“þs ÿÀ ÀÜ+À¤8À…HÀD ¬Pü>¿ý#¿Ø¸@ @õÃ@êÓÀ D¨Þ‹¿d"¬A»x@ð‹À l ä"”>:#BÓJ�‚ßã&BR,  ¿ÆÚøAûx´V@‹>ÛBÂÓIÀ%¥+‰<'Äå`4LCü{�†š�ÿ;8ŒÃ[kœ,Bö#0.¬-/” 0ô=& 2d‘'´ˆ4TCükÃòª8”Ã9tÑÂËCÚÚÄèÃ&øCàDïÄŠ(D4¤P EDŒ��¨E„ÃFtDñðÔ¯ lÅ#Dç±DLÔM, N,OdƒPE–r )Å(8Å3HEh!4X”¯WÌÀXÄ€YìÃZ¼EÂÈÅ]ìEPE¤ÆR$FcDFúPFg|®eŠ´dJ·mÓÆÌšl‚Õqx´ŒÂ§  õ!4 tÆè-èG € HåPäXCcÄDzñ®rœ³V1uÄ,vÄ>ß{Çx¼U©ÇÿÉ+„\Áô£‰}œ,üÇ€È�d‘‚,ÁFÜÈKú®…T³†,ž‡¼¬ˆ„¿‰Txt»¹HŒŒûɳ||Á‚øHÉ É~I’´ ‚Ü ƒLE•–,©Õˆ´—¤ÃGLHÔšI¬I*¸Éœd‘�äI�ôI;l>�,.~$J£ ƒ’ôä(ctH«Ì®–¤ž©œšªìœÚÂÊÔJ®´H¯½:jÊ êÈ™J¬!JH˵,Œ¶ xLÈ4F*TH¨l ©„ã©C¼¤-½TB¾¬H ÑÉÚ ÌÆà¶Ÿ4BüÄTL¤4ÉÍ(ÈŒÌTœLíZ¦1¸MܬKU\ ÚĬÓhÇߣHÿœŽ(NÑœCt\�Ód?�èLxNè\M£\LÂhL°ˆÍǔ̸ ®ÿÈè„NÜÌMÌ,Í\IÓúM‰Ì>á Žâ¬�ã¼5òà6iXlΫñÎïÔ�y,‚ØS‹¤ ØÄNíÜÌáêÎÐÈOÏÛÔÍc¼KóÌ,ô¤Iõ´IÐlÏ÷TµF£úÔÇœpÎüÜÏþ4�ÿ̈�Í}Pá2P‘@P}òXF¹ŠÐ¬œÐ­¬PãüK°ÄPKÓÐ)JNû|üüNu{³,Öb ´KÍ/à0ã6ã°@cLÙ™âxdHnãfà–㬘==fF®Ü…€=vÜ]ÖkdAdBVå8dŒHd|¥ßYvä5ŽdƘä0ªd7¸d-ÖäKídéýäeeøàS T–7†W8æá9X¶eYfäZ¾å—=TÈ%"Õ{ '®Ø›e°à(úµ›:6Æ/øg€&�“’•M6··dßþ …^è¥Y;»y߬è›ÿž�ZäP‰�E#¶ÞP•3ÙÏ6á¨Q�Cg£x¾‰y.¦zÖ’{Îæ|î§}C…é[è€��Γ31hcDŽ„^h…nèÆ“h¢Šn‹Þ ŒÖY�îaŽöèißi1Æ’>+xi�”F¥•>€–VœâÐçÌåç™®êT´éh„’•�¶µ·lŸþ  j¥a»¢&ê£Nê±Xj$hêr~jùèy é~¢iU»j0:i›Øj7êêáÀçzŒi ÁYÑÌÈ,Bë/Pë·aëAõééÊõ¨¹&¡†½»–è7y ‹N‰Œ> lïlŒ"çà¨l¯x4Ćç¬Î Ɔ"ÿǶ™hÙIÉÊÖQËÖ!ÌÖl—álêðl—>n RbpíÒ>mÔVÕVjÖfj×®™€íÂ�í|¢mà°íÕ¡Ü"ÅV�ÞŽ¡ßn‹4î±¾’âöŽì<ÅhM™œ®‘¶ Ⱦí:’î îºjë–�Ô¶�ÍHOŒàk¿Î ð& ñÆ'òÖó~4(½ý¡õnï¼Á-ùÊáŽú. ¨•ˆýFQ”9©´üïŒpã0í×KðzŽBއð *àZ¤p¥ñ™¯€jêØOö`�®´ï×µË;ň3 õþj§qà&˜ )õá(œ�oŒdqÿÿçÇ7JÇÿÊŸëçqW‘oð�pª2r1ôî¥Qr¯PŸ3AÌ'o­å’°�µÅ�¸ò>ËrÚò¿Q/‡oL1Ç2OY3¯G)LnœF¨ïì͈ó�œs ®s;ï'äXížòs`ô$¯èAÇ�B'ÊCw‚D/ñE'µF�šô¢³¡V°©¼áï”0‹1ï§2Ç”¯ u´&"/õæ>õçþJ±íz=Voõyuĉuížu†Bò ô ô1ôCÿõL vÁv(vêdWöe�“f×thçti÷tjßIk·iÆšMÇí| ÿ˜xŠÏv7‘'Êo wÏãq»¡_s_tßë>_÷‡hw¬t\�wÜ!Fzr{/FW ©á÷òwjø€×’�v{4xÄ™öà>óüKs†_Õ¡zxåŒx× øŠ§*m§‹Œ_Ÿ�ÿŠŽ÷x»Nð�ÏÜ‘Wš’Ï"§u•ÿî[Gê\W˜çõzÇcE‹š¯ò}¯d’éÉ7‘�²—�¥Qq¯ï¹È©8Á³_r³Î <Óœ°INOÓ"6Ûäd YAv¶â¨H0‰¼zt�šœýü”=ÙÚa7…õa6"'r‘‚ˆaÂáå8B³ Ø Åû^$g\°Ð÷ÿ�(»;Ü»GK£Ìû5Z ðí{Â0|  ÁßÂ÷–7lBS| `|úx4Èg%ÉÏÊÿ*Ž*j¢ûMÏ�ΗÐ? }Ú!}IM$ÜAýÔï©Õoý?ý ‰ý™}=YÛ0’Ô`pÂ.@hã!Dˆ'&¢¨(CÆ�Œ?pàñ#È�"G’,iòdI *W*hé2 ̘fÒLhóf…œ:oò´¹ð‚� ƒÚèaÔˆ‘JlªÁç…R‡ Zñ* Z·RèêuذÇÊÀjöj†´j°m‹råJrç"­käçÏžzZèëwéÒˆ‚s®{ã°ßÄŠÿóÔ™“ÏÃ’o®œƒ æÌ6sî¼Y èÐkF“Vbº)OªWhíÚ(ì[·®bû n� L¸°!Á'ž¸zQãÆŽ(—3oî$\•.]Ò¬¹W¯ãœ×oþ$JµèѤK�öF¸PjƒïDÏÎÖêÕë„øòÉ^<{VíÚ¶lßFŸK×®Û 8Àb€)%D•†Øb &FžÙ1PUPXx¡e„e¦™gÎð!ˆ¤•vZy Qhƒk®G\{Ôv[n”j¾1ä‚1gFqÀsA 9$Ña0]KÕÍ4 NÙA¡�@ õQ°!”6¢§žUfµø^WòÉ'ÿœ}e^¥ß~'éŸ\LºI b�c "%™ƒyZ¡„'^ˆa†bÖá… bˆ"®aš5ÚtbŠ­­8Q‹/�ÛºÍè¨B7—ãŽõ˜Ñ�DšzjJÑ!©€’¼‰Pv*‡*ÁD>p°‘«¶m¬³:¥p±…‡%­6 GT  ;[¤;�p'+ª m•JÒšlF+à´€Uûÿи Þ°­?ùÕ­NßVnã JFA }.ºé’æp­º6Óò¶h¯½˜êÆk§t¾põYgT0צüÀa‹½ØÂ¯6ìpy?E,ñ•ãUÜëÅAeœÂYwüqÈÆŽ ðE&¼à�—08ጭlÓŒ3¶¼ÔËuf(3Í6÷…óc~†;n™k.ôÐD§;Ãѳ&]ÕÒMO*ê©C c¦Q½�ÕX›¥õ]Ûä×b�­XÙož�6Ä‚IÜCÛ»¾]µ`kl–Ý‘â-˜È#�å7�.8áƒ~8B‰´ø�ƒ=žíÌÛJ¾'y}‚{y†šoÎyD/ðyèOŽNTécÈ›ÿºê«Kíúñ`—£«½ k£ªÝí¸œÜéndSÜ„6wuêk‹Mñ˜@ &OncÇм=/"ÑKÖôØr2\pÙÓžb¢å½&|sŸedæƒò°cç£\tFžaÎ}A€_üÿºÊBJ‚‘Š ¤&JSÊ©›@´¥&(e2TÐ Pî0é‰Q> ÓŽ=«Cµ¨f¥Ép4ñY^Eˆó…¥2‹$…:ÔN©/N A7…È…@¸Ê«8 «1” ÂÕÖ%Î)­jU°j!¦Ùg+?ÿZ!=‡tO|æóüìg ·S�4 3uhbJ˜…^°-•h NôÓŠbt�`�wÖª5aÔ ûÙ;<µ:=‹¯ìØ ûíq¶òœ=žl�ÛýŠx®ÞQ®r¬TûÚ0;¢ _Ô‡ ¾LŠß.ãQâøHC>Ý–¾&ìs éÕé›ïAçÛzRKÝÔ¥‡ìéw1�EõOŒ€Î?®ÙÓ¾Áe¶ýàžÚéÛñžÛeÜÕÖÜ _�…Ä�Ý�Œ<›™ýÙÊ%W˹ØËÝKÌm[·ÁõÝœõ-ÕâeŸI0sÁ ¦ Ïá@¬ÀÔäÅÜÌ�‘\ÞõdÞù¥_£|ÞCAD0Të]‡éÈÕéM–aÖH&¡?áÒù=ÿ ÿÉ^íE�j�…T¡RÔX®õÊ_Üß [‚Ä_–Ÿ%_uÙÜ´1Ÿß9_¶AŸ$šÆ@õÙÇõé ž„ †U ª`÷å@½`Ä`ÆÌ ùažùeH4¢#â Óí`èE„v�›!` !ýaf%¡Z"B0áëIŒ>aîÚí™…^áÚeaÛ ðqÝŸÈAà@H`´±aßYàßa`àiààE_zá&Kîárô¡ ü! ®` "øIŒ!¦"BMùÅÛ¸8â#*ŠçiÀúÍW%âßûU�¢œ’€'"á®Q²ÉªÁ)˪â*ºÿÚ‹ÆiŠaÝÕ¢Þ"žÜ.W½!à=t #ÍÕážÅ1"cH°€E^äê1#ÄÊj¬FU}¤ü Œ$I¶È:)£YѪXäˆ DnaÎàz ‡~‘#`ÄL>�ÔXÐ…Ò¥PrdG2.}Ìe]–66"¦¸€SnÓ¶”Tã…t‘—H€~¨Ú†ì½$7 cDx€¨qx…¤Ê/^‘SºåT�ÈÇY€“û´Ñj ¨°�È@XPdE^¤E®ÞbeGvŒH’äH¶ˆH dJB ¹±äȹ¤i.EB`âRà$?zËNZˆOZˆ!ÿQ%Ï eRž�)áÆZB¥KMe.Z%VhEVbÀVAW¶XB„X’åD˜%Z¶Ó¬e[ Á[ÆG\NJ&Ñ%Õ Ä]RI^ Ü^ö¥_~`æýùa²F¤&b*fH0fcÚÆc²@K€W’]L®‘ef*…f¢§NÒ‰g^ÍO¾�h%”¦±œ&jçjNNôA”kî]OÆÓUÈf[h%ˆ@Ím`n>ÄnšEYvÅY¢ ¤eS:åpççŠ$g�-ç4gb=§ñ%XL'uV§`*Fvª†a bŽä:-f†§½Œgyž§„T¦÷}™MfæÁM&tf�¾@}fÏ}’ÿf¸˜fR¦fp>%€F¥€6UΧŠeV&(m.¨½4(Τƪ±™)­¢©®) êD›"È›–)qøjg«�:'žB§ž¦(²*ëuöE >+fD+¡Šµ$¶æŒ¶:FM¶ÔðXTædm‰pð hÚg¦–ëŸ8ée¥+[’»^é‘ ËlÖ&˜~%¾†åXòꙎ„J¤i”ÎlÀæDpý ‚xèÁJ ]*lG «`ü }È@êL§ÄrÝÑzlan§ŒÎ¨´ÉÆžRÇ>ÆÇÔÈVTÉnfΠl.† ¦^\v¸ì…ÀlHÉ,„Ô¬»fi¼&€ªÎ«ºªÛÂêÏ–iЊÄÐþ«Ñ2+ÒZ•Ò¦l¸ü ¦Ô®†Ô«UíÕúeÖšÿÔ`6kצw’dØ>Ú\Aæµ:jQB*˜I ÉN©É2ܨܲ,Ý:†ÝZÞö§­®é¶U©Íš*¼¢*àΫàÖ+ᢧáò&¿R@… í…2®î‰c$­™Ù®…P®Óþê¶ÖiÔl.}t®Î!Ѳ:Hh GÇ!GFœ.�¥.y2jÙŽfëfHVÕùÅn¨Îní¢\¸´ „àçîFÀYä˜ÞÒ¬T¶+�¯–欗r¥½:hÏêæáÊêóF¯âNïï6®õ ,äf¯o¯  Oc|ïˆeæ«Àq.êdúNlƒ¬¯`´¯û¾üþ€üîýî(ëvd¬ì¯ô/ÛÊ®Û>ÿF¯á+Iå'°v-pðŽª—ê»F0—êl‡éChïkâ†Äâ~põÂ'ö‚ëŸpol¤0ÈÞ~¶ðCPmùÆ0ãÍ°Öæ‰ G»ï÷ðsŒ-¾Ü/~2À﯇@ÛÂçÉFn _“‡¯ÏHñ[Q1á oßâìO°mv1Ïž¾vÜ×j³ÝêÍ\ï«ñ…°1l¸1ÚÚD‹/“…ù"+.ç².ï2/÷²/ÿ20³031³132'³2/337³3?34G³4O35W³5_36g³6o37w³738‡³8�39—³9Ÿ3:§³:¯3;·³;¿3<dz<Ï 3=׳=ß3>ç³I!ù,*ÂüÿH@€= (4Â��C"JœxàÆ "‰�±Á‘ã‡�QB®@’dÁ“(Sª°¡¥K10cú˜y æÄ›8#špÈ „O…rýHôC„£HC(µxgͧfJõQ ªU¡9.h5Áµ+Î"`•†ÀŠõ�Y—'KVYK§­[ž¹/zÍ®7ñ«óJp\zIÂájÃtœ™’¯š¶9ñ›qÛà±vnLaÓK”^´#“èjצŒî¶./Ú¢ÌÀaÿD®G4ž«mÎ*éøLM váÏ[“E”d\r-OŽÖ$ÕÈå‘Å”WTö´Pi2hPsU·5òÞYgvVVs©Ò °ûÕ¤…L½Y±‚ŒáŒR�iÈ1çm» òaq?rµ@Å‹r¶ºãÝ­Þ�ö¨ß‘~sm„¯dxKÐM¥¸…Œ·öxd‘¯5¹C•G5æUµ¶9WþVY€¢ëX:§GŸT«ãå¥ë)�Ý d'ÚYÄvÃÂ�šWÞA(Z¿ƒ_ð$²¢ÁÍxųZݘ‡=çåÆ+B]N¦£šYïnÙCÉö6нžM'|w_ÊW…ó1 }—Yæ°ò¾0 ÀsŸËAèÿ3ûÑ*1Kÿ´Âºÿ­åu± PÁS;€Ý®1 $ˆ#t˜úÐcdÈ182 žŒP#Bá¡òÂo}1k3£ž ?`œë …ÚkÎá2å½�†ŽûäÊgC®O‡í»KãÄ!Ωe¤;¢ÈD(&Õ1Ñô JHÀ©ð„“Ų89 P€c”[Ç&8€0!•d4#Y–—ÆÁ­ñym„Ù}Ç–ë„¶ÄcõÈ=ĉç{ìT®ù�AF®�Ò³Ü!{°C¡,²sž{“#‡I›û!1L¦é_Z÷ÄFQM}„ Nªh¥+殃 tÐ)aË@àžøô˜}\YÿOãÉ+´TKú6‘>¦=-j‹²ZÖº¶µ°�­fûƒÚ2&ª"›jty[¬þ– Ánºˆ ãöÆÈU.F™ë\ƒÑºU•®�NUÝc—,Úín_¿‚ðŽ÷&å5Ðy#ùØÈ΄’í¥Ø]àûT´AȾB²Lñ›ß0ì—¿ý ÄŒ$˜¶)´íp{ÝJÐi ö-y¶’®Jx[æ£TȪ0¬¢õv�7‹g]‘ÿÄl^0æLçÖ9 *æ+‹]|åÞÄø03fi�Õ{cö/”<6‘|å d!“¶ÈG&J’•¼äÇ–À‚{ à3ØÁ[n—¿ æ*ðlŠÎð™™ëX·”ØÓ'…sÜÚ<:×ù.wÎó^÷,Ø>æÏb ´|½Þ$êäÐVJ¢—³èF+�kn9U¤?2é%OÀÒ²…rö¤Le+û°0 ¶ —£àeRã(̳;n™Íºjµ¶Útq†õ›©ïÝÚzÎv.²®ýªÀöz—×�y‹^ûÇÈn§²ÍÖãŒÙÉÙä)}¤=íjWºÉÆt”|ÛçvÁàÖ²¸EMnsÕÔ-ÿœ ™ë’Üv ´`\2Þ5±\Y«ÒÞ÷Îw~÷½€hÑš¼—1ÁiœÞb‡)=•MvæÀtÑ)ÚÇ•�x5sp*Š…XÏz¶ÎukÓ‹ë\÷*·=^e�÷6¹ްÉM„nT÷IÕËu7�c^¼™[Õs6­ïM�›–»G¼à}¾`œð=ZV+8¡nèÍ$]áKo:ã+'I=‘õ­:y†–u­ƒ=ó\Aç±þùrgzÓ�ÞmÈÑj�zílG¹1=©n–kX^¬žûZdNR_3¸æôžµœsŽk}÷Uðƒ7ÐÏorx%žèG¸ã J¦ÏÁéÌ®ü‚./R¬h~óÚ=ÿJzñ—^ìŸ2Ù½í¯pWeܦ‡ýcÚŽSŠbxÝ-�ûË©V>Þß@õ@TOá^†wo”UXw–< �|�GxžV€¶†x^¢xFwHG}Jg}اÚ· F`­Á}VGæ÷yå7zç÷PcÇi'oYÆz#çz%'ÊA>’S÷g{.çXt7vçfÙ2Å3€��tv€5�€ È€Gà€/6ÍwVTX…\Rt…flB�×8y ×�8[P†f(‚O"j¸†%v'Øy)(L+˜z¾·zYÕzjGƒ+aƒk‚ƒp·ar'h=x<½÷m(„qC„ `„s†„Jÿ˜@�ka�×ÙÛÈÝØ'ßx@JÿŽâHŽÓ‘Žë¨ŽÑøŽï¸N&Cô¨‘öV&ùou‘Xñ�-�_¦#r²� ¹l‘µÈt·èi¹ˆ»õ(Їâ‘Ã’ ’Ȉ–%7<©DÓHnQ�/ “ �DÁ�$å�àø$âxo9>ù“ì¨DB˜ñX”Xq”UÐ÷¸”šAü–þinTé V©�X™•”'É‚eç•I™)–HI–8b–ˆ–MbñšÅ›"3›)Y+)—mq›×˜›yI“{i“¾9uÁÉJ#Tœˆ‰œF Ycù˜Í MišOi™QY�´q�ØÚ¹�¸•sЕ»õ•Ñy乑Ê�žé©žì7îiOø�´©’,Y.yŸw)“ù¹›ûÙ›8BöŸŠ’z’Q-ù%Ê™”¦™° JÓ)•–™ 2¡Êpú™¡I‡>Ä¡a)š”."ŠêY%:2 hÎ7D¥¢ñ9Ÿ¶Ù’u‰Ÿ¡—ÿÇ—7*d.´£Ú£9•˜«¤90¤€ ²éœ\# *K ¡Ùé PZ¡Sÿºé�¢É~7�¥Šš4•3I¨Dð¥a*2cZ¦#s¦l’0µ‰Iö¹=xù¦ú§ü9§©ˆuj§<úw†˜šÊ§~ ¨ï)¨& ©Òé ÔIjNŠEʨ�š�š¡ß¹¡¥™¤XAž„“©„Ê©âa<Ÿj¤AYªCvªÄ”ª§»Äý‰y°6²êQ´Zd¶J¨óh ©©«=àE¾Z™Vp™Âj�ŠZ¬Rz¬Ú�Ê©ž…šЊ©Ã¨©Ô:Öª€ º«> —,JŸtÀ­£ºÉ›3®Ý'±z®û“®ù•n1¯ÊÊœ�ª ¤A² Z¯z¯š¯Øi¬Çê¤UÿÚ‚Ïù'Í " R°7Ò‘Ög}K¢ÕZ<ך yº¢òÙ¢/Šª2ªª4ʪ6 J9ùªk®çjÑrgMò—,+¤îZžв"Ó$šª©ir¨0›¨Oª¯ï…ƒ¯þª¡¥¡³«û‹Ã´L7´,ש=p´)›´iÊ´mj±3бx“T‹£V›ËJZk \+^ˮɶËY¤qc¶g #i ¬L*\ÃúN3»¯p;5ƒèq{l&`XþÔÖב¶¡]$�»ºëJtÖ¨tÞWÅ6`ñ‰‡Á³±QjÔÆÑ–…uw±ŠUa:j˜5ayK­A/Ô[Cÿ#’TÀ\Vá½"ÈbNµºî»Fc<㘧]!»JEµ;Œ·ËXº»»aÔ»ƒñ»�¼0¼ÀRÆ+ÈkÊkKÌ΋Ó½ÓK½­q½›½¨±½Ý‹$ß¾â[äk¾U�¾­§¾v¾?õ¾,l)ñ[<ó �õ[X³‹¿Lg»��»ýK¼;g¾›Àd›…Ä‹À²À œE \Ò«ŠßwÁ™AœvË|&ü} ,¾#¬VçëÁéûëíÛÂh·üWò ˜ôËö7n‘¿Â¸¿xµÃ<ü¿>À@ÜlÀbÄ!€ÄËËÍ{Ï‹ÿ,ÅšGů{§Oa*ÑYG­ñ—¦¡© lúmmd^æ®5iN¦ß:zÅ]Š„zÌ-Ê>>Ê@ž*Ló€AgEþ$Gn "›>MŽOn'Qn4S^ÆÿcåªåXÇåwñ—Ææv¢#cnæ–þ_h.`=~"™=çž.užüò„z^iPšYÈ®ìòN‹"ÎÄ�>ê“øì�§N|Wí™qíO’íE±íûØíÅ£èªK¾ã^î9pî)>éZzì¾d¥÷îÌÑÜó¾ñWï»~ç¤>gü.íþ~o�î„®í†Îí´žð¶ÎpºÿÃèàè+ ñð-ñØIñïZ?¡ð®ñ?ô„c³-BÚ]ÁwLoòÎbí^‚픑u\B’x/7 ÿ¶uâçð8_Ò”A`PZzföh�ñy$ôDßö•bô½LI»Kßôvï1ššò/T¿V¯|+K¨Þž±ÁcYôõåö•Aö�öŽïøj¯Ærîö”opoïrïìABv÷Î’÷Q?ðS�uUÿW¯©ƒ_ø _ˆóÑ®òrÀø;ÿø´ÿóØô“_ùº�—ßn“›ÑùM�÷„ª÷9Ï÷¤ï÷¦�ˆ#ƒú0ÿí4+~“Æâˆû²_—µŸý\ùœÿÎö»ÿý'ÑûwñûÏüÂÿïàa ?q¢�üPúPOίõ1Ïõ*!ýIFýÔÔþטÀàA„ .4HÐá@%NŒø�âEŒ5näØÑãG�!EŽ$Ù1ÊI”9T®ôÑÒå˜1eÂ4QÓ&œ9uîÌ9ÓçA…!Z”ÎQ¤”.•Ó”ÂÓ*Q?L QÕj¬Y‹Íšue+VŒ%ÛñéY �Ô®ýª²+Ö¥L›þ ûð!C¼yÚuØÑbIÀ�&\ذÄ�#7e,gê—6mþœ)¹&e™4oöéÒe\¥�›*&=âáÚµT¯n›ãñcÔjQ¢�;´5Ô[ ·ß¶¸8ªïV|qyóÖ›ï¥ü~ pÓ¼ð¶á.qÆ;÷|QÇ׆\)É£œ<ËõæKçÏ[wýuå|ôJŸêôÕÒÎYsØ{÷½óÐÅþ4Û?À]5ÝÍ´ëwæ›·û! i/þø’7t]ç³×¾q¹ì•lÛ©/4<ì·7ÿ|лï{âÃ?Âñ,}úë×X}²z…¹x÷$ ëÿÄOœ³_ ˜èyS0ë_Ý@º�€¤` “Àõ-°aä ÿ (ÿÁùYP„#ÄÏÏ 23…L�„+da ]øBÆP†3¤a mxCæP‡;äa}øC QˆC$b�xD$&Q‰Kdb�øD(FQŠS¤b­xE,fQ‹[äb½øE0†QŒc$cÍxF4¦Q�kdcÝøF8ÆQŽs¤cíxG<æQ�{äcýøG@R�ƒ$d! yHD&R‘‹dd#ùHHFR’“¤d%-yILfR“›äd'=ùIP†R”£$e)MyJT¦R•«de+]ùJXÆR–³¤e-myK\Žh»ä%|ùK`ó—¼$f1s¹Äb.@˜Ë f2“yL%&“™ÓÄ€3� M$ÿJ“šË´&1±™Íb s+D‰Q7yùÍ#j˜ã$B9͹t1™ g=Ù£'AŸçŒ'õùÏ#ÔÓžãÄç[þÉÏ~  ú(=ïy |îs— í!,zÑ…´¡ÍND�€PŠæð¢]hC ÀÑ«T¢ ØCK]ÒŽÔ¢5)J«âQ^ºô¥0µ`2uÚR›† C%jŒzTÉÔ ­ùÊæ°�òÔ|>ý);”­š(•©+q*T›%ÕRU§V½ªL’ºÔ­æ «Qkö’Y2²–•&6ÑjZ×úÕ¶Úï­ý¢UYÏšVµ>•­yeÞ^=Ó׫þÕ®‚Å+a·7^r@ÿ²%Cl¤”ZO¦Þ•wŽÍdw)YPV[r=+f[£ÙÃqö±‰ìdù:Z¿Òµ¦m jY§Zíyv íœä* ÙÒ¶©ŒÝ,n§[Þ¾Ö·¤ .=3KÜÔ·yÈuíaa›Øæà¹^-®t÷—ö–:™yQyët Ú¡¤»‡I&ÜûÞö¾×½Þ­x[*ÞñZǼØAYzO²^ÃÄW¾~/}écß=ôV@äÝ/Œú;¼¸¨7ºÅ!°{+Œ#Ð!áUî‚cÒ`=xr ‘ðm�sá gX?¾o‡=<;8`þ�€ ƒâbÊw¾*6‚üâ£,4¶1apLLc˜ÇˆÿÈœŒßüŽw3E C•­,dt=L…#92/“¼d&ÀÉ€²tô{*[¹ÊX>ÏÔ˜df4Å`Þ\“Ÿ¬\IÑÆšI³šÙü77–8q^èœéÌ(;“Ï—1󔉢æ5‹ø1�.òHpiLg4£HA hA+SZ0s™Íêh"@: 1òš×0÷JO˜$ Æt¦5 PNÅÓ’µ¨Cê;[w¹BµªYÝê¼:Ö&. ­k­€[ã:×»æ@¯yhÂ`�,Ϥˆ¡]è�„EÜV¸@¹Ícv>‰CüÁ—Eò�™�ZÕFÙ“JV²±“ûæ·0cˆmm�…Ûñvÿ Á=î°˜ûÜ N÷[Ö Aw_Ü“7¤ém{ßÛ3ù'¿ûÌ;$…øø5 žc‡| áF¸ÂË�îqª»7ìŽøª&ž®Š«ùâ×xK8¾�ïÛß08É0p‰œ…o¹Ëa¾™—†æ)÷Í�•s+ïü-=wÉÏ‹t ý…E'�’ ´§]é+·Üþö.Ä]îs�;w�pw¼+Aï{oBßý¾À^ð€g�Õ‹…Ä'ž‹g¼Ö»R2Ÿõ¨ |å“pyÌ ó ›çü <ÿy ’ýG :{ÚѾv¶ýín§{ë»`w¼ß}ï|÷{ßûž 3K¼âÿ¿øV×{ëýмä+PyËcþòšçüæ?úbûÓ§>�tp}ì›^ûiÿ|�‰¾ûÕ³Þõs‡}ìg¯÷ÚÛ÷‚×ýÊÖ{Äÿø^þã‰?ãùPþå©ðl>ç{¾x, 飾él@ì˾íÓ¾îÛ±±¿ð?ò�Ø“½óK¿&X?ö«ºÝ{?ø“?>Œ{‹)>ÉÛ?þë? @$À<@ûI@l@|@ˆ@ ô<ï«À• ?À@¹+¿¼ëÀôÁÀk?�པ?ÇËŠÄ?ãsÁþK‚ü?|4À@@‡€?PÀÔÁ1àÁôAîBÿ ü6 \=#¬; ÜÀóSdBÀ£ÁíS?üÇ C24Á‹ ¡¨B™È?,„Á-ìÂ/´ÁÜrˆþ!C3<4LCdÃ6œ� „Ã!¼À9DBœ½<ÔC>Ô¾?üC˜Ä(ü½B4D@ĘPÄýËÂ-¤G$@04Ÿ‡˜Dø«ÄKTCMD» T2!|B"œÃ׫CóSÂÚÓÃ8EÓKE?\EVô=W¤7XŒÅaÁÉ«EFŒÁ\|¾]Ę€ ‘Kˆ™_¼FØx\ s³zôÀ.Ü>ÈG}\! qêSÆÆ™H¼sAžx’'¡6¤Aì#‡4A2„Ç-™ù-ÊÀÿŒÌHÜ»èH\T¤FxŠ—sĶud�v¼F‰”Çr£G p˜ŒÉ{Ô>}ÜGêǶùÇ9 HÈ(Èý;H„ì …\Èçkȇ”¿ˆ„GŠÔ‹ü‰ŒÔÈýãH�L?�œF‘äž²Sž�Pˆ“�”dÅ•TŠy¤Ç˜”IÄÇšd~dœ>€\¼‘ñI D>¡J¬(J£ô<¤$ˆ„?‰lJnyJŸˆJŒÜH½ëÈøÈ�LÅ‘Œ–’LG„øJ²èŸ‹[Ê-`É pɳ„É[TËšlKðxˈK˜K‚¼;ƒÜ ¼Ì ½Ü˾üËÞ L‘©H” ÃÄÄTÅdL¬tL­½ÿë!¯| ‰‘‹[å\α,€²|ÉÎüLš\KÑ$ Ò4MÔüIÕ JÖlÍpIÎìL†¼>‡ôK¥L¦žxÊ)ÄŠÝìM«lÌ?|Lh‰LâTGãd䤷ådÎx$Ë–4ËèÜBдÉÂÉ/ÐI#äIºÜN»ìÎÖO=ËñÔ�ò”ÍÄ£MXO‹lÏxϪl‚5Ñ«L»ù©g9Çþ1Á´1©ý4šþTNîxÎÎté4½µd�_! ©De¼¸E‚Õ$¼ÌM …N %Àò¼ÐóD�å¼8žÈB,Uª¨<ª\̾#ÑE»�(’4º•¿m¨™]‚ Pÿ$�ÉÝÄÏÛQ êQ3l=‰ÔÐì¬ËÊã‰1R ­Q&TA]R‡ä’Ä{Rz‹Òþ›Ò~©R¥ÂÒÄ Q.mLo Ó­K÷`Q qÑIÎ]ÓÍœP7%Ð|>9­ :U@;½Ó‰¤· ÒœèSÃ-?ÏZµU\ÕU'UN(Ý )Ý?*¥·'±RHåÍõ».jTúL‚x5"Óß+S�:S‘ISP ϳ¼ÅqŒS_‚L£ ÉQ0¬Xÿ‹M&˜ñQºóV MM$×��Õ¨¤ÕδÕ[%TuåÕ‘ñUÌV—Öz…ÏÚË×}íWEy€ ?�e<‚­'ƒµ„�V6­Q†½VS}ØúŒX‰еX§ÅØ†ÑØ¹ãXWõX�Õ ‘ÍH’=K“e‚t…�Ce×Du×E…×F•×· Wb�T-�YùôC›b7M…�'¹¸‚ê ¢"ªœ¸•ø[À \¥p =…I&ØB.Q¬ÌG$=�`7˜ñŽ\£jƒF5D¶ ÃÀÝ\Àý—ø\Ð ZtAäËÂm��Î]ÐuÁ D—»Îå\£i 6µ€½T|‚íû<=ÿªÄºÝ�»¥·¼ÍŠ#í[[™]ÀÜ–(\8ÜLÜ.õCƽŸûDˆ‡€Ü†‘ÜiÛ5ËåAÌÕ\æí\§´ÈÑ%]Ê3ÝÎDÝåœÕÝ\Öý\×ÝÀØ-_À­]¸ÝÜ ÔÝí]Ïû]# ^3^Ý(^£9^¬H^œðÛòu^€^é@ê]\¶ÄÞ®Lˆí… È�É­\=¼\d#_üµÍßJ_õeß³t_圂%XÝù­ßØ»_ü�ýå_½Ó].Ü<ž.… ÄnV»} ¼=d`p`æ…` FÜÄµàÆ•Ìƒ^ùãïå4fÂ'ÁÜ4åÜÊBß+TßäS¾ÖàÜþtaÿÎ}Wä{Ý3®áUzìß æ¼þa â_â�Õ�'™Ö%fâÙubÕÃ…âI=Öë5¤>Äbþ^OƒÆ'AããëzÊ@^D3n L^~áÍeãÊscP†c’Ù_9ÆÝößæÝRÅc¹M!V@ž€?¶Œ@äå}à ÜCNäé�bF¾`G¦bƒ°âߓ䯸`ðÕÃKÞÜ/ÞÜ0>á1&ãüä¯åQ^ã²mã |cü�cð¤ãÿ�åF^[Þc\&bâ} @ÎæÊSâœð Î5d!­fÎM›é˜çÜ?{Æ üÕgäëçÿ«à€Æ`�héé‹dñŽ#uÁy݆Ü4ÝÆˆ.«@n “"g¥^‚-XN�*ŽÖ�¶h�†G‘>V>çW®c”6=ß]g#aiwvéͅ阖Œ^–Pž¸é`~ÞaŽ^E&Q)öéêjò j 5êAê·åådêMã™F>¨n(©þ[QeRŽ��çSçTŽ��–‘netŽå;Fëa7µî½JäÜyk¸¦gÊ«i kaÞgÊÓé6f/UÒ‘°,Ãÿ‚^<.y‘¢Þ¿£ÞÀ¤–ìUìa»ª;Ì?ÀR‰¨Þl¥®j«þÛËV¾;íÞnrîìlk’6i;Ni1m3ôkÕ.Ö¶‰¸ϹæÙÎi¼.æEÎíݶ�^t¿ìÕîÁ&îÂ6îææä†Å¦€,¼Ã’yîˆî�\Œ®nËÆêþËîíÖîîöjÏoÐët6ë¾ïû0oDïÍ]íõ6�övÉ÷n⺎ໞà�Æm}Õm•öIÔïµê+†ÿO¾Ãî ÄVNåÎ3ÌHðó[ðçvp®†ðL¶n Çîó»p ßlïæI°Ý/iX>iYqqãÈY9¤»ÿŠܹ6oóH©‰áF¾ÁÎHBÞÜò|ÎÊ“Y¿Û>PË™µ$«¹ˆ˜i=\È«ŽéÈÍ$¶€z>*s»¸‹Kq8Ò#½Ã×�USCîHÓ©ýÖ-÷ONÏŒåÏ«'¤ð „ß)X —8Ò®ÝsüC‰0Æúxµ¸Ts}É¿7¯ôÿ–s §ó_žÝ;gÓ<¿×¾ãs™òóµô@—¯‹24tøãÜD�ŽE7ÌFt£ŠtI7J·ô_ÏìØÓtHãtÐðônõ–õRóS§§TïšU‡_Wo X7YY�@Z�[§\ßIÐunáuE·Œ8¯ç`ÇÈ:Üb—ãcoÛÿ}O»>çJ�øs™zvh§i‡?jï=k¿?l· F§iGmH/·o÷w ß¿L?�MçÁN�ÑO×_w·QS÷\|OzÌÉõÈ·•ÉÇŒé°ü9gøaçÜÍ?y ðü&Øú‹}!ý‹2ý´C}ðPý¹cýpýŸ€}©\ûÊKù â B ÆhèÐĈ&RDbñ"B„a6rÔáñc��"»�,irË‚>|P¤˜äe.¨Ð|bsN:éðLáÓ$Ð)B#]é#bD&J—6i ä)T¨*¦¨Š *Ö¬Z·ríºõ ذ@ÇváÁÃa j×Vhëvܸrá.\ˆb�¼ïjÀá÷ïZ´‚/.Ürb‹ÄŠ£ÿ>%ãøñ˜È’‰RŽ`Ô(ˆÌš×pîÌÎÐ3�.�â4걨Q Žqà5ì¹²ÔUø÷ïa [º-Üàw�9†Ïx°uk"Ê%¾ˆÑøŽèÒ?~S¤Î^¹èJæ˜6­ÿy*~W½òïÏ?¬XÙ•dZk±åV[³ÍU› ­åUÃ^Hõu�!Ca†¦˜b%xøác�IÙ{–]æƒf›uÆÙgç�Vi«�¦šŒ­Á›‚q1H!¹íFQo„dqÅw!ZÊ!_EÎ!a\ÒI·•U^‡�€Û ´’wE€÷’x5Ýtÿ^zëµGV‰FÉG_}MÜ—Ÿ~þÉ9gU‚%à€g9d Z&˜#]µ9¨×D|ñh!r–‡‰}bˆdŒHâ{'¢˜"+²È˜‹0Æ(#�«Ùxã€Z�>ÞäC9”H:¤$“9ù$tRîP¥•Wž€§–qùÝD0Å4“˜æ‘Ù“OgŽ•f|?ΧT›N1gœtj‹ÕÝz+# c™5î¸h1ègƾ¤è²6ô`„ª’ì2Úè£F*é¤Ð^öÀkºF‹ç9p0ÂàŽÕ ;Lj©sA<¤H"©Š«®¾«»´JKÑxã}¦ë®¼nàë¯Y¦´ewÄj`ÿl˜ä�)Z™ÍÎè^¥ÑZ@›ö] ç~Ûjëí· E.¹æÖ†®ºI°ën ð*á¼Ô«è½æ[¾“Žá¯Q ¬iÁ¢!œ°Ñ&1ìpÃ+ñ6ÜTqH]vy—ôjËêñ·…LÓȺš|²¯À®,lË^²2+K3³ìÝŒfÎGIÛ³µQa´ÐsÝ­ÂG#M CçúÙôÓîJ­Õ"Úš½â›o×ýf¶Øo \vhg\ºÚ‚±Ý6©pÇM*ÅtÛíÞzÄ·ßHžÛàT.åá(+Î]—_;^y.Öly¸8W¦ææÔVûf~ ‡¾ÕõÛoçÄk‡ÿÿ–â�Ä,Å'Э=8   ÀÞ �Rk ±.¹ÅRC’¥”t5ªå)ÏBø!%) \àp Ö4¼µ-T’b(C*ªD¸!-5„|oÙ˜‹gÂ!¢ÆR·jZµšà¢?àð†ú#‰P¢8…=¨iÙÛžt Å-Î/+ö»Ÿ�žØþõïDÿ; Äø6À"0� T X�g‚Þ©à‰.XÙh°lÔmÂŒ�„D "jPøª‹†jÍ •#ÃÞ…]6lâtè.zȇƒây„ˆHÑIH¬Ö1)F) …Šy±âà°�.zåÿ‹õßɈÿñ�¤R#ŸØØÆ¼Žq¼#ARQ°-Ôã@øè– ú©ƒ�| IÂQ¢@‘ `¤±YH6†“Ôƒ8 sÉ&jRVœ,�'CJш’›«)¥sNÙ¦T6q•¬te `2Y]±å,1ó–â›"*Ñ@P´¢À4�0ÛÈ·†2b¼ÌšY‘´6ÒlK^†Ùƒ:°´¥ͦ‡ I�ÞTi‰TºÐÚD’*µPƒjÉ÷`2“'ê(©Þ™žôl‘‹ý9Ü2o$K° V½êV<%&6‘]H½”t"V4U‹ BJ*†ó¡¯ÿ’èD+JQ¾ñ-£Üè1¿ ›�%¤wlKIk‚“V ¥Ãl©Km ÓÈ”¦Ç»é0s:Ì�Ö¥§? *PG÷ƒuæð¨µñèA>´Tž”U~\�jI5ÕUõªVͪ§¸ŠC¯~6©Æ«NJ{V¡¥õD”]HCÝZ$¸FT®s¥k‘D"V•â5Žz} r�ŠT°%%¬aÛˆX–¾T„15¤cÙÙ6J¶�¿Uˆe‡‰ÙÌŽŽ³7´Ôs ÔÑêö©&‹*ŽäBUº¹öµZѪloHÛº€6#¸%kYw»-û‰U­7bkGKˆ׸�@n‘ŒÀ p˜oFø°ãÝL·¯è².ÿI±[•n·ÝÚyMPS™âô=:]+OË©œËbV³š jg}Ø#DÂõåO•Ä dü¾F6 4Jk] [ø^‘rà#+XN Ö‰ƒaaJ˜Âpµ0†‰£\�l¸Ã¯ú°B\Û�¸Ä+9À‰QlÒ¹ô‘ÅÛ}q¾bOsŇý³-a m… š„…¦Ì¡ÅœèES»ÇÖî¶�2i°§ÛNE2•4Íi'+Êüíï”KSeS›Õªöv¼·2oWƒÖˆ–u„Gkæ¸ö×çõ›}}ƒvgá~R8±ŽR‡kâ_”øÏRqŽ“×Ùæ�¸ ÒÛÆõZáã j�G¾×’ÓwÕ^÷¦Å�߸”ûÜUˆ9ifÎî9¯ÝÀïv{έRVzÛûø¾�¾‰C\9 Ùètk3Ò®t¦œT v±~ìÿˆì[ßq³ ý쬣WÚŒfïÇC.émü &7+¦U.÷&“»å ~¹”GMåugˆòZþ;Î_•ì¡øAU’Ù%‡ek¢/}¬$ ú#¸>öw½k-p¿ûØÇ¾¦5½–‡)6-&â 1ˆå¨ï!â�ˆùÓÿÎs_>jfð? þÿÆÑž\ÀƇðMzˆW”Æ!, öÕ½)H—@ qü€^ ”FP­Ü‚(ă@ B�€b –`ñ�àXŠ¥˜Êô߈ÕÉ ñP!_± ó­D]Ñ�ôM_WT_|ßõi‡uŸ÷ aø)ÙøµMùAÿ—+ÉF|Iû5¡|üÅŸ„ÙŸÎFÃH`­ÉÿÑÀÿàèÝ_ ¾F¾Ê¢Û”1`jáÂÉFZápPà\ ö‡ÊÅB| †€’@ š ¦à‰° l¸à«À ì ÌàŸr86ŒQì`Åô`ôy áá!÷�bŠÁ2@§IŒRòÝkH¡jQ¡æ@üñAúÀ¸)HÒá¾�aÿ�aà*Âzˆò¶¡‚zG-Ú!Z`’ÆÎ^1Ò†æE â"""^†"²b†À æÖ#Êà R"X¢©ä h¢Hpÿ"x¢õ ¡(’¢Tcœb*n£1n¡‚0ˆLÉâ..âkÔâ-æâBâ_-*^D…¡0cä@ÉÞ]W(`3>cÎÅfÄV`5^£dcÓÍ¢vc |ã Š#¨`"žc\0b†±£iÅ›$£< =ÚcHà£>&@!S6%@ ¤Z�ßl˜á+ÖEBŽ”´_CúâCŽ–d\ô"J~a$12$G"£*#ê^3:#FcL£Jâ!KºdåE$7š ‚à ÊNš£Nd:®#‚ý$«e Vâ Î#&êà«Rþ`õ-eS^æS&á@R! "¤!IXVÒÿ"Wb¡Wê"U†%LäpHTYVãY¢cGÇGz…Hº!IÊ%]ÞáJê!6ò¡6Ve_BÉ_R`Å`æû5¢OBâð½ãbÆccåcÖcdò 'ú‡e^&S$Ü Xê¤g’hŠ›VæZ.ÕWJ§jækò@’a<#Z†’Èæh•FR¾áe”älœ$ßÌ€æ!h•DEUU.Ä7"`§çFš_^Ç�…º# Z� ÞÀ%2@&Vç&^gd§vVf5v'Ÿ|ç9†§’ŒçK~'OÚ'zš¦FÊ…X&ç/¶&§|¢#}*Œ¦~Rfè§È™Š¾ €Î�€Òÿ¦§(yv`Á‘\F,hq:(Ä<ˆ„â…�…NâseŽ¥‡Þ#ˆò‡ˆŽ(w¦œž¨ƒBéB\åR¨hªãy¦Gz†ijú"E# ¼§ÿ!ÐŽ ©ÔçpHX�r©¤©4Ĩ5ò&Œ8i‹詵^Pi`Z)©`épLh…žbb(cj¨cr(d&—uö vVãˆng‰ª)*²i›Æ@ÁizÈéTn%�zdiê%�æéXÞ¨{V£Žjá|¾¡æ€¡’F~. |1ê\:*’Bj°diPj^ZjÍaª¦®D­ *�Eè§ji¨æÜ¨f(·Ši‘”�»¾ëdš©«¾*‰âµ¡‰Š*â­~&V>鮚§¯Æ(°¢&”ìK{ö©±þéêNª�ê}:«�*ª�I«�G’.iH6iD骎Àb:*(qæd¸>h+féXmi— et~l]°+q¼+¼–©Wœ©v¦i¦­)¾–ìì«xök¥Îi2 ìiÂE�„ÁVd±æ¨ÂÆ'²ò¨²>,³F¬<+\î§ÅRk‘dl¤(ÇÊ�Çž –yëÈ fÉ^)¹æ¨réü!ù,"*¶üÿˆ `�ƒGŽøXèãÆ€‡#8@±„Esh,À‘£–2eˆ0°¤É“(Sªüòeˆ—0 Èœ)±æ€™K`ìÁ³GÇZ´J&LH“ÖdÈP£Ó¢JMšô€ÄX³’ÙÊÕiË`ÃŽ¹¡,×hÓšXË6mZ£/[¶,Kw°`è•׎ߴ6R<�3çÓt)^¬r ÞÇ ®Hž 7ÄàÁ�#²Ý̹ó…Ï ùˆÍt¡[´=G‡Yí4‚k�eÜŒ%Ù@Aƒ$dê0óÄŠ3nüù1äÈÚÈ“Ÿ”˲òLš¾oÊ̹³'q¡D‡V¦Štié§¥Nÿån5bV­\·ze‰ìltÏžî|úFeæê–½‹÷1_9~ÑX`ƒfÑS~-ƘrMF\—QÝ�UÈh¡�&ÚOÕ—šh«…ÑÚk É6r·å¶C½eV`p8Åaq'2hccø9÷â\O>uTvÚÁÅÞ1TâApdy�‡UzêiôU{ïÅ·U}ô�vsúÙÕž}ý…–‹Àæbd(¨Ø�8(YeB™™…xš€ágnÈ¡‡<©ÆšF®E›‰ÇÕ–"B ±Ý‹: —ÃŒ Õ祵€ŽÏõ8Ý�Ö ©¤–ºw5íHÀ’K>)QgT’ÿ±Þšž¤%ØYM•-&a‘  ™-Ö©aù•ƒ›ˆÀ ™^•qXÀ„yZ¸ç}ò!­´ò∆–8Š1ÊÛ£ibãpBVš(¦˜jÊ)t¾ù)�וjª‘¨J¤*«à¹ªg±ÎZ«I·æê×®õ Þ¯cîU¦€g˜&²9(ˬ³ÏFË!µÕv–m¶ÛrØí·„’Û¸Š–«[£¦¡KŒ2ç®HðÂ+/\ªzJuà+ª¾¤žJUª;ü”ÀÁJ¥ÁíÙjÖV ÓÁpD?qKq±{`¸j´ñ�Ï&àñO ‡¼ÙÈ}–üÓɃæPè¡,7vÛm+Æÿì¤êÖÜ®q8ç|©¦4$ΩÏ@ íѨDÓe4ÒÏe¥4�¯r6XWà�–ÔuUÍ[¼Âå«~ÀæõlÕ ´ž™�%$K‡F!†ø.ri¯ÝQe5…\ÜÊÝ�<-y·¸–ª´wA}7$3ÐëNj3á´~#âŠó,ã ò”oäeMîŒùÀ›m^åSžƒ:]¢/DºDÔoÿ’ꪛzi³îz`ÿ*íj†ÛÕ&mnH ¥UâõÀwpÞh„ÇOeˆ*œÞ–×<°+]’¢õ¬'ìÑ`qѱWu¼74ðm@|QUùXu¾¦iŽ"œcŸh>‡0ýÄÏó‹ˆýÿîžüadýSXë�™…av¬�ƒ@&��pq �"A? Ï‚à9ÞÊ’—’å! ƒÏ£»u¯P=Žh�¿�4¾ÊaårÊ\úp¸>§´/ï+˃‘!ÖFDâê”ø?›¨ŠMN!`5ˆ»gYñŠj ñ¤«ßõiI,Ÿ"Æ º±Œ„™óþÂè‰�Œo¬MµÇ£Òq…Aº£ aþÑ|�D[Ô'«ÎíÐ}= �ÂF·–š8²�ÌŸ$!ã?&pGuË�&§¨’*Z‹Fq )©dJ ¡’‚«Þpy3¢‘–3‹”-§GÿÏ\¦d—F¡W4;rúÒ£Q”ÒÇ™ÌpI5|Hg˜¹¤C&r‹¬&ý™MýEŒ›”ô¦%wD‡Ë8°^s gE�…Ç™õñ��¼è;ÇÂxyÏI&Í J¿äÒuõ¦§ôÓ IV·ŒéšzÂáJ©RÝžU÷¤ÕR~5xb˜Y×Ú@·¦³uí¼ì‰×Üõõ`Bc@—Ç,)6¡wlèdû8ÑÍÖ쳡íž+€Úʱv°=Ö ×ÀÀé¶ÅÁ�’÷¸ä%Kÿ,w�N½nŠ_xÌ<� fyç (­4>˜¹MfýÛßÂ.¼á½fÛØÞžhÒ­}õ®_#j“ðÂļ WìÂÇ’¶C¿¾ÍÆãÄ).mjœãfyDîi’ÄäÍAyëT!–“ŠÝbÖjÌ_¢s)×ü楩{tªÖs©þèE:¿7Stž=!IW:Ókâô—@=?RÏÙ{ÒöƒÊ[^ÙÏl¤µ>— ë¹üú¨)¤é�W™CÞ~¥ÙA=›“‡ åÙ†jÛÑM6áº|Õ2—Íûý¼3Eï¾á{ßÿtÁû¦3…ïÁá��xï.^"�Áã.ùÙPÞò•Ç<³5¿dÎ�Åó £ÿ蹬mÓsõ#_}IÐþ˜À¾ãž=˜mOqÜÓ]÷Êä½Í†sàgðEÐwD@|AçHC·É·|Í·tÉô‚õtyè5u#q}Ø÷In`di›G4[máGBãWnl[çgTé—3{&,Ø‚.È‚ìç~k{¤6§Æp§j0×¹7^žÑ{ü—wø7!(€(XÆw'œ‘€„t0¦x Ñ7}‘/“÷,ØWy¨�Ø}Øy.‚Ö3‚4HzSf~‚C[)/+ø‚nƒj×lw7¸9Øn;؃]uwAø{CE8|€IÈ'XFׄˆ÷„Î…Mÿ÷€Ž�Ôg…Ö‡…Y¸…FÖ…üå}#~k˜qú�sð—i›‘=±$V�Šªh=p–*2]䆮xý÷‡QõqRa€'ñYõ=ÀW‚XÑÓ o�aÌØŒ…XXu2ª2èArr-ñU°�—jqCtH@K’84 ~çy.gŽð&¢¸{gxŠà¡Š«h8­8‹r¶k4‹AP‹56¸xºÈ‹&á‹LŒ˜<‘Œµi›¸iƒ´›Ô›’ñ›œZ9œ›Qœ‚œÇ¹œþi8tÑœ—ñœ�é’W‚lÉVõÑŒÍèoÚY;êÙ�·è�¬9EyIfEy†h–j‹„é”ñ—›«Q¨I±2ä˜6‰V³fœÈùŸ0š3J@šéq«t w#°³  jú «¡€H¡à ”;ønëIŠòv–¤ùŒFdšD¢}g¢T‚¢‰£¢@Æ¢p¡Ÿ?ÁŸ1¦¬U:�Ä5j8;z=ê£x¦|@BêE@¤w¡MZf·¡*¡™¥F4¥pQ¢t¢’‘¢Ï²¢\ÿ ^Ú`*¦’š3Z;5Z~7ÊQs# ЩžÚ¦nñ¦? ¤uúxÚšF*w¬æ¤ é§{êÑqMÒ¥„j†Z;ˆzŠ ŒÚ¨!𨩓:¬)Q©!r©ñ†¦@¢¦9Úžú©£ :ªZªRxªšªjf® $•QR'³:¨ïY¨Uz¨Wš¨Yº¨[ê«¿ª0.ÚŸÄ:¯ÑT¦q¦5�©´²©6ò¬� ªi!ªq:§tú�w:lß™§Úúªå©¡hæ@ßzá!ãš?µ ·"¹º«�Ñ«� ¬ ¬ô:¬xáWÝÄPQ8'gïaFfä¯ ¥á¥„„ÿ‰!�CK@g§ ›N=Áb˜UY+!£* ¡³75_Kr-×¥F™5T[µVKµšµ^ ,Ïrµ^;ÍFd�Q²d{²Š�²Ý!,[.;0»<2K³‚e³D‡³Jû<[³(J`¸‹†¸EdD‹ .…R¹U ¹Ž%¹üӵ ¶—[_c«¹óʹ!¥²™�sK2º¤‹¦›?¨»‡h·…®ÿ[>Ë·=à·¸¤)±"Šœ�»º+d¼ûPû4RYÉ«¼‘¥µ Dmïáµa˼™ë¼Ä ½¹²DÒÔ C�À |½‘½ê²½î}¬г° ´};»‡¾T¢¾›Á¾ßk7»û¾¿éqAô›¼ÄÛXÆ{û{µý;ZÍ À“j¶J眶¾qÀO¡À ÌÀŒœ& Á!ܺ<Ä x/$øñmš¢/[áÁlÂÍĸîKÂ9`Âí¼*œYøëú;ü»¼2ü¿4,©6ì]8Ü:lƒ!›9àà ÌÀØë¯=3x ¡šQµHlÁRÈÄ!àÄÌÅí!Åd@Åkÿ¡*‹ûx¤YZÌ*¿»´®‘…?PÆ‘•6Ô)ïñÈ‹&†i¦kŒ²t�Þ‹& Çt<ö4]×’ÇÇ·{,gåÜ)z¼|œëÌ$íÌx?ëR²+†òÌôÜwÃ,Å\(ûÌÏ\áÏÊÜÌ–ÿ\yÖ › �ŒÐ¥¢ÐŸÈЖéÐ¥ìÆ:ŒÊªlÑíÊ{Ë6‹Î¨Î¶Ìθü8KÒlÒ푾¥!-õ|Â�Ïú¢�ëÉë%Ó@Ó5}Ó�‘Ó;ÍÓàÓeÔb)ÔÝ,3G�Ô ŒÑKmÎíýÑá;¾±{՜ռÕÒÕ9Ö¥"Ö�EÖ�eÖhmÉj­l}Ðn × &×ÿÞõü|oŠsºÓ!§ñŒížµ£Yÿñ°qYõa˜ &\ÉY“v¼ `¼�J±¢l­Íï‚G2PÜÆÍÈ�ÜÊ�ÜÆmÜHЙ"Íœ=ÝêèÙ~õÒ2˜5D¥]õÿ�ÚO©Ú!ÂÚÁýÚ–õ§uBÛéfÛåh¹ý¼m¾M%ÀÜ öË�ßlÐÜÅ­�ÐÝMݾzÖ­ØÍ!ÚÝ”Ü ÒòÝ ŠÊâ½äÝÚæ è!ê]{¨vÛîÞðÝÛôÛ>Ürpß³¡ßËÍß2àßàÍ:à0žK~à?‘à�äHo:WCd›²'¢a0á® —uá—‘áUÅáñÞzßó�õÝÚ&þR>倎MãX®~3ÎÙí¤:n?9¾ÝuÆã ä|QáÚ\µ½áí�ÛW~q.ß!Nß>Få*Aåx†è˜å|NàŸÍåîåb^?a®àcn›eÿžY$Žæ{j¾Þl>mo®ÛL>çN^çS~çy¾éVŽH}þéX¶årÐå|ê×Tè7¾ãš$-…’ZïÁè@R5M²ÉAé .<"î^ =Í›ŽçžêÂê>ê�^ê�Šã=úåû&lFÑêòê¨ëB~ÞÄCë´œ¶Ž¸.çºN%œøm.üëÀžŽÃ~î2^줫†NèË>è)¶ê/í?!í@íe0ä×®0µþ¢6ÒíM®n_×ä^î‡îo=¢.-M:D¨~›^opAïaïø®ï³ÎïÙ¾íºç(-fîª7î/åÁžð*8êÎ! Ï[©ì ÿÊìñþ¹nQÏ?²ÞØžÎNáñ�Ñí¨â#?ð›ÍÉ'�òæ¾òNG-ÿ/?z§þîí^óQVO@®î°ÎóÕnáûž+ý.¯ BôFfô2MòȱôLðO÷È��DëN‘©}°!:1´ÂAay*ñhúøZ�dc0ÃÖcÉ‘fÉrÿøÙ¬)uŸJiã5H}/Æ�%øÿÔˆoøˆ¯øI•ò�úš+ùDBùNjùЈùá÷Äcøž�šúœïX£�Æ·eú¨ÿûÜ“OA•/èXÃ౯ù³Ÿû�Uû’ޏ¿�µû ði¾üØ/Ê¿úÿÄ;ám‹î™Ï›Y5]y*qûIføiCúþtýÙÿË©úÙ‘JÞ¿÷àï®ã_þ…?ÀàÁƒ.ÓÐaˆµL¤˜ÀâÅ‹5näØ1áB� =Ž$YÒäI”)U®dÙÒåK˜1CPÓfœ9uâ ÑÓçÏž„ZÔèÎ=”.�‘ À’3g>ýA±"Æ1£J©ÕëW°aÅŽ%[ÖàL›6í¬e‹Ô(P:qå¾¥éR¦M#PÝÊU!U¬�³šàw!aĉ/f¼mZlÛî¬ÛSîÜÊEïâí¡wïÓ¾~ ÆˆØ°ÂÆ©U¯fÝú#HÈ‘%Ûq[ùrÿÜÌšwNàÝ;Ãoà|Iž0š´EÓ§]/gÞÜ9ËÇigÓ¦lûvn H{ûþ[øHâÆ�'7üÜüyôÍ£«�]»îm:Øjß>¡»wÐÃO‹'MÞoz°µÀF0ð@ÏTpA«&:ð@ "”0¶+´ðB 3<èAôðõàp %ÔðDSTqµ?t1ÁG,1Âk´ñFYŠíE%jpÄ™rrH"oŒ-°ü‘à ‹tòI(<«$Œ‘É�¢ÔrK.S›# ³ÊB$®K4ÓTÓ«//óM8Ý�sNªb;sM<óÔÓ£6-‚óO æ¤ó);•ÛóPD×ìÿ3@ãÔ�:!»3QJ+}rÑFß|RB%5ÔRPCµÓLÃÜ4Ò´&uUV[uõUXc•uVZkµõV\sÕuW^{õõW`ƒvXb‹5öXd“UvYf›uöYh£•vZj«µöZl³Õv[n»õö[pÃw\rË5÷\tÓUw]vÛu÷]xã•w^zëµ÷^|óÕw_~ûõ÷_€x`‚ 6ø`„Vxa†vøaˆ#–xbŠ+¶øbŒ3ÖxcŽ;öøc�Cyd’K6ùd”SVye–[vùe˜c–yfšk¶ùfœsÖyço;ðùç‚z¢‹æYÝŸ�:è¢�>Z¢–ºi¢1°ÿúj²Öš®».ák°—:²ËFàéd¥žšê«±Ö:뮽ûk±(Ûl´‘U;jªhÛê·áŽ›ƒ¹éûn²ÏÎÛØ½èûo W`p ÏárÌBñʼnmüñ¿%§¼ð0ÏqÎ;ös¶C|tËMÏAóÔU–õ¦kÐ}÷"z÷àƒ÷lÙs0àx¼m_}o"šw~wÞ}ï=xá{'^öã H^ùÛ™w¾yèu—~zêqþëâ³ßž{_IpÿýïÁü"Ê7ßzô±G>qö�}þø…¯ô³ßùJ§?íñ¯íû âG°|Lßþ6·@Yõ-i>Ë^öì7ÿ†Ð#$a G8”¡ï+d¡M0ø* n°ƒÇ a mhBš…BQ! Wè¶*†I›¡lxÄäЄ;<@}Ä ®jˆ?+"o¨D2щ-¬IYÕ7âЊ5Ä" ‹¸ÅvÑ‹¢cøÄ8F–q„g”�Ó(€5²‘ja4!ã(G:šŽ…É£÷èÆ>ú‡E $扜Bê1wˆ,¡“hBFÎЉ„Œ$¨Ú½7Âq‘@iäå9˜Nî©oäc%mxXÆò³¤e&;(\æò”©<Ô*HI1–²¤å,m™½\êr…œä¥¢ñÌ#D³ÓŠ%qŸ0ÿdS›ž Q¼ùÍ&½dŠ>ƒ\9ÿÖ·Æ5,x&"¢y„i6 šŠ4!6µ™Mn6è›àÌLÆÙsèÜ›:¿ÂNhJ“šB±f=osO|꥛û,C8]òO�š“ j3(›ÚùÎxÎŽE±ç=óiŠ–A,Í(ä6*µŽj¡îT¨<êÇ¢¢a8)E,ê–¶´m/�ZLc2S�.ô–Ì©ìvÚÓ‰üT+AªÕˆZ;£®©5éoðÕ¦šî©m�TcòO¤U­kMë1�׸«eUGåêM‘øÕ„scmŠ™ú –¾‘Ž­ƒõ�[ 0Ä&6®rUÉVá©Ô1âUÿ¯—ã«�¬bVRM°„]«a«X«1¶±t}¬M—jEÉ¥x2`mk7U¨®¼³¥m7ËÙ¶’r†ŸEìbE{džԮ^«je×Z×> ¶‡� mk;ÃÛâÖ³¼õíoK\È¢¶¸?Y-reðZOÅÖ%Î�­m ‡[µN÷³ÕÅUãHò‚ nW]VHñ‡?ü„‰G$@w§Íâ}³�íÜ`ú¶¬j䟼BQèWGئp…'ÂÝq¦˜Ó…dåÞÆw¾TK§²ì‹_ýî�¿þÕ€e'à#¢ÀÖH‚²`ÞZ2Â>¢…-€aÝi˜ÃYóp¬@ü?‹�¾&ÿÉ}óë“ýÚ°¿øo6ìÍËxƒ4Fˆ�‚ãÏêxÇè±…�\!_®Ã�™Õ‘ß—ä¥-9Y'~rPT,e×ÀŦƒñ€gL5“¤o` t¡é'æ[òÌiÎÁšÓÒæ½½W€E‘3²èœb®˜Ê-¶ò‹±ã?7-Ð#t¡ }h?Ž™ÌŠ@†93dVnvߤ�Réc]Êw®á”«†+—!Ë¡vZ—M5SŸz|ˆæ1«]�XËúU´&�­Ÿ÷Á”É qòO„{Ú^çyÏÅö–]ãc7-Ù`@5UÍêún):ͦM˜ë*j[Û'ØvŸ¶çÜdûäÛšþuÿñ0WÄ�1¾^6H©MÝî1¾Þ ”·Rè{£fÚ‘n ¾-s›luÛ é¶À³îMë¹ÓG8DN^†Àá†^vªÇE�Ã]Ñ üÞøBî¹Pë”áØ;4k¸øý þÿê¤�„õUI�A_Úx‘~ìâ£WŸ‘ÓßçA�×12¯xu�Oj�Hú.êu´#334|µýöä•}y�WûþÞ¾¹×0ï}/Þ"ß#è?úIŒúxJ>?b>¶R5UóŸ@ŠéãƒêË»ëûªìÛ¡íûªîë‰ïs¥ðë�ñ¤òƒ¤á?¾¡š× 1öû›Ùƒ?�?úã ûû½ü#>áÁ•ø?½ Ài²$\+3ì ¤>÷±>½Ã>+Ò¾ ¬À¸À`"#ñ;Ìs¤D% AÇÁ z¯ÁÚ©L+Û#ÜÓ½Ýïûû¹ä(’ ÂÜ ã³ÁÀÁÿø9¢ܱ´‹�XÀlšã#B$2ÂíCB%¡jBxBSŠÂÕAõk ,„¨-ô�.´¢/Ô½Ä?"Ñ¿Ž@ÃâSC´Afƒ08ŒC›ÃdÀ tÀ!„À"Ü¡�òCð‹#A$İ£C0? ¡ÂDüŸE¼§F|D$ŠÄúC¬DÜ?ÌĤYCN´¹D³!P ÅÞIÀ:BÂwÒÃ#b¢�:¾¢øCD tBòó!Z*\›¦A\d«ºËTA0œD2F3ŒAþóˆb;LªìÄU«¡f¬QŒFRœFS|§Èú*l„(mœ¼àFo,‚ „ÂCØŠÁÓºúÇ€Ô ;tŸã›2^´!¼:¾l=“kÈVL¢W GŠÜ‹lŒ„(�,ŽÌ&�äÂøÉÄ x ;àÛ”LÉÀYÉ�hÉÀyIЋɛcÆf¬Éœ¸IÈI�LAíºŸ„(÷ˆ'‡dÂoD£¬H‘èK¿\Ê{jJêyÊ0ˆJGœJH IIÉx¬ÈñK¿ÜÊ“”•F#—ŠÂ9™!š|FÈ÷aK�€Tp+R�¤Tœ°Ô*ÍÔØÔk¼ O5/ý0}ŽQ�›OÅ3MS5eÕfuSPQuÑY½ÓçÈÓ¤y/%€Í {/` ÖTD¡Qú cEÖˆPVfÕ´)ƒÖ�Öd¢Vkµ¡ÀÖOåÖPmŽÀ*œ|�Éÿf×T-W8Q2"!u•Sv­SZ}W[ÕÓÿ!ØþP'- ¬ŠÕW†UEˆ* c-$uÔ�mº‚ýN�@Ø\RXauXmU5òV͢ض ×8ÄØlÕXŽ ÑW]×mׯ¬Uµ¹U@Yz-K”›2–å —MZ˜ÝC™½'šUT›mTœeU­5XŸµÒžÀÒ ½Œ¦½œmíVQ%šÄ"�—%Ћ=Ur%Qs=¢úØX Y;­Z’E”| ¾uR•m˯ŋ°-ͱ !°))m:Û9MÛø&%5×V�2¹0XªPÔýÙ¸ÕÔ¹•‹ºÍ�»�Xæ(š½EZË¥NqÜŒÜ�mSWMWÿ8•Z:MÜáD©iÜøyܶŒ\�œÜ¥¨Üí ÖÌ}¨™Šš•�ˆÝGÝsÒ� Ó} ÔUÕ ¹Í>¡ÅœØ-Ú¼]€Ú�›¾5UQÑÝ•»ÁEQà…U¥�U‘uWç8Þ“t\±íÚ”åZgõZ hY¶ê[}�ÞËØ)ÎuQÏÕÞeå^M+]žÍ‰ÓM]¸5_ÖE_º}X¼•X½E,¾`‹ÍÝùEÕ×5¸ûíØ¨Ù©í_ÅýߨAÞïQ^�d^'�2^+–Þ¯ÑÜlŠà�`o ÝÞ}ZIí/ ¾'¤Ø`òíàó-Âôµ[¢Å£0u_¶]ß”ß1"¡X¬âya¨Í_á¥Úÿâ�‰«› Ö¾Ý.àé¬ãþaŒÞŠ2$rà'Þ\ëE[ì… fVßý^:_‚ßò­bNÝR–Ýå Ý.†_öÌ¿]á1f«2^âî-Üà•áá F6Þ 7Þ 8¾áNÞLöÞå5à&îaÛ~åkäµ#dð­^%dÓÉÞ$Þ^P]'îe(Þ )~äÖRIZˆeßÕÐÒ�R•#l¶¤Ý‘ ÷ð�n̾ Û¹ƒëš¢‰/£œãCOb#š’(0ÒaÃkÆæê[ÚÒùäµÂ!(�%>Ö&`Æœ+‘¹/8h¹ˆ'küÍ"˜¹�H¢‰žhÿ›8h/�΀% !A„¯k§úd j.œ3•g%ÒfÝyhÙñ oÖp¶8Ó1r&sæ-t=u67Q# w&éS5i çÚ�ë-Q¶2Vcåçµ!Ö€î\Ùh‚6ƒFè¸PhTìņv`ˆ^¡è°hŒÆ �^Âx»K�«li×é¹)i &Ö#Úæ¸(–î�o.—îºqæšr&¯sœt¶Íu^€vÞ Òqkyj ê€^Ó£Fê9Uê… ¡¦~j Žê%™jª¶‹NèiZè²vè¹.Dúêƒë¥k@dè×4€³Þ«´~¦�žfÄ9ìŸ~ë�¶"¹¦ºî‰ÿ–çÄž™^€šþ¬›Ö»¢ìÂNÛ^a VlƆj5…ìȆ¥~þçÆÎ©6�/éì«þì¬V¾­âÑŽE;2í‹Îè ÈíÁ3ë�–íµ®mŸvn%2Vxö£Ýîíøm¼î˜îâN¬ã~§¢Ø).óˆžnëÛÎ!ø€nÝ)j¥n•ì1ªììÞîèn«¦¬¾�mÞ&mBoÔV Õ¾kŽvo´µn ¶ÄÆ!ûNF8Êï•öm»viÿÞkèkçúë¸áSŸ0ðs‰‡ñ¿¦ÛÈÑ¥vÕè¾ìé–p2 p+²péèÌ> ÷ÏnÐNqïêC qõfïŽ~ïÿ]�÷inxá�šñ}|KøÐoþÞüîÁ &rR!ï‰�ºC�(ÒAT$¡"‚&_Øz~ðì.)ŸrënrÊÆné>¥‹X�š¨j.ÿî6ô#üɟؼô�¨èÓ.s²NñÖ~mÊŠí4W�5ŸoxÓ°7WÔû¾«¯šóßïnhûï<Ÿ=oKû)pˆôŽôÂ!ô#2,DïÐ&_ô€p¹{t*G"+‡rK·LMïrKúô umõškS_í²Nu4ŸmÆxuŸ8Y‡(8@[¿\7�º.¿Æ;÷õ¸ÑórÒaŠ?/EÂ>v²t¸¶!f¿ �öF—ÿj�ôÉ¡k?bÒŒmïvNÿöñw‰uØ(÷Rëõ>õœS÷oñÔpw$‡wΘõ9eÃP«{Çœ|ßw†íwï€G!�/b¿'cçdŸegxÝê eh—vƒ›ø ¸n§ælO€�çì §÷¿qÇzrs7y3WqØfqøvu÷as+*½¿‹÷{š÷iªù[¿ :ßõþîõžçšŸŠ §ž¡×¦¢ßˆ£B‡Ò†¿Œ‡7Ö)ut)¯ö#ºx2y¬Èúðn¿AOÿøM÷‘û’Oí“GwTÏUÏmbùÆpù¯!=·‡{m’û {{·û\¯s~ßñË‘éÿ_‡ž`×É�ÿ‰‚'ȃ7ú„OvbEü¥Ïž¦§c7}òm|‰|НpJÇöeªü°· ŽÏüN—¿¹é|°ÿü±ý²Wù³Wý±ð¥–tb¢ÁÒ0¨Ò¤èÔ"²üϤÈYEŠ„(hЄà𡉈R¬Hàâ…Œ!rpä棠� F’4`ò䊰liÐ`�˜2#ЬÙ1GÆ*+¶$ GÏËŸaþü!¹ ìW»t™2} •'K"‚æ8Iâ0‚ÄŠñÿ2nì8¬Ý‘‚'‘Êv@Ë–X±ÊœY“¦–Т �.mšôÉ“6V³>] aK•O¾,˜0áeˆ~s;”šñÂÆ›fC м µÉ”l3³¬¢sÌÏ4oæäÝÓ$a¬Ci=š)ߥNŸF½Hµ„Õ›XµVéêÕñزѪÍí®A¹tí2Öû'<~­Ø“fbŠ%öƒ G™`–-ÇÜfAA׃tˆ6šk§!gk­�K²ID[m·!ÄÛ²è›Fr�$Rd*·s8wa†Ô] Sn×��PDu7Âwà…7ÞD™WÕUA±çW�Å·�YôÝ0 [÷Å%Ü~$õGÿÒ^á¹H �?!H‚‚ 6øæ˜vAXÙE—åX!üŽ?~Zä“WNÚåឨÿ9ç[³õ¹“B)ÒmR 8]êJÄÖ!Íu°ûLÓh—/Û1åkÛÙ]Õ|§µ�Œx3{’W¶Æ\)m!Àô,"½ÑynÖƒÌܘ¢½ßp3Þû˜B¦¬ñ‘Opæã€áþ§>)®}¡�_üø4?×ÔÏ”+ƒå¾¥@›íÏ ýã`ú°Ø¥ž±0à M¢:¶Ìi^´‰ìœV4}¹jjTâ]¦Å¬ªxm<ž¿˜‡6[�b]Z!õøs=ŒÑ� é\޾—C¿-†‡�)߃è¹!R¦ˆ¯;")Ç%Òo5’sâý^#ÅBéïPü©8GЉn]íI 0Æ�”±ÿ6‹ �r©Ëzj‚C ÕßÈ;96©ƒ¬B¬Ü£Gç©-…ª$Å Cìò�þ³af©Ã‘92N?"ú„h‚õ­ÌˆZȤ&yGªù5ñ‰Q¤ÙucJ+¢òš9Ê®pÅÊz¤t°DZI™›Z¾ä–ZÐå.Ó(A6ZPw¬1kXÇÞ1aÊ4ÛÖǵý?Ó‹&I: Ò‘ k)Öœc޵¦ °´¥Ýôf$Ã9Éq‘}—�¶½Ëm‡xÈಸ�i8•›ç,K@ýQÇ÷Ýe�·¼÷»åþîøÞ“ÁÓ˜s4ëZÿ$àËø›%ç #ÜΈ*v‡��—ßB|Ä/1ÅOLè‹K[ãÔæ¸_‹æ6ÿŽmÏcà k˜#}á‰VÍÚÎvœÓ€Õ>"fÿ8UÌŽv³ß™0ºÕmÛôöõ¢{%Ì‘9|Gm÷Rã=¿z÷ßýcÞø\0@ÿ‰áˆøÄ/¾ñ8z¼¿92ù^›õòµÉ¼§7ßÏ0t~ê¼}FÝe!Ý+¦gꇢzÖ‹S"f—±ŒÍ.û‘ÓQ¶¿ýäƒìž’õžÉ]äÝD»Ùcß©_òAÀßÕ%ý\¾ÝDôuÐôý[õ1€ã šm•XY`^§ˆøyÑG”_XxúÝ�è1éUÈûÁIüÑÀü5@ë™ÀýáŸè_ÈÍ^ÈÕÞO`’[bô•¹ñ^nüÿØ�ßD¡®ØŠ1 ^8 ©A`Aô�._:a áAŸŠ^Ï$^tàA&÷5�å™ bS š ‚… VHè¥ÐèaUXmF ¾É æàö þ¡¶©raw ¡ÿ! àcà VÖJaR¡rYaX`!–iapáîÄ%Š!^JßR_m0ž^fŸä¹á’ âK®`o™_ò¼ úaû}�û‘ÅéÅ!R †œþ "zWŽ,bßÁ",öŸæüßíI¢cPâÀ%f¢&râjãW€¢ñíÝ*Ÿ°q×)ºÚbà*j`+rà+Zߥ`?¸„Ü•xßK€_ÊèÈÂq^/¶àùéaúÅ`fÌ #ü!cm¬ž*£!æß3V@4J#52ž5¦ ’c@!ù,"*°üÿHP €ƒÊZتá©SŒ"2@qÀ¤I´�iÔx+‡G�tBrÉ‹—¤“’ ª\ɲåʃÉ\(«a«‡§"é¬X1�OL@7Þúñ£•£•’ZšðϪ§6gIÕ‰'EWX³ÛZÔ㦯8‰5A¶lÖ¬ÎÒ~ÃÖ–Û_pUÉ�;7ŒÝ»6mF*KÖgž�Éo-ƶ°¸ˆÁ„y÷®Ôdzøöõ™U™e<˜CÒÉ)1\— Ø@ú©éÓyâ|YjêV|bË>JÛJ×Û9Në6m˜mí£(Q‚³)M›%N¬x1ãFd‹jæ\2øðëØ”yè¸êœ;­úÿŠI(Ñ®´“VZ:¨©é¨SÃó<‹uðí¯›ÂŽ•LßUZgkµõV\tÑÕ˜]¯íÅ—_€ ¶Uo‡y&š†ÑZd’ùUÙe™‰4’g¿d7iìfâS«±ÖÚk²ÉFÆ‹0âÖÕ‰§Aø›Á�4\q 1¤šr<5÷t]MG’I‰¨$KÛÍäãMQeÕãÅÑyE¥§S ½×ÐcRZÕŸ}]á§ß#’™Ðߊá–-ˆhà� fèSƒÉ !ˆVxašbe™2˜áadgž-I"�»¥xÊ…,¶ÈŒ1Êø£OÙø[Ž)�ÆãÞA $s ÝG‡V—ä’¬jww¡âÿ&OU–wå©F!µe{]Bõe|U‰I™E™ù�XhòG›öfœrÊUa� Þ©Q`y>ØŸ¢ùÙ ” Ê¡¡"š˜¢¥aJ£fšQú¢¤“ºk饘jZÛ’ŸÆ ‘DA–ú®9¤Š¤Ž­ÜdwOÊ*_O?Y –¹Z¡{îùÚ ˜ _5,We‚uì~|­©V³ÂI`´Ó¦¦`Y ^ë aÛJØí�ڙdž„v¸Ù‡‰*¹¨º'²’»dÜFô¼© á„ø"ÔcM?òKªsBY®ªÌêÁú‚,­ Ûú0À9h¹—NYŒñ×�Éq±Ÿ‚lš"H²›þ­´tªÿl3žzÆœXŸ4k3Î… "º%m¢ÐtÝ•äó*ÝÓJæ›ð¾õK5GVïÌ Ö�jÝôb4Ñä¨ÔT†mÞ©0šÍ{»]èÈí¤N¢Õ`oä(Utcõß{z&çÈãåwµ~å�-¶Ä³%ˆˆUaý]ø=6÷d7‹›3¹ìª­*Ù‘ø³ãOANùGë{¤Èûð[næ"jµ¨¬[äoÕÒ]=p馫ŸhR·�ÕuŽ"µzû^$»Ù ¢v­¹�#r·;ÞÝæw: ž†çŒâ%æxÉCÐòXÖ<ç=/ÑÃô¨÷ ëU{_ÑÈåŠA%Nhâ;YùÌ·ºP]ê“×äÿ„XøÁoB»YšhNgœÍ�Š"BúWè¨ó¿ž&”…—Óº<�G�‰�®Î6;BF‚¬ïŠqÁOYžÇ7äÍAyyY÷ürB¦¥0+¤ž a¸ &Ë4´¡Î4“C½Ée‡æó¡õ€(´öåÀ’F|u£ÄÅ0ñiÈáõ÷9"õOt¤³bæHÀ-2Ì‹ ì8F>P7¶Ã/RAbùÎ�„#;(8:ÊÅŽxÔ‹ÍøxÂDƒ´Kö¤²=D†«†ã‚\#çII² ”d—%‰æ…rš3“Š˜�:× “O‚ʉù‹"ÿPå?ë¨2;Ê¢+èÿº[-� ,#.#¨KýéN�ì õH´ppŽpY„D'ŠL»På¢ËôI�¶ðzÒŒ!5gxME‚�‘I_7IóÍp¶‹ˆÿ„‘9Ï™IvÚt‰«@ï—œxît§¤¢=ïy�|¶2E¬K ?ÃHK‰íŠv=cA/rPW¬‘� &CÕ$¼‡3¢•hEÃpÑ7’°yý£ô:ÊÂh†aš³¨f"³‰Ã”ê;<ì¡$]:4˜2•R3-':oJX,)°^H…b‹‰P•ªµˆ¬doS˜QX¶$¼(X6ËÙÎnVNœ‚„hGëBšKnbñËc/"YÉ�м�ÓŸ¢:ÿÍB‚%4áódY€Þ† 2:aÄá¼7(YʲÈMn–ËÜ4)'"iZí$ú8ÍHT=•@Œ¶Û5 J·�ÉMîD1‹Ù{¢³BèMï]›€öº—¨­BìbÛSFH·µ‘¥,[,;Šò¶Ê³hs4ZÒZÏ´qC–jW‹ßZ¼öH±-ÐlWQÛGI·%ì#o}û$àFB¸ÌÃYq�{‹ð"—¹Í•ÌsAÌ—ïž°º!¹n#·k€îÞÎÅÏ3qÆKÞÌÂw V¯zÙëÞöþø°��¯b‘ûâW¿bà¯Y`Ï88mirZûÄÉ­}ðèJ"ÛIÒ¶€¶Å0ZO¸áüÿc,枈-Câ›ÅËuîs£»Zênź‹À®v¹»¹Sx·Ï'Ô1�É{d�YÈè%r‘-"ù*™Éöeð“»RÙË–D³Uæì•Q’eHlY]Ní—5fwÁ¶Ìà<³Ó|»Üjx(½us‡á<\lJuÖqnõ¬>?ÖÏÅ´ áBc;ÇØR´D{ìã#‡š³ºöf)]0KÏÓ`ž,§÷ëéj/IÛ.Ph³|êT?bÁ�m°˜1 kÓTø1jfænqÍáûy8ÎÖ잯5Œ‚<·ÃVñž%í—){Æ„æéC}ìD›xÑSþ1º7îYnÇ7É—®o¸ó;î(—Ô×ÿõIJÝî«:#w°«!\oYãßµÎ0›ù­kó:ÄĵŒÁŽðæ["Ʀ*²n×_4»ÐWºÅËñO7šãX€ÇYåíÅ®8æ·á/ˆn•K¢ÔúLQncN4jË©Q)’`¾5zÂ\çúÍñxn-ô¡£èFW¸rÕðd@NÆI¡1�_ƒ“¨_DÇ:¦öÖ³Îñ­#y¦JNÅ×Y-ݲd×6¼Â*Q´u5kç|dÛÞã·ëÆQrÏùšŸg÷~Ã'ïÍÔüþwÀûäè!<¢Ÿwø@«GñÛeüÄo¼ZÈ›Xò§üÆ-¯¤®+vóñÞ´ç?úk�žô¦O�ÿ£RŸýVSÊí‚ûjbï[×½öxŸEps¿{¿ûþ÷‚—ˆð+N|¡!¾ÈgÊghÌ÷XÎ^ÐÇmÒ‡nÔçÖ— eõaÏÕGµW¾p�øy£Ð}œE4ßGz¤—v¨§s´W{Ø•ÔÖR¯w±GäqUóÇ<~QCwyP:¸ƒŽ²TuŇ]8€!:v‚•�€”¶€ÚÖ€-ñ€¸bX{˜�ܧ$ÖMá�’‚ (‚8á~%hwH˜‚{µ‚ëׂ.ˆ 0»†{4è6Ht¾·ƒ<؃«/@èÆ—xÈG„·c„&V†=6yLjNÈPXVRø~vÿW…¨�çæYZ˜\Ø"^‚§†$ˆ-Hˆä¥‚§{jè‚mhw2øaôg¼‡ƒv¨ƒx˜‡’²‡ìòC˜�ˆ½q„'¨„WwˆU–ˆ+áVø¡es¼ˆ]r2†Xø�W…l¹‚p¥0‘ †Ñvq‹ð&¶@orá^Ma â8Ž‚}Ø2bdó§u&ÕT+¶b�òØôX�7 ø˜�¢‡èqìñ)»ñrð‚„Ë(ŒITÄøÆxQÈ8ˆ'x�.ÑŒ�õŒ_�/¶¹F4Õ%:���!mÜè�ªŽ 1ŽäØæèh)ëø1ÈrHîøŽÊ!�ò9·ÿ‘�ùX!ü˜%þ¸‰)Ùð"‘ y” RoÅ� �^Y ÌèYÎh‘ù<ƒ±‘îÒ‘^’É ’oB’&ù()Žåø\R— -)#/‰Z1 |ïh“ñˆ“]¡“øÈ“³Ø�Vð�N“6Œ2”EQ”R‰”„©J ¹ IO™\QISÙYUùŒi"�½Å‘"5 Öè•`ébÙ^áX–g©i¹–¸Ñ–1 23I“!—@—Ea—±˜–B|©S½ò—B�’b”…Ù›¬r˜‰©‹‰\�ÉM A‘3e‘›0™Y ZI)\Iš©�#Ifßè™' š*‰–qŽt1“)ÿrš� œª)èš›²)#´ ”}©.홂阾yŸKœMyŒªW ɨ¼¹ÈiNÊÉœX©‘•¹•—™™�’Ô–ÖY’ØI–Ú +©–ß™Ž^7ì(æyžŒ�žB““v9Ÿ·ñžƒ”¸ÙºÙ"ŠŸ0ª­à”Ñ 8J’õŸIñ¢ÁYMñ¡Å&”Y–ùŒ ú.“ Á†\U�&¡Eö™¦WØGUè˜\–â(ä©œÊ /"Ê.$ª“&ê(Z›0!Ÿ¹I”±Á_>£p:4j£�¥£‘Å£•ð¦@¶YAj‘+f Ø’• �™¤ú†-Çå¤Û¡QÿZd:ŽVÊ��•¥Èe)»›^j‘`Š|êé칦¸q¦ð¹jÊ¢lÊn:˜qºª1§üY§@±£©ŒªÚ@šBŠtDÚœÏ #Êi¨t·ov¶c‹Ê™ê¨ @¥‘*š«E©}`©º�©™Š›ªx�šŸjª¡ú“³³I+z-šªöɪä 4z!Òe§µpUð²8Çɧ¸ê§ ×b«%¨Fª Hê‘ר L:âU¬Ýx¬Žª¬ š"Òå¬ÐzÒ:­›P­4v­Ù ®îÉ­hzy¥.ájYzZ®¾y®­‘®±Yì*)î:‘ðú¹ ] W¯z¯„š¯]ɯ‰J¬P:ÈÿJ°…$>x+#—j— û»]×€eZ6;ª0q±By ²!®ÆÉ±«ê±�²˜ Y#Û"%k«'›²gÒe¯GzZÒ)³þª¨5{�Sš�UZ°«q°ª¥>­@´CkE‹|G+ª)*Lû­vñ´[«R‹Ÿ›?°‚f«aVeqkÆu#Üè€ÊÉ~Iw–�¹…qxÖ†gå Ö?•¢µîU!Ÿ›"´Ðº®[g—(›Û!vdGˆU!•øyµ#¢ÁÜQ!ß`…˱‡û>‰;k‹L|Ḳ¹‘;¹ÈW i²²�•¹–°¹]ѹ«{ ¡ÿë£KO¥‹§+£í¥ºŠë(®ëºFã.ð2»vY»Eq»½1 åÄ»•È�Áx¼þ«É«Ë»P€u&½ÜH½Šg½×[Ò¥½Ü[Þ»¾¾y0¾ Aå ç[©{ ß‹íÛºïK)ñ{ ´‹)·a¿†�¿^ ¿ZÈ¿ö¿4¼§ˆë$Ìk�œ ¹ÐÃ>ŒÀo¢À4ÆÀ ¶«ÁlÁ¹xö½ŒÁ£Á‹`º�€ºé ¼XÂ0Rjò«“ôû,\Æû£Mh: XÃ4À¬U;ìÃ?ü‘k B¼]E\Ĭ¹IܽK|ÅM¬}O¼Á¿ÐÁñÁ�‘ÅCD)\ÿŒÂó«Â¶{ 2ÆqÆZCÉh|¼jŒÃ¼«ÏãÆ= Ä’ûyXÇ |ÇۛǼÇ9\Á{$¾~cQl¾SŒ¾  ¾«ŒÅȧÅ/²È�‘ÂŒ²Â�,’¼§×&ÃÃ|ÉR›É#~㉚’áɹÀwÊpU¸PÍÖ<ʤ|¹“!JŒb†| ¹åİ,Å.AÈYÔ¹ˆ\DSjæË4Ì�ÉGÆÅlÆeŒÌ…«Ì`“E ÍÒLÍÖ\ͬ™ÍÚÌÍ%Wßί ÅäÜæL@èœË‰¼ÅY`ÞúÎ]�¬òÜY|Ï(‡ˆøœÏpÃËü½íøÌžüÏkÐ-—�½TeÐE! ÿ]BâÌв\ÎUçŒgéS»\ÑžuÑ'r-Ìó<Éý_KÒ¬ªÏ›ÈÏ ìÏ|Ð=Ð/]ð"Óm‚ÐW̉ÍsÓ€,È´|=�b?ýW]`}SG½o Ç –ÌÔõìÔå Õ̼'ÍTýkVmÍX]Çkˆ [݇mß\–¦0/ãœÓ½ÓgÍ\i�†pÙ˜ÍÎCíÖŽ:!q}s]×TÖÔx §zmÒÎì×)]Õ+ÍÒƒ]Ä…�Ø€$)4ýÕÁØŽ�Ó<Ë,ñЩÑŠw˜�ÙBÝY„õـܡMÚXÈÜ¥£\C@ ˆóZSrÝV.Í#]„ÐÝÞÿ e…1Ü—-¼2ñ‘Ò"P¦£•» i»q#{sýÜô §Ñ�:Ó}Q*ØÝß ÝðFUÞýÝÍâmä}îü=Ù&êMÖX�ïýõ}á¼1�áœ8¤|áߨ à«öXÞÝàmàâ�à ¾ ~7ÎÛÃÑÞBVá÷’á8žã¡±á%ý$æÝûâ">%$s«uâ„�âbpà,Þȧñâ9P1^0nã´¡ãXŽá÷Ýá?äÖ=äÙ�{عJ.'Mîź�4QÎSÞ*U®ó�år~É[îã]^Ýdæa‡y0æxVæræù¸j.åI±ÞnÿîÞpžÔsÞèt.æ”E\Þ ^žçz^Eîç(èt!èøHèHƒ„2\!ÈçŽ~ê;!‘.é÷s{�‘&—ŽébŽ|d^àb 'Òâj.êö|m¥Îè¨ì©éåÄê­þ+�ë±þß³®xµ>Ó½�뢡ë¡~‚ÆìY¿ÎѾíåªêÅÎê¯q!ä¹ìÌÎ7¢éÌ9(í‹AíE‘à¼^ÉÚ–íœÅíö¾ªÞîÆî­AžQ¢šðî´Žgêþyìîþðní½jô¾m÷>ñø™ïûžâ~šÿ~ž?ð¿�îËuðb—ð±ðÑðØuí�ñZGñ.�ïQ!»ÿ‘ERó­á(x#DC4"?vž"½›à½K?/_ô÷Î2ódóL? RÙ;ï.D�ôämêFŸõÂŽô�¡ô©Óô6ÿô­ÎQ#S_T@_‰ ŽõZßö�Îõwáõ41áõeÿ"g?‰Yçö|¿íì$÷ A÷�¦æw�÷8%ï{ß÷Šïè¯Y$øBFø…Ÿ÷Í�ø‹ùsNÔF@�¯^’O)È­ò �ù¤¯ãšÿø��^Ÿ#¡ÿð•Wú°Ÿá§Ïù©´@M­�øXû¼_ß’W¨_ûÚj)’æ^”/"Ò×ûÊ�׿ÏC½+ü Jü�•ûýúËýhÜüæóüÐÿ/±óRüíuüÙ‘üØ_þø `ßÔýw€Cøæÿþåÿhê€lÿöÏûòßýôì÷$XÐàA„ .dØÐáCˆ%N¤XÑ"€5nÌÆãG�!?r$àâI”)U®dÙÒåK˜1e6,YÓæÍš3uîäÙÓçO A[â$Z”¤P¤I•.eÚÔ©@£Q‹>¥ZÕêU¬W¥nµ™ÕëW°aÅVäZ–ãX´iÕ®­jÖ­I¶qåÎ¥Ëò­Ùºyõîå[ðnÙ¾�&\Øðaĉ/fÜØñcÈ‘%O¦\ÙòeÌ™5oæÜÙógСE�&]ÚôiÔ©U¯fÝÚõkرeϦ]ÛöÿmܹuïæÝÛ÷oàÁ…'^ÜøqäÉ•/gÞÜùsèÑ¥O§^ÝúuìÙµoçÞÝûwðáÅ�'_ÞüyôéÕ¯gßÞý{øñåϧ_ßþ}üùõïçßßÿp@ 4ð@TpAtI#”BI*´ 3tP½ ;TÅ 3ÄpÃô<œÄ E‘ÄóL”EIT„„Å]¤EmÑqGÁ³ñFsÜQÇ¿ûñCU’È"»ë�(£¼eJ*…²I''ŒRJ*§´’G,·ãcL2·„²Ë)ûPsÍ%mùåM8ÃLŽ$+ê´“Ì2ÍDó–5Ù\Î8å<ŽN;ëÄsL3éØÿ³O5ÛôMAw#iJ+5àRLí£N;ÍåSPiuÔN 0U T+QÎ U‰4·I+¥ÓLíÔSP?•TNM-U1T­„U ]}õ¶Xe¥õRMoå4W]w¥¥ÔSS]õÍV�E–#Yg]VSÂwrË•vÚ^« öÚ_²Õ¶¶d-]6zëwÜrÉ=—Ú_­Ûbß…—Ûn—5 ^{ï5!_}¥åXa‰…ÄX�e#ÉŒ36az^˜á}ÓíwÝÛ ¸b‹9ÊXãy9ö˜áB.ÆWˆÙueØ.^Ù”�]Vf™iöWbŠqvMç•QziŽóxd‡E®¹ä›�>ÿM¬³igS–fÚç{a®el²à‰­N-k­CâÚk¥›~:_²Ë–úl“ÓV;4’ªðûo®#ß| 0üpGW\pÆ#IØ©…µ¦a„qo´úþÛïÀæÃW<ñÆr’%¯�ò-ó±4ß¼óH/7tÃG'½ôÓ!VuIXÑõÉaKvÀwfÜvrq'@wGí=rU‹°uâƒ7,’6ñþûÒg~çQCz3ͯ|õ—ÖÏ~{î9úüð=ÿ¸pÜÍGKõ±>Âì±~YéÞü6¾¹Ý.¨Û_”ú'¡™¸�xôJç‡ÀŸ1Ì|úk ÿ¡b�x�úŸbAú‰/ƒùÚ ;øA…pxÙ#¡ �òæÐ€,�Ç,ñC ¶r¤Ã‘dÀ’°†6 Juh@ Þ ˆA"ªU¨:ñ"òE½XETqBŒcTâ£.ÇD�8‡;Œ¢¸¦øC0žÏLX´‚-ÂE/v1Žc$cátF4Úe#ŠøÛG¾w D./\“`d#ë6¶DR’d d%%)I5þá(AžßŇ=ùÊWÎ*†¦•Ç.¶©C�< Gé7Cz‘§P¤ éÈG^2’•´¤.3¹Iˆt² Ÿ ¥( @JSš •¾På„XyWÒ#‡L¤ýnÉÈGÿÖB—9à%%·ù˳p’#›ó䡊)Jd2ꔨl&ŸI–AJ3 Ô¤¥5¯™Ímv“ ƒàg?;̇“˜hºæ$Hy®uæ±� |'E¢ Ëiʲšµ[ä=s©K}öÓŸ¨CjN‚^ó Ò‚V.öä¨G5Ô¡ñ„è<%ZOŠÚÒ¢uËg75Êφ3˜ã$ç@»TБ'ýSJU*WŠd–³ôX#‘ñT²ùJ’‹ */¬zÕ›"§yˆ"¼J’„U¬ŸlZA�FRhí)J;Z¢lÚÚ›¤†d©ˆl*#ŸŠŒ¨šjªU½ªU³ºU�tÕ«"«X›VÖkžU¨iEÓZuôVØ@VÿRƒTê\ë:‰»æµ{]D_ýzSÀfD°Š lakpXŽ™j‹Í•Z¡ÄV£²¥€N\A2×S\6³c“j$©ÚYÏþ•£:eˆWIÓžµõRm¾Î5ÔÆ¾ö±±-MVgëGÝØö#¸Õ-Ty«Wßòµ¯Â•�gy1ÚÒv¹ÌMìjGÝ.9ÖMÔ%�u‹êÇвrµ¬ÂœêÝZô6¿5/y#d^ô"×´ë¥WsÍ…ÖÖF—°¥meB[/dXÚÚÓïØ¨”iDòÄ-ÜÑHW¤8+ÆC‹�Y€OÆøPmjS†þf\ãn³�ájZøLlâr]BÈwíÔ-tI&a]•¡Žÿ¹0I4¼aFuØÃ’=ÚFFÜÒà Å*f±‹�)c0ó�ÆK²±ßpìU÷Pa=.Ý�áä!?µÈGS’­ºäÆ4™#OÎ0‡Ñäá’�86¹r¶;WoÙ+NF‹ñðâ0ËxÌC*sάˆ4«ð^lnœ›½çK™SF¾$’U¥ä>æÂÛá0\ýj)ÿŽÊ­!4‰­eF¦xÑ]~ô—#ýÉIï¨Ò² v±wì1pšqž^¨E] RKÒÔ•@uѳêeµúÕ®ŽuÄèûšZcùÖ^S4£ éC� ØÁ¶Å°‹Mìc{LÙ‚KE½í dr 9Ôr5�ù`g^àùÚÃÝÿ« ¸mnÿyÊß®²ˆm½ÔDçšË�ö²(?©î³ÛÝïŽ÷š9>{ßûÍùŽ32æ\ê:ŸúΩf2Á5bðù!|Œfôž~;ëÔ„ÛÐ)v–O|Mš¯øÅ2.c»D&acèoš‘-®¦,äõže³v×»F;’Ó®6d:DB˜OæAO†Í©ŠsÔèü#=wAÉ>t„=ÂGSÒ!±t¦w|Ó“úÔ«®4˜aý©ZÏ×WníÅ|ýQa÷ÞØƒnöE ý4jç9±}îö Ã}ÛrÕž�®£�ÛéOO6ß—5õTü��<á p–¦£P< ¿ ÇÓò’7 åÃÿÀvˆ+ ó4/(Ñ!Üy4}¾ÝJ÷Óe¡wq�BúÓï{ÈUÏz¬»>åÔ>óóÙ}‚@bk$l…Yª%2šsgà“>£!9¼$ BÛÁùÁ4¯61/‘rª‚D13Ô§^º$z¯©]«¹)‘$;ñ¢±ªÐÁìA.… B4ѧm:Â$\BûiÂKxÂ(d*Ü+Ìœ,d›-ŒD/\0 CÃ2„?ô&] ÄHDz)Ä£D¬EÔF<¡RÌHäÂID"ì¦K”…$T‰º'd4(”Â5 EÅØ©F¬9E.LÅ*ô,VlErzEX”E†¡Åp±E\Ì]ÜÅ^|<¤—`¼„a,F2Ø&dTÆ<`Ʋ;ÄHJÄT’FjDv€ÿkB>3Ÿs�B�t†nüFMŒ)NôDsTt´u G4Å ‰ÄQ€GQ”ÇyÌ¿¿±Ç3ÄÇ|ÑGàGÜ)©œÃ€È<(ȃ,F…|)ATC‡tƈ„Ɖ´…itŠ–´Æ‚€Él„œŽüH�Ô%LD‘ÇN$ÇOœBNˆGwbÉ‹tÇ$¥=YÅštE3�ÅXä˜YÔGŸ  Ô¥­Ù;È_D£ìC¤R-RiÔQT¯ôFÍ”ÐB¥PîMï|ŠKëdMVGåÐ-ýÐI�ŸJ=€0­—1—PÝ!N]–µÍ4µO+ÀRÕ§ DÕT•Ó¥ÓedÕ§tUEN�˜UZe”>eN\ÕUQáÕ%õUëVì4TíDT””R•¤R¯8ÖdEÖeÏf-Ïgýžh�Vz©Öp¹VÊVÿZÙVIªO5…pmÓnWTUÕÄܵ‡¼Sv½’¤&rÅÕÏ�™ØäÉ~õ×fÎd•Áë”) 4Ù¼PÚ¡šJ‰ØA€WY=XdeY}„²+)ehZ*IVzR=Oó˜M,·’½:²ÄmÒ%¢=„bûÕ¥¹FÂÁ{1ó ‹¥M�ÚÀÄ·e4~!“¨\>¤PYT}:—}Y˜Õ·œ•¤š¥º›e¤¾]×�E< úÙ㜡íZ£í˜]¡r11¦uÚ)�Ú—bÛ£Z’´Ú.ÉZnÜÚKêÚ¯Ý×°—±-[c:Ûê©�´�¨µõ@†t[L€[‘‘Ûâ¤[¡°[8ÅÛ¼ÍÔÇåÛÿÇ£YdµY~ÅÙàÕÙÄÁÃEÜ“X\¢mÜÇ †‘\hiZexZd�ZØ�Z…©Z‰ÛµÎÅ"­ÝHݯT=±�²Å:³E´Í0µÅÜz‘]Ú�S±]J›‘Üå©Í!WÞÍÛè^ÝÞ ^&ÜãmÕÂ5ˆåýÙæÝAÆ5ÚèêÍëÅÞÐÞS°EÍMßI`Æ.©)^"_I2_}E_ÓU_Ô%Õ­ i]—zÝ ÆOz¡ß‹Û1™Û ݵÑÿuÙÎΙ�¶¿M½À�„ÁN+Xà‚hàz`¶‰àƒ�à–Í—ˆ»¥ ®Üì½Üíu3õ`^ÌIú\6a°Ušô]ßÿ»j_ßY]I€az Õù}ۮݾ݊®Ñ–XZ,ȱ\Ì"&ÔŠÒÃ!VàäåY'~Ÿ‹p^x…^*†™+n¤,¾Ë•aÌ5±/Náæ²Æ(2&_3&]4Na5æ·tiá†_×�%9®a:NæÖ_Î Û!èéã�`C.Y¿^À-^FúåÅ´&&ˆEž ŠÚ¬ÑhŽf£âû‰\\Ãbʵd£Å­ÒdscOã] eÐ5®YÝ-ÝŠ:e“£–©�8~©WΖe;¦e<¶e=Æå ÓeÝáå�¤bc&`öÞ�F^îS@öYæmf¬1˜h–f¸¡fÿI¾fJÎæÆåf2˜MnÁ0Î1a]J’.is–UtFáu¼[QàYe/ˆ_DšçzžåZ®[~ö€ÖÛèMâA>â$FæD6\†v`‡ˆŽhM˜æHž^‹f¤JÎè¹Ú!ŽþfNþhÂã&rÎ�’6i¯:çó…Ý4^a¡!xfåve�ãÙ­cû…±;Î_œ€\6 ]F¶ÞõÝ ja6bbFâ&Ü¢6ˆOz1}Z&Z%„Èš¥Žh§žà4ü@l¾^->Xrµêeéh™êdðg®éKúj’>i¯ëf„²fßÔõ—´ŽéVžé¶†å·¶ç¸Æß¤«ë»žŸ¼N ÿo^ªPõ¿.àa>`Á`„®6::lcJlTZlgjì‡^¦nê‰V˜ßÆ-Ì-¨©6ÚÌÞèÍÆj�g�¯9„IÒNÓNi²6e³vi7†i™>šŽe›ÎgÝîg¼þg½¶f¯Á­àV˜á.èÍ=nCLîÃ[îCAìnRìGaìƒplêfêÈ®E¸Ñîq[îÆhïFUͦÎæ\ÐÞÅE@oÒ^oÔVg™bg6~iÖUë8žmz¶ï{¾i˜ ‰Kc#û�™‚‚ÜêÀ¥ŠÖlÚ¬K²Ñ$œ$g†Ù·§rZ]¢#,MÒɵ^eø$@” ÚLB½D¬[J®ƒfú~’”)¬û.ÿð"ám¢ê¥*s»º+�ô•Jò¢?JÜ‚€ [=_ïAr$·Ã½kȉë”K‚F3‚L¬µÓ×&„q[8‡BM™Û•T ?3�)¿&èI Ÿ%!$"—$#GB?Wò|ardpòBÇ¢(çÊ)·^+_¸7ÉòÜò©ëòÔº&} sÀs7ǬÝ%5ßZ6_Bÿö§ŠsS™ó.ªsD�ð<ßó>÷s@‡ºt%YBF_8t‚PôÊɉzt5öÈI¿ÝJO‰KDZLŸ×O·< õºõH*õV8uÁYr¬cõVµ“WÿÈXoÚY—µ:×r5ârÀ#/o¤^ÿ[à&óÿd?ó°bæƒýω�tg�sJ¢óZ·s‚Às/Øs>ß?Ÿ…kç±l¯ßVïv,Gtpÿ=FIrçøsWÔ¡p%L‡¢g˜‚"¢OG$z�*]Âw}�~¿+_W€ŸKº„™�WRºòƒ¿õ„Ïõ…€†g¤‡æˆvŠ'ö‹¿¤cO¤�_v(ôx2ù_Ú‘Ÿv=¯ö?„@wÈmJ˜¯óo?®pÿUƹyµw†œ'Vžm%•QžúÑt ¿&¡—wí.zÞ:ú=ò$ß÷Tï÷ë}rW7“½fxŽ¡ò¦­zZ{IZ…ÿ±rióùzâû´Ç«ŠOó²Ï�³§¥Øgöpöÿ½‡û� y“§{•·{ltmç”—÷ö�˜y&µù9ÆyF¡t‚¤� �(Úô[z|YÀðS�ü£üX°üY@õ Ó|ƒrÏÿü¦}ªw«yÔ×zÕ}„iýnòuØOß±·ø²ˆž*h0’‰„ 'MB晳ˆ&’©èë⯌’6èèñ#^¼¬*¹jÓ¦Y*g=z¤ÐDž˜®f&«YìfŽœ9¬Xñ•ñ'G�Š…)F–¬VJ[Œ)fLL˜FtÖç*Ö‹¶¶ÚâÅKXU Ç’-û1Ú‘^L±mëô-—&Ð•Š Þ¼töòí»)`Y (lØ/�:sÿÆj¼tå[º’/=D¦LÙ­Å;yr† U2èОc^.­ì&êbÉTjýó×F²�¦ªm›îÜ¡ŒÎ#æ7ðÕ«ö¨=¸e\… +ת5q¢ÎEÒ5SÏéà‚É6¤*‘¢EŒƒšIÒ$Ê•,]*„:ÓUÍd¨óôùš<€¡F�&]Úô)TRygVWiÅ•Wa‰eƒ ¢€Zm¹×v IfW^z!æ×u‚ewˆ!"¦Øb�Åò˜J‘�FÙC—e¶˜&1ÊØÛn»õfÚe©Ý´Zk•Ü'‰lÐf[m¹éš%I* \p‘Aœq!'×r5÷‰9H·Hušu˜Ý)VéÿPUÏ­v‘}°áG–y&�”ÒJ-½äM6á¤S}¯©ù‘~F!µSÚ9噀dFT �¾pÕÕWa5ø(YF(¡)V8W]Reˆ×†^fˆ"ú•%cŽ)™S¡±è�‹šÉ8ãh5Š6ާéÈ£k@9[QDi$#»)¹$“b8ùä@Q4åKc"såsÑM×¥N_f'fw†:cfxin$Iƒm¢§Jr¶'S�òÝ™Sž?òI”Ÿý)õ¡Si‹hn• £�úÛ‘¤#QZ)…ra:†›vÚ—µƒ… √™ˆâ,*NVY«0¾ª �²JÖÛ0!‹¬£jõøc�C l°HkÿI±Æ: e*Ç=‚-sÎE›Ó–=öXÐA7|•ÙBô]gЧ&¸ Š[Rzq²—�ðÙY }=é‰_ŸEý韠FeïÑÎÜr6Úú2ªà¿ÿ¼¥–|¡¦ /ü×u1?|DÄ%šÚ ª‘¨Š1f®nܱǼ�&òÈ·šœëx)÷ê+˾ó±4ÛŒ³•:Cdzt>·´ÐŸ^[tee‚Gšº6]ÞHnF]îÔ0¡kµºX㩵»BÁëµ¼�†9h€dW…vÚŠ"Ø(XmûûöÀrËE÷]vßÝ¡Þ÷­Óħ¦˜êŠ„¿¨ÓÆÇš¸âž12ɸú¨«äaøšJå.‹ùÌÉÖ,ÿåͨwŽ¥´!ºJ�hCÓŽÿ´Å-Ö-í[áŠÝ¸Ôc.ªÝ.>óÙ]šÆó®ý|m^a«×€�w6µñ«yÎK�Ì£2ƒ 4 yá$z!C>Ð�:ˆqSIö£C£àpÔ‰J‚¸ z�&Fð,{Ï{Dx 1öÈ+nd^Ðv&(FÍ©VÜ÷F¯Œe(~TÄ!)H@)…e´8$"§hĘ Ž|äË×B2$>ñQã÷ȼ~µ-…#YaAZ(JÆp†5ÔÌ q¸Ãöð‡Å"JˆèEæ"ÿ‰’µè:F‘–U´¢/°èA-rÑ‹`¬ÎiXÆ3¢Ñjdck4–8êpŽÀª£›“ÇÇUB“�ä iHD’–ŒÝ#!©CIâÆc–¬ &E'M-¨“AúääögÆv††”2ì…mè—®R‡­Ô a)K¨ÐÒ–ÛM.µÈK)*ò—Vf ˆ šä£š é2�ÕLgŠšÝT)X¨¹k ›1½ŠkÚ ›âTœj5RO™ôÓt õUD�Q�ªF¥rò_M}êeýiJ>´/YÕêV‹ÒU�|5ˆaÍÃX_UÖ±l~„Í […ãVŒÆÕ‰Åô(µr‚ב²P¯Í<)RúÆ•V¡¥$½fۇľѦàÌémqCKZNV�ûagTm4ÍŠ�³&´§lð)?e…vª£--_N‹ÕÔª‡®d,‡øÁ"*Ò¡K–m]ºÖж˜¼=…\éÂQc7à Lv±Wä*×�Ìunq ]m"–›Þ\ìM±+`ÈnwŠÝudÿeetÙ��÷�›ìRÑ«Â|fx7/|OHKkˆËw ø1�Yi_„¾R¡Ùé -·›.^¢¶¾Š0-Q³š˜8Á¼¡«Cìº+Œ¢Ë^Ϋ‘ªV´…Ô¼ªÀðˆb—;ÞñXvšli°=×H/,q.Ô¨ÆÇ}éƒ y‘'F7r¥³þú,�CÉO©NÇÉÔ1�å ä tȋ٦3�_0!Y‘JVU !êQ¸Î¸U¤”+Be¸"Ø·Åò»Ä/™¸ŠóíÆ|¶2Ã8,h®³šaÊæZ¸Y±p€œ‹Bç çæÎ%Ö³w87ôõ&Ðd¦!¡·bhH!z½úlo£gÿ’c«Òadžèñ¤,d7Q'Óš6ò`:=ÅO¯(Ô£u©™­]TïHÕŪ²«çÊàêÌšÖ£snÄì¢]'ÓÌ¿Îp°³ÉæbW7\qäœ=hjÜ8{»ÐFž´§Gí[¹Ù¶Å¶ÕmÛÔ¸Ÿ qô!}nI§{Ý&)`Ü�éMy4¤¤÷dì}ï|ßúÔSL5V-¯Þ6ñ·u•5O ~p[C5á¹^øÞk°<üÖ6±�ôæò\üž¾ÑqZ~mä<ä´Wm÷Û^)ôy={O§&ª6~¹¸Mns£;ÝzЇ‚s�o@-jSK"ÿˆŸŸ¯FL¾7¾Ÿ<âÿfSéJÏbÀ k-œÖ‰WDކ�Ñ­ôTã–›¯ûX[ÚÒØ;¤d‡aÙEç8CðÜö³½�q÷ØÜK^w>œ<,ßr ÅÓËwo·œÑ0¯êbøBxšOúðh9ýâuîø‘@^ò“§$Ðéry̽êÀ‡¡çÿÍj+/¸�ºÁOŸú«¯>ë­æëÅÞHÍ^B¬Yí9ÉíIGî…DÙ�]„­�" ß-ßñÉJò]Òò5X<ßš Ðéñ\¼ñ×½Œ% F.PA y_€Dø‘ ØðNâØŽg,ä R‡ ¾…gTÝU‡k-KKlhìÕMHH Ѓ”ÿN`Žz°LYj<‡_¹â ½ß{ÜÚš,  –I°Üæá†ÁU­Lo4‚¾¡¥€‰a-y•dR …ËÂËÈÛá‹ &à 9Ï E ²Ú ¢� BEñ "¢B*ŸÆ>‚Jƒ&S 6¡]®„^Þ„¢ä|K¢Õ±Ì�Í„ž ^„ž–„n#Œ/þâ¹xÆÂ!…Èá@²ÖÊS:Í QŠà"J ÞÞ ¶M!R õ øxÌ"ÆD#:É#.Ý~ÅÄ$b`%ê×)D^&ÒÅ&vâ}"Z8!©Ç,”ÿâ)C*&×*nD+n¡Úž+Ìâ-Ô¢/Ü¢G@.®Â.¦0>¤\´á06BfÇ1"£"Ù!2�&^~Eã,) ^•|]£ÛÀà6Bb7ÊÊ7æA8 Ç8ÒY$šã$�W:ò&†Æ;bEHÉ£B†âÚ#>Z*NÄއ$üã+K,ds|áo„¡±•ÅO6W}1¤²8$Dn¥DcEÆE:¢2ndÊ}„ž R*%„�a@†›SÖTŠ�TVœYT%éÿbV‚IAl%WŽÆD6bãŠeNüYæ› %J¨¥X±e� F�Á%¤dã!’ã I�´$^V„^ _2“™âQ¦% fN2Z¸æUôdbÎ#Ðü�vþÁŸØ£äáÆ¥>¥*¾Ó´¢ã!XAç#p¡,>%-FåE$/<_¤,dC’æ)˜&Dv宦E£kæÀ9Y˜lz Gò!°&ÚŒ¤i•$o6ˆo¦$p¾…pîq¾Ý€æ]þà$,ç_Þä%¶ãÀÐLPgø•OÍvrgRxgä�'sB&yò£y²â÷ EzÊÂz~çev!|¤|ú}ÚçXTeÐôÿP`‚ >¤º!€ÆÀ è9½^¸tˆùµç‚ŽMƒу"Š[íæ„:ˆ\Òe††† ì–¬N^z‰JŠM_†(“�(u&;ºà©(‹^gU¾hwJÐŒ2BxÚhåyî¨"ôè�jS¤A)ô�a1és:é“þboÄÌ”D•Š£2JV%`©Óh©ù�$EåÙÙà˘Jh™R噯©"²i›v¨uÄ)ˆÚä�>gžaarâaâh‹e=F!°jîDf?&¥¢ä£©A"$Ààœ¥ª#¦f*ާú˜|*LŽ¥è�jy˜*�âZ¤j˜H«¾å«Âª!Z¨L®äpÒ*–ÿ gpƇJbM᮪c¯jâ¯Âc� ëbŠ¢Pk�&ë�Jf¢f£³ $¤©´€’Mµêç~b«ÁìͶÞ�·¾ék.£ÏˆkY¹ª¹¢ëªŠ)0‘i»&i¬^¨¼j(½.ÐjÜ+Oä+Mêªfàé`ú*ñiy,c¬‘ k.ì²R&`< ÄB«ÄNå}V*5ivØã,leùpl±ÜÍ^|¬q‚ëÈÒS–^Ç–¢ªT8èʪk˺êËžEÌÆk]²dͺiEà¬èìœòìbøltlÐku­ŸÒc ’"Âæ£²æ¨?6ëRÚÙÓjf|r¦-Jm’RkÕ^êÕÚ£Ön ×2 ‰×ÒØ’�F†+=!ù,%*®üÿH�àRYÈÐ…C Hœ¸¤¢E:9häчG CJ) dÁ“(Sª<ˆˆË&0º€ha€Í<8sBØ9¥gŒŸG‚*š¢hÈ��’ŠXSf…§P'â™jÑ€U�Bh­Qƒ¦W›vŠ…€'‚Y³A�œõÈ–Ç—·pUÈ� ³ Œ»^! ÙËwìNŒ€é™ °áˆŸ(®ëêÓ‰?#ǰj í˜Ë!Oh^Á¹³Ê�B‹ÆBº4eÊR«Ìp˜×°ÉÈžÝöãà¸sÝ�b0 ÀƒÃ @üsA– Y0lø0âD‰/fÜØÑöÑ‘J 0Î�;r—@7ÿ¯y3'N±=§DN;TÁnßI-ÑÔ¡ãǧâ©zU£Ö\åX~‘uZA­U\qÍ%W]wÁ _}ùÕšo†–ØbõÝWd’Mf•e˜�¤Ù �yfœh£•FÚiV©¶Zk¬ÁÛl²Õƃo¹éÆ[oƒ'Ü[ÄÐ�@È)´2ÑôtÑ-VñÁ–oØiwä–'}÷R}4�eÞy<ù”PD5X|óÕ炇RQUeXý €úUÖ�i)؃o9ø LNH¡^8X†…!ö€bOˆ÷æ} JF‰cd¶YŠ+pÇbh.¾£Œ©ÑX£�aà˜cm<ö8Â�@ÿ%$pÃwd’-ÉäxO2¥”ÓqP啃ei—Èàex`Xžyè™{iÆŠ”RL5!Ó¤ŽÅ¹ßœýeµUWx>›Óžgõi–Ž€~!¨ â•XyŽÕÚ�f9 ï¾ŽB*)œ…(beA]–©‰›¦˜, 7 £¤`j`¨¦ªªŽ­ö«o³ÊP«‘·&—ë’M:÷ܯSRg¥u"‘tl²[.+i˜æ’ Azë¡éžšG±™í¶3 Ô9®€ä 0fè"¨Öº ún¼ÎKoX²†oûò»a¤Rpˆ—\" 'rÚ)² ;<*©»†ªªd`|›«ÚiÇñ¬Çÿ,²r$óú$ÊÁË2HÆn³ß-}©íxbŽ­zgÑÞ{kbKßãià¹ø -çtúwt¹J�ÙtêFÀ®Ô‚R�z½b¡`[w­o¿rþ9èŽméˆfŒ¶fBr¶pÛ<qÜUL·ÝG¹:BÞ%í-dß!#äÄ÷ µ ¾€•JGV€QöŠ/Þ�ÌÍ&�Sô§—^Zim Ò¾óµÉ¹ ¿ ÝÐÀU4Óˆ\VK�yV׺×1è]*TÁ2± #¹ÓïÀæ»Ï…N`e;‚Á4u‚ä­�KÌC£ð<èUìD'RHØGÃj§HEb ¾ç„ð�//å«HÊÿ8�¾Ú`'qZrßûž™9K�ôk€ýz‚¿ èüëßæ¶Àà‰î[¤ —�ø•š1 _­‹Ø5ÖÈF]Eð.W‹ã*¸“ Ò!ƒ]Û ¤ºX©È„p„+ap”Ç6æ­°…qƒ¡"cXµÙð‘ØÃ¡­–è=ð-D|- ŸðÌgGÑeyS"%YÐÄøE.Qœâªx„+f±n ÚÃX@qi§<d5²q�n|£¯FGÜ _ºs€ÃÖ-áù‘x"<[Ú8µ¼¶nÐ[ä"uäHHzS’ %}˜I nRˆÁ*b[>™ì‰Ò;Lt\É䇓TN‘•®Ô—·Øÿ˜f~‘hF»%ê–Æ@^FÀ—¿ f‡I¯bó@É\&ç‚Bhòx(¢f!­É(vúÆ7ÚTdFJÒnzó‘àÔá8/ùC¯Xç»F<ùIö½Ó8ðãÍ X¿{V1ŸØg,ÅöOôN $è.ŸvPRý˜Kz# JA‰ˆå¡g‰è×þEÔŠ,𯛦Â6Ú°zô£G ) IZRN�’)íÞ-ILj’‘á¤Lé@Ó#Úô¦+‰'³túÄùõÔ~øüQH^é? u–¥³%R˨@]òÉ mcT…IÕ9Zõ/ZC¦·Ę̂8ó'”fÂT„BCvô“hM«Z5ÃÖ‘ÿšô­4Œ«@Úšø–‡Ln?+p€ìE2é J•ªä›}ýà¹9¼Õ¦;Ý:ÊQŸêÀß …É$$Á1æ¹ÀÀX‘  á¼G˜Àd{’6l.�Rƒ|=DÌ D XÑHöEø÷¿q,®€@„¸@HH°‚´‰˜àÁî•YÒ�‡]47:È0&1ùßÿòÅ"[ÃÊEO4’ – ऀŠWÌÎ3¸øÅµÍÀ O 3ÞvÀ·3®pí•â72É=Âr9Ò\}=÷Ñ}u«Ë¼ë"&»ÛULw¿ •ðŽ7JæE¯zÙë^†ÁW1òU}jßèà7¿ûíA;L€ÎÿÂö�‡LTÃÙŽ…-|6 kxÃ-`3>\‘kdÄš)±ah|$p:Z’Œ¥�q¬c& ×ÇB@®Ó†Ì‡";àÈIöÎ’`]'CYdÜŸwÁ›ñ’w YBz×KÂ.#àËOó˜)Xf‹œ+i^s‡Ý|gÈù>tö§�áœç=Ãè¸ɰh6z †æ¢O èÂDš;�w8¿]Môö·ß ®¥yüLkšuʲ§A=IQ/¹Ô×=urRÝ‚UW¹ÕWŽN¬gÍ呾W.ñ�ï}ê{ßür Øô4±ï|lÇ$Û´Ï)v³{Rág÷9ÚÞ° ¯�ímw;äÿþŒ¸�ò7ìÜ9N÷޹E\ãfÈ›–÷`œ ÝzãtÔkºÐ�ü}'„ßþ~Š•_=ð-×Úà^F8˜î†›Ùáo€Ä;[ìŠCE@³�ØÇ®ñ'M˜ã|6žŸ§ è‘ïÄø±j¹-·%+wôÝÉ óJ_ÚæïN §çÝóqÿ|ÉBº©?å'L™Õ8qu”ÎKy‚?=WAÂżp27Íü�8›'g¯?ì!;ÙïÜ«)vü4Ð�´©ív!Àý@rk¢ë¾è½$ïºõ=w&�n'¨ûï?þI� ·#�çÈGNÖ¨�ø ÝèA:••ðWS^Ë´¤ÿ­q­ëÎóúóÀNó~·NÕ®›õ’Q½ØËþ×;\Û—}È9Ìæ_•|î''|(|8$€ÝA|1g|3çî†sð&dÕÑ|¿Ð÷\ÒtÕGtÓx�÷o‘pñ}²ætâu·&u¹FuPau¾†uê×ìÇPîçuðòg÷§^:8öçp±'m¡‚[ãqwhÈ{Þf€@€¨„Ÿ�€~Çn5—|1°|ÏW�ˆxèdˆjR¦jÛWK‡eUD‚5~(X~UçyWzêƒÃ4ƒWƒ?qƒ9¸ƒ�m¹k„C%ÿ§{tgwÈ„¡æ„'…2·n4ÿ׀ʗs+#�Y}öF]8†cÕ·YЉžø0¬¤}�—’'pg~ih‚ä§‚OÁ‚ñkúõ‚r(Gtxlú¡a'y¸ƒ|h„jr:ˆøò+"8}H¨„ˆèsŠHŒ¨€ŽÈ€€ç€‚w…ÎG�Zxx˜˜‰3°‰žø‰0ŠaØocX†¦ˆ?hx"j¨yS§JðŽðèŠK‹÷‚7Xø˜�qT‹rv‹S‘‹ª·‹:Ø‹ø÷‹úŒ¡ˆÑQŒÇˆQÉxˆËØŒ)ñŒÇ'…�X…’H,(ø—8]ÜØ�Õ÷��ŠU$ŠHŠ X^§Xp˜u옂î�ï(�ôø‚=ÿp�ùˆ�ûHq¦ç�x�c'�êE�?˜aÂx Ä(‚ IbHˆrÊ‘ù¡1:F“­|¡ƒ)'2$¡tÓ7j�)ºò_‘�“8) F“ïÈl Eö°(v‰% $¸æ]|™ðXS‘‘E—P1Ò+Å6`Š)`DxYøS1ˆÅRŠ´OXeœ¦‡¨í2•ž)JU)W �Yi[9]Y<_I+_–1–KV–Šq–þ•–j©~l™`n©p)—éA—ùe—r€—í$z‰‚}é]éOú!˜áB˜1ˆyg‹Y1�di™Ø“9‹d™¡u ™ÿ©‡¾Ñ™ŸyžÉš*0šïXšpšx�š`µšÓšIôš°9]²ù´I¶y›û•›H°›½9EÀ‰ÂIœÚqœ1™œ~ ˜xàœµ�Ñ)#Ó gÕ‰*×é4Ù‰*‘‰ÝÉ^'ž�±5㹃å (è¹¢[¢žì©î Ÿòi0ôù®9ÓWuAm‚–? i& R sY—wY,y©ž�â Ë‰qÍÙƒI—:¥@7tc�‚¸Tj#*±jC¢¸ƒ/œ¶Hí|,š¦(á¢2‡•@/2J*^‰<¬y£H2j: @ ;±`yA¤¿i¤Ã‰¤ÅÉ KšœMÿ*@� ¥Ï)¥T�Vª*ÃJ[ÃJÚ)#Šò¥aªE—³¥g ijzª'Á¦ è¦pºúa; s*Hõi§Ê‚§yº§ŽÑ§ÚB:¨—j¨ ZŠªL ¡Š:©¤R©8r©UÔí¡©º�€ñ¥`Ê)bŠAø2ª'PªMˆªä ª\¬ª•®:p^²ªštZ«÷‰£¸ª£º }ši–A¨ 6¤Áê›=q ‘ ˆÊ>ïÂC|Ù¨^ô¤öì’ê¬2­³!­øC­C¡#›:#�[Ø¡6)ªà*®‰X®iz®L�®¦¹®xЮCð®ó¯6:¯¥ÿd¯€Ö£µùúº_ü ¨ ¨^A¨K¬‹= û= «¬S±…)±K±d`±ÔB­:²H#C×1 Ë<";ª$ËŒ&»¢(«²ïɲ3z5jŸ/36ë8;š³|º³1г=ð³¾ê¯H°&;Ë»µÅ©IëKËœ�ú°ѬP[¥RKµå'l�µ¤¢µ-#]Û6_;[akxcK¶`•mJšoª®BÀ•r ¯´:³m[³o›§Mp¯O‘¯=±¯AѯAû¯ÀÚ·ÂZ¤Áy¤„‹°‚¢°ÊÉ´ŒË„©#Î*µS‹*˜Š/W«HÉ„¹ˆÃµœ’B+”L# (hºèÿY¶¦Ûª©‹š«³­Ë¶Æù)o;Xq»a:ëŸ<{»>›»@+´4A´€k´Ã‹´Å«´Ç«¸Ú´�K—Ì;©Î+¹LE¹±HÕË*hõ±ÙëZ½`뽦 ¾,*¾íyº+[¾ñy¾4*³ê›]í+»´[¶;¸{º‹¿¡¿�;¸™K¼b¼*Àªä´L¥ ½U´5Ó CÜ‹½)¢½ŒbÁž‹ÁãªÁSÙ0ŽBißó;žÃPQôZ¼ÅÂ)œûÄC+µÔVl‡"[#hœÆt£` FQ?VAyÂ)� ñb¬•ysÁJ‹¹5­‘Æ'/v‚<È[c0†|ÈCLŸÁÿ±H/öbfõI�ìb40É”œ,cjÅc+ňAÅN`Å€Åô³Å¤]l—_ Æ=´$BƇrÆiŒÆkÌÆHàÆ1Ç ÇvIÇ(`Ç„x,¬tƒ|Ì~¬€ìbƒLÈørÈÎ<‰¯‹¬HàôÈGô½ï„Íš\®œüž ʢܥÌŧœÊ`¬+­|ge ˱<Ëll˸¬ËrÀ˾|BÁ¬Ã,ÅÇ|É|Ë,È…ü̆Í´:Í0TͯuÍ|bڼͨÚÍßlÅá<ÎZ|Êr`Î<Êé gªÄÎj¬*´\Ë]õÆü!Ïôìbw “y\EÄŒ/}ŒÆ\Ç.ÿ¶BMЗaгBß›w‘öЭ¦]|àÍh@Ô,:Ô XÔrtÔH­ÔZ¤ÊŸÜÔ÷QlP�{çÒ82ÒV .(­Õ*ýË]íÒúì4C0a-ÓÈLÓg@ÖŒbÖ9]‹´ÓŒÒÓ+÷Ók ×ÍEnäHç~‹Žþä6åîÞðýÏWÌYžâ\ÿ¾â¬Ñâ½\ÓaÎ(cþß4ŽC6^²îÐ;Îæçéæ™äÀÓ† õ$u.áwþéP±äÉËçN^è’âƒNÙ…Nß*n^Cüýè…é”<éERéÌxé€…àš¾é Ctž¸“øXl¤anGQEÓ÷çiû„ÎC*ÅÈ|ÄÙ{ŸAtœ+ŒÜSìæ~îÆÑÍŽ’ìÊÎì\wgÏ~5ÑN?ÓÎÕ¾sºƒío##Ûn�„ëí[î?2îœI$b‹îîêŽ쾓îÞ~ðï`1ï Pï�qïG‘Lú~Óï“ØíIÈ%Ï�åžð(¯ðÇîd Ÿ�/ƒ/ñÿ@ñ?DXaíú²ñ¨¡í"Èíˆ ðGÂ>âþåGqò)ô<¾ðÐòËó0gnFñšYóáVõ8ï:#¤¢^ÿõ>ÿï!¿%B?ðŠ´BF�ôjÔJÏôEðòsèôF=ïS"ÅxõX�ï]³õÓõ_ïõaŸ¹@ßeOògÏ(i¿öНÁøæ(Ö÷´(÷¡—t¯‡s÷xïYŸ]Ù.#ïõÔƒ3†,ì³B‹ì »øªo²���/ù= õÃ4R¯‡÷‡ùxïjÃùû®Ÿ¯¡rcôسB¥ßÙ™¾úÊŸ¦­ÿ¯/ûýqDû•¿ƒ÷×™¯ùƒ±ûŸÿÒù¾ÿùÁÿ”ÃOøÅÏ(ÇOà7¾üêßæMædÖ£##0�?äµoý‡ý™ÏiÜÏ"í(ÔRÐ „ J`˜ÀáC%N¤(QÀEŒb̨1A�!+Ž$YÒäI”)U®dÙÒåK˜1eVDPÓæœ9Gìä™0a  A……PÔè¤I,eдÁS¨¤NåPÕ*¬Y=låÊÇë×aÅv [öËY´ ,èá†]r¼è1]vCŠœÙ×ï_À�&lófNœ<{ºÚ8†Ñ£I‘.ДÔ¨S¥Z½š+×®_½Š[–,Ú´jQ°më®»séÚÅ«woÿ¹uïæÝÛ·K Á…Ÿ ^Ü-�É•“aÞ<ÂsèÊ•‹öʹ*ìÙ¡oç~Èû÷Û¸)†gX^‚ ôéÕ£§ÑÞýoøñåϧ_føâÆÝJOÞÜ9wþ  Žë8ÈN;îü¼ÛP o=epï=û*´ðB 3ì ¿üN8.@ÿ˜K0À <»\ð�ð¼-Âõ&lOCk´ñFû8ÌïCþB$cDþìaH"O„"EîZl)<¼”ÄñI(£”rÃÛ:ôp¿CR:!‰ÒÈQ;ËÉ•˜¤‹Ì)ÓTsÍ4uÔÏ'C,p:ëìÒK0¹ó 4S2“£>ÙtPBë Ï.¥óÿqÎ:é ÐË/O SÌ@Oú£J ÕtSNÿ:Ô£ãTCaQëu”?H{Ès»=3-éÒ‹\ítVZk%éS�BUÍÇ-T.ÕU¡kµÁ%ok’X[“UvY\’‘QEíÕ×€=Ñl³v/—`@Öe÷ÍÛìz6ZÕ¦õ5Õ1Úu7[m)E¶LcÏœw\|ó•²Y‡ÎEw u…ÔÝwáu`[¾Xò\}vxÊ "–BQ_°øbŒ3¾Ø`„îa�C¦׫Xc”1æ˜á‘[v¹á’Õ;9å”W¾÷eœsÖ×Û™iÖ8<–uzhB½ÅËg‹�:a¢›vZS£éBú¥—ÿïi¬³&w/¼ª^Úk µ{ì£Ôj�Àšl¶Û&ÌlLÑ@í›Ý¶ûî·ëí:n´éæoÀ îXåö›iÁWœ^®÷æÛêÃAZ|rÊ+·ürÌ3×|sÎ;÷üsÐC}tÒK7ýtÔSW}uÖ[wýuØc—}vÚk·ývÜs×}wÞ{÷ýwàƒ~xâ‹7þxä“W~yæ›wþy裗~zê«·þzì³×~{î»÷þ{ðÃ|òË7ÿ|ôÓW}öÛwÿ}øã—~úë·ÿ~üó×þû÷ÿP€$` Ø´$P�ˆÁ‰ ø@>À4dÛW§À2ð�dà;PÿA ¦ƒ ŒàA‚0„§áJhBNP…+,] _¸Ášf†4� 5ÃÊÐ^ã!éÖpD$Þ�ƒˆ C�¸Ã"j΄*@b¸AÈʼnNTÌNÖÅÀM±ŠGT¢³�-6±‹#ø"ñ&Æ12AŽs´@íxÆ4†a�mt£Ø S8VqŽt´cñ˜Æ5š‡!|ìãÐþˆ€@"q�r,¤!³˜ÇD*’‘�lX YðIP:A”£œ$ZpJTR†2’AJc ðJXº .á$Û< ÊOŽ’”“¬@/}©Ê¥°ò®„å+e)�¸8¤–d»%.u)ÊRúò—À&1‹yLÿ$3Ë[3CùÌhJ³À@5‡RLc¶k–á¦Ö¼™KpòRœä4§PÐilj³�î!.á©ËpJ“ž¬´f,Õ‰LذsŸOS ©ðPˆº@¢gEÇ Ì%dT£A¹'6ש̅24�…èC'JQ‹ £Í(GÑéQ„Ò2¤NkèKjÒ“º ¥*U%K[ ”ŽT-úœ)GjÓ›æT§;í%9}º—^S¨ÝfQ‰VÓ5Ü” Jej/óÔ¨t ¢"ªU…†U­rµ«_õiXÓ9VÕ”Õ¬"óà(!:G ä5{å«üú×§NA°ƒ½§ {Xlrì‹E\JZèCÄø“ÿlá#纛ºŠò®rÌ«øÚ׿ú5°ƒlakØÄl±?h,J;ÂJ–²#´ìes“Y'l– �ýì^C+ZŸ’¶´è<-j…ªXÆJ®%¯Å`lý9[ ÖÖ¶ƒÁ­nyÛÛß a´¤5íiS ¯Õ¶ö$ÌÍ`dŸ;ÁÊþqº„©îCñª×Þ>õ©ºg ì{ßïf+¼Êe yIÈ@Ù¢—¶ê]¯`ÚK…÷z6¾òe)}Ñy_üWµÉ½ÚJüëBŸ×4é5L� L–'„X«�½nŒÂà[§¾N�¨lFD �0Ä3~‚sq ]J×Ã~)ËŒGLb›¸((Ö¨ƒ‹Éâ«æÅâÿ5É œüd‡ØÆ ¼g�t¼ã™ôXÄ7r�OLä%–Hv±ÁÚød(GyÊŸ¬²u®Œå˜hù ?&1_¿œâqæ8dVÍj÷ c’LÍNŽr�D'ºÍœD£�8§ä‘r¦s‰ï\ä<ëÙ-|V‹Ÿ)ÜX zÐ…¶Œe­htÈÑ�¦K¤Q2io¹¤]¶ó�}šiMû„Óñ4kojz¤.5N�èE[eÕ�†4æùl“n œq¬�Ê$ˆó¯ŽJ�Žc%޵j¼#œâ3�PÊ.w¹ëfwªÎh$�Šlƒv½`ºi²Ú×>e¶¥¹mn{Û-à6˜ÿ¸MÒÂrÇs�érEÉùîiF*ó&›½¡�oj‡ØÚMÀ¶¶ýÊíÜ'‡—ÁK‚pšÝ ï¬Ã� ñI|›ÅŸ�q}kœß-ð·/î‘'„äñBM…G‚ò ª|’]6AÓ�îrUÂ<;2‡Ð&qfó7ƒ.ß,Ø7Çûíq!€<è:¶ZhôŠ ý�殤˜îô¦C�2RÇÕ×cõ—a=Ú=Ìø6Þñ<àÖùv‡8vöqc0áºlûÛá.÷¥Ð vWÞ]¦÷×°ïÿzàÃ>”ÃZå8BïPðAõiÍiÛÉ ÷¸ÏóåY4åÓcù–aÞ&8çºÎ½ÿÎs°‹�ðn)®L?B´SD�ªëOêz`ÂÞ�€äm�Ü�L÷5á}×ïsÁ}ø>)þñ1˜ü‰,õIm}%_{ê[_âU¯Ù˜ügýs[÷~çÁÿyñãŒ)?:½“K½õ+)¥‚>U’>ê+6xªë“E’¶ñ üË@ ¶fóþó½ï륟kŒÀâ2?B?‰P¿æc¿çs¿èƒ?ÙS%”Àù[� ¼À Ò@üãÀVÛ¿ÍÛ¹žÁð#Aë0ÁÓBÁRÁˆ`Aç›(¤ œAʨAŸšÀl˜7ƒ5Ó¶1Z,C1,�û’˜Ø œG’¬�Û8 'ÿÌx ˆC9,Aþø«D;<ÌÃ)ˆûZ-ÉÒ*­‚ÀÞʃì"C<Ķ“¾"Œ*1hÄû*Žô�+|ÙÂ?ò /#1C)È9ÃÉICZCkkCizÃ�Ã9´Ž¶³CDK�=Ô‚>\¬?Ä’ÄÞò ¬8DD¬$E@{z¥FƒG$ŽHL(�ÒJ4 K´/ÌÄ0ÜDû2C¹@Ã?RCQ$E_2ETŒÃYE¿J4WÌ>´/?ô'Z¬ÅbD\¤]4ÄD„½E*`tDû‚Dô�ÄqIF›ð RBüÇm´hLi”©Oü£B[@7|Àì2opäŽWŒÅ˜Å’ª(ÿ+d©ulG"xG¸‹Ç€¥`Æ(FƒÌ}¬‰BëÇôǀȂT¨Åy¤„l½…Ä –묇ŒÈí˜Hr\,sÓ*Œ,¶§ÚÈvôH§I‘¤Ç°G 4ƪBƽ‹šŒ2–lÉ— NÌOœI„Œ2…,Å7ÌɼÚÉV”Hq„ÅŸü� ¼©¡,µ¢ÄÅCTº„»„�:êEÇXJa¬Gb¼G¨t˜”D€•œ¤–tÉmÈûJ�‡`2·©J ËiR%²Ô€‡ü«pÄŽq„°¶¼HqÊH�2J" K5¸Ë»$±¦SÊyì˦ü˧<ÉIü#aƒÌ»J€LL­d1ÆtÇla«Éç£Âÿ¥¨ÌËô«Ì„‚ͼ¯Î„¨·´Œ¸ôŒ¹¬Ë»ÌKxôEFdJ§ÄGqy¤ÙüJ³MÄDEÅ´¯ÝüþœßK›ä)Ê ÎJÊ®ãLNûZ·jΦxάàH¤LMë”GI¿,IÀ„M[‘,a¶*ÌA:L$ÈJÿ@²òìM¬‰ ôŒÌõœÌö$Ëâ‚øTKÎ|¦$Q­(ášüÌÅ£äÅêÜËÕ$I“”Éd1ÐE³µJÃÎÉ¢O*d_¦\&àBFâCVâDfbÁj`<|à=^�H¶‘ÅÛ¥A²â ¶äcK•LæâÉõ`¹%_0[žXSRNaÛ­£.S`–_Á"C;ŽVžcjµã)Àã#ÐcàcЭ‘]~&­úå@daWC®D†;ENf'^f(nf)^, y¤h†¦ÿI¢f(ÅâK&’l®�mæd %§[ýæpvÖq.ça=ç&1u`vžw†0xŽcyŽå˜å¨e1¸åϽ^ég]úg€&b;"d‚&fƒ6f„Fæ)Pæ#`æ|vfˆÎ‰N9…›#‹ŽR¦Êè!ÙèŽ&10i0ia-iPEá“Vc [é hé—¾¯˜–á™æOz¶g|Ögž–PÄ%a+¥~m*�þë¥(BUæHPQ§cÀÊ(å°Š¯ Éâ° ÉŠl:»úK¿~SœÝd¯§Aì`JŠ Ȭ0 (mÓ&§CüÇ÷Kʹ.θ§uD²ãð‘®>ì¦HV×^:îžßåfŽæÎ&†€nå�éþ¤ê$,Æn�Ön°Šî>ÔÃNlñNÆö Ç&ÈVïÈfo }'àà‡âfiªoÀ¾o m¬ mþ&Ô6DÕŽAÖ–å;vm«€m\”m‘ÚþîÛNV �ð3n'¨pé5näVîÿò¢ØvîÀtM¿áp/vr÷tsõ„ðè·%uhpw÷rxóU×ø2¿ð3·�XŸõÿ÷Š× �Ïu,îdGøCd7=_øï~*‡?ö@OöA—ø‰oö!Qü=FßxqÂm¾ºöÆPåu$ùíÀtZ¥Ux,Q•ç€{²’sùÁ¶•>ܶù�3v>èð�ˆ÷�·w|oã ç÷òÈ>•x¤œEú¤÷kƒ¦7D§öô©©çƒ?�/Äú¬?¿CoB®ÅŒ¯Ì§û½"û¡0{\D{èPûµW‚¶®·/¼ü˜{„(4»O¼Ï{ÿSßû?÷ ¿ˆÔ¥pžou3ÏpÂ×wY7üEúü7ÿ£ÅŸ£ÆWzìŽ|"˜ü=v©Wù‡ï�ÍçüõÖú¢·l êúÑ'ËÒOÖ±·ï²ßn8{þàv"øÇׇý�tûqçÚ/ÛOLb𠉄 ñ0lã!‡ˆ|&ò¨ˆâ"Æ7Îèèäc‹Fj¨`Òä� ¦°œbÃÆ‘˜GÈЬÈ£„œ7èéó'РB‡þ\cô(•¤J™0mzò)Ô¨¦R­j•ª!¾´‘‘°Eư`֬„ –°m[àí׉|RÐýúõèQz÷†èë·àÀbÞ©‘¨O‚›ÿ0nò±H’#6lÛ¶ažÌW­غµëW:¢G¿-] êÔa‰ i­ä5ì´&„´l ÷«M›'vóþâû·áŠD(›2íq)ZÄx1xÇ�„” 5åÊ–/eάÙEN Á“/úôx�*]Ú”iÔ¨æÓg`ÿþÕÌúódõ :âjcQÖYȶ–eK”¶Ü\uÙÅÁzk¼1!…~ý`„F‡µˆ!÷DcŽA™dÈá‘à˜eV YœyÆÕK¡�&šio¥¦ZX­![liÑVÛ·E”[E¼õö›oÁ�XœA²™ ¢r1w“s(@çH(–ôvµm'ÿMdØ„“N†™·¦Pé©·^{I½_|OÑWß}öå·Z}V#€b‘ã�,.heƒ)<ázVhaf¨¡zTˆ"W"c'z9r,º˜ŒÈ8ã܈cŽ;¢¶š�@¾&Û�µÉ’<(¹“Mö$”RR ¢gf¹¥t]Z¦JbÂD¦wX‚—æNlZëÓÙj;bœTDu¸áf5®˜{né±®d#åi_ñÊ v­6n0Ru_³-ð/À�†°Újž¶ûevÕUŽ”ùÄ+H<1"5Ýts2®¸ä áj«Òkk0˜|òIã6@ä­r¸üÿrÃÈ_´ÐD£gtGH3¡4Jà6]8Ôß…WµÕWÏ õÖPuÍÖ×éŠMöØg£�6›kgËmœos,÷Ü€½.ã­7ß_Ý›U¾îk_¿„~x»‰/›ðX�;žÿ#ä/H>¹ÅŒr9ÌÍIsœÙçzT2ÑÁ gBX™­N÷•Ô¹,f¬ó€ë^#îŒg¶Cî20´�M/GcLÒ²4á!§p(ž´Ž‡¼(oyÌs×ìãµU�mzÔ³žÙ°—=íuë`QÑøæ6>»Iæ|3J_ ˆð7÷~ƒ›‚ fD¨\eqùkÜãh1ÿý�rH‰ÓÁ4G¤)  nÄÂȈ„-V tD-Ⱥ Övu”�eh÷ÁŽp#%dÁ ›�Bƒ¬ðÃs Ñ4µÖð†8tž¡ÇCéU„zÕ¢פ½QqPA¢«µÄòÝí]è«—úüÆ>À @ÿpµÉ¢ïw’.š„q #Æ(Lˆ™‘=hl—‰ÔÆ7Æ‘5­¡£m#ÁˆPP»:Á1˜A?Ž«ƒÜän‚&BÝ!€w3ðð*À´/Z’œ! •gÉ"h Ñ ['= D„Ò<£,¥.M‚Ê©²n¬l¢+ŸË(Nñ,ïc@ü°X¸\´¼Ä_ôÌa ³˜k(I’Y›eº±™>‚fV (M<Êág»Ê&¹ ȶÒe.=�8 ©‘C&r‘Ihä#ŸæÎ‹Èy•¼!=wx£æó‡ ì'y´5�Žäˆ3YAÁIõ@¯ì›gIŪD—EØ.­BÏç)è-eÿêß=JU ¬kLÍòJ‡7Âtt<‰JYÒ2›Þî¥ä#lΕ\ -]‘ 8qš;º 5ôiTôÓýë­4É àYC¥h�$'ÁÛ=Á63²…çl<�ªP¤ú‘¹ZÕ3X}�VÓÅU¯*¬ �‘UÊ:ѳ¢Õ$=í»ÜâVÏrT®Ç”L]¼a¯Ìô«)ŸØ"M“‘å Â+^¾º1±fY¬J;¦Ú„ᜬ!+{Ùß©*šeg_èYЊVy¤ÍšiM‚·;Í'·aXíØZk¶×Â(²umOyÕTâ6·»mÜWcV!´Ï¡Á½¢Y)*µb2OÊuÿs‡éÜö¤‘…vUætõº*ìVt»ƒMÝ5Å;^òš×èm,[Û³ö’œé™o:OrßKT¿oå/%ý›”ÒVUÀï"0 Œ`(X n0¶²5Õçø)MMVÁvá…e˜¡bõ0YA<ܳޏ*kÍd[QüÖæð£dItaê&ЙsÌ.`MÇÒ—åXÇ4 /zücõ>‹½--¬dÇIY7!¹¾OYr~=K(UÊT 2ÂL`-ËŒµ9qía`Û�YÓúÁs•—¼ÎŒš4ëVR¼õ Á"KÓ’*uÔ„ˆ[\‹’ø)x;±¨ù\9c²™.–î e|#—9Ñwœ ÿ­cHK*Œ¥4d‰ü^MÇ—ÓÊì}3³Yù9¹L ­!§šð_”YÕwbµ\-X Á´®µ˜gûg à:^ºŽ¯·êk ÷Vÿ5Õ‡kƒì7(»ÎT¹s=Km÷y®�iŒ«;c9þÕ$6în5Žc¾–û)çòz#›S#£§ÓŒŒwæÝdQß[yùÞw¿¯¼êÜn¹Ë_åÁg­‚©ûî=¥zv‚DF»kÒ¥ë)p!½Â‘Át›0jxËXY)�n»”4§9)é�vc¸;Þ¦†½ó½y¸OCÂ7�EUÓëtÙøk .Æâ!|ÕÄ;oÈö›ä1Y+–!� ÿÇß=òcûM€2õÑ«€ï|‡Rð¦?� Œvùö”ǧ‚öx-ì¶¿ýr¯ûàŒ‡MQïÀè«Þ”«'7ë«Úú® ÿõ‰�^d?¬Ù $%µ«„ío‡»lä7)á d´Ó»éÕàwÀ3Dð„§ ò¯Ń‹ñá³{çw#yßü¾ò!¹üY4§y˸òòÿ¼o„ÞOd ˆ� êeŸ°¤¸§ÀYŸäíuÅíÝžd :v`ï­Éï Í ñ™˜ñÝò)‰ò�]ó=ßEßYLõYßõ@Üi_¸pß»xÏ€Ÿé�Ÿ}^øœ_ꤲ%^þµŸJ4ÞÜÀÿßxž üFý „å¹ûqÌþµEÿÅß Ìß Oà B‰îZˆ–>ÅžìG¾ÄÚžn`ràšGRÝZŒ`�ehÏp�ᱠع`ë¸N©È ÚÑàõIIÃÌÝ�ì «|¤„Ÿøe r1€Î ¾Œ: šÅâ-áûñŒÿu!~Á>A^a¸d![láþ_ ¦ `�~¤¡_ÐâœHì ÀÆ¡ ÌáÔaÞ!ª‰ïE�* ÂˆŠ°ˆÈä !z�!†"ÊLLŠ”È†#¾�¡äˆ$¦E÷Ub^bø!'–ß>È6v�ú]ÿ¡û5!*r¡¶â+&!&-B!èåb¦ì"ôâ§- 0†@©´Çã16@íÍ!3j�3:@–Ǫ€ð1E©\c‚Øhcò"óµàª”�"Šã8*D9ºÝ9šF:*Ä:îˆ%Z&Âc'žË¢Ôãááúd>ž‹$ýE�ýµþ‘"ÜÈâ ¤-äêâ.*¤’1$0>¤µEdVÅD. À` 3fäF’Çïå[S�DH†ÊHj›I*‰£Ñ@7ÒË5±¤ÍhM ¾$LÊJ ÀL–FMª%âd;†€Í`¥I¨ˆQÆÄOž¤×Ý#Qš¢>rG*ö£RRáýY!@Æ¢@Îe®ÿ"ö„"äéýÜBNà~DWBÜDŸPEXvÅXÒaY:ãäæÓ¡eÔ©%S°¥5º¥ep\"‰Ì…Wpˆ“8]SFò‘^¢_&DLf‚4 ù�ÛÝdjädbš!T0¦¹ÈÄcª áEÈ(Z@)^6¦eòã*úãfÂ"¸@¥Tªâ-~¡A†ˆiî�§e¥jêkÂD† lf…lò 2Öæ2Þæææì&b¤%§¬åH´%e`ãªÄ%x9Zr*g0§3:gSF§túe æ[\çºdgançavg’-&r°çxò†ò™çP:%v¨ç)¶g-Ú§f¦+ÆggÎçg:MhÞçhÿ@iîâiþ”/þg€È€‚K� Á�Â!EZ E2h:(„…„–…j€…VÆ Ž††îÆ\v¨r‚èî䈒hTü%Š€ŠÂ‹æ r‡_ÀhÊ(eÐ(=Bf×á(>R&{ÊD’éÁ-eS¢çS)À4*.VåA:)¢¦þgLéYTigÌHlNÅlÊa—ÖaF‚i¬ Ee!Àˆø&�õ©'r,J6"‰‡f@›Æ®ÂiÊ)g�BÅÝižîé}ô©LüiÍ(f€çÈ„ò]\+¶"êdòhe2ª{Þ'|2å°Jj@òh~+U†¡U’ᓞ¡§‚ªYˆªÞ”ª1"ÿè–¢ê^äªêf«¶IeÅê„þæHÔªŠàj†êª‡öêNüê®d¤°îetFűVgŽ$«¬h'jpç³zçSH+µžµbëµj«Žexîã�bæ£j¦¸ÊçÐ繦¬hægjªjx*€BEk†ÜÌ«�šª½Vd¾z)²jÁ� Û�Hš¼Ä‹7y+Þ�h…˜’Ç>õÊlÄ^KŒ2XfƸ¬QóAuQW­â€Ú®íY°Mñ Úýå²ÈÛA Ü-Þ^Óì-ߎHËUÀÑN®„Gx´bApìIDmL(Ÿîí4þÄ(e�äNî_jÎ^…š eèÍ¢ Ý�ÿuMí·Z ‡ð“.mÕ9-È‹â�èRm–X­nB×ê…×âìŽ-‘”íÙæUÚ®­Ú¶-žÕ­LÄm Î-Ý.�LàmÞî ßöípümàòÌà®.q ®I´.ã6îœeäN®äV.Ü\®Ud®Û²ç>HÙ~®h„®èB!éR€ér$ê6m+­.ÔÎÊâ]ÕæÄÕöSí²ÀírªqI ØfÙ6_ïÁï¯ðÖñÆ„ñ^òÒíò2o èíón€ß"šIL/wT/ábï@+÷ž÷~ïã†ÙÚˆïøÖ åò æN¢æ¶ÅúÚEû èæÕëÊ/éÖ/ZÞ/5Îjþ².ÿúÿ¨ÿÆ.Ï®kD×´æ®ï.÷î³­Y¤¯òÂmÃÉ-Ÿ$oÛ­sðó~pE‰°L�pá éá~m {Ý ƒ¯öÀp�/ǘoU ïðªïŒ,JÙ6LÁÛâü q„q™’Ä} q õïÝý¯p( ðï �D&p­´ïöîEoðn1ÞôñËÄ_–ŠæÔm�îFFŠáˆ¸kfÔõ"‰õ^oÔaòuÀ ‹¸�òÕ2GF�³0Ïð~Ô°:ßæþ1û6Ÿ ¿¯ǯ!±ÒnÏ@|¤À6r¼\èxFL(€7+@$3ñ$;q%C±^\òådrŸx KtòÙ~2(G0 Nÿðœ2Œ¤2[ˆg¡*I+à+GiÈòÓ²õ¢3ÆxO¸ìráô²õþòÁ ó0—/ Ÿ¯ sqE çÈ 38ˬ 8GéNó,F¾‡»ó }¼*ëòH>Hóž@?gʈشIL @¯1A—ð-_T«R›«Ó04á^�PüD3Wé1UH‰ã°2ë03kôª´´Gƒ4ýŠ4I±Ik6§4š®4\K2% QpÐôGd5³ó¸3u]äO‡rP#3=µÛ5ǰȢ,uSkŠbdµTψàVÿuÜe5>s5Àxu—‰)0�5W‰šþ¤uò^tDd´iˆ \C¡\#²˜*²À"”þ6@ë¾®_“3`ÏôUc a#ð:/°Ø5°b× PË3)ÓdˆËR¶Rß-o\6ˆ<õktj,sö,çF- ¶ˆöVkáB^-ƒuPˆµjK k7ŽkÓ-ls€l—†È²}2]W3þò¶#Ó3p‹ó_cO`wMw÷ã´îÖbçUs×Às‹ò 5wL·d'tRÛ…e;£+‡fóÉTÇçy›÷dS꿘ö«ÑP¸7D¯¶gµö|'±>³µØ5ó�è7Ùð÷éR3ӱ긅K-Þ­Ê0L'm9ïĉ+8Øfiƒ·G{s®Dø„[€P—rL`ø=Ÿ7[T6v³²‡û3ˆ;ùf¯ô@‹wA#ø`;ùh£wW«·õ²7PÀ¸0Ëø[ÑxZ70íl�Ÿÿù}¿E~Có~Kó��´ ùïï#+ñÝ!yÇô39›—·“öM¹T¹O;7cC·ù–χQwyŠçuo°˜ßá‡g¶™‹8x§¹MŒw¥£¸†“öŠËùW»xX§vŒÃ÷ŒË·kó9Ïü9 ·õl¯ ��Í!!ù,%*®üÿ @° ªƒ—)\˜§¡C#ΚHрŋ-®ÚÈQ‘Ç�CŠI²dH(SúZÉò˜Ë—Þ˜I“"E>8sÚÉÓ‹ÏŸ¥‚ íE´h̆š’*õÄ´é…§PsI�j¢ªUX7i%µkˆ¯`­ˆÛ©¬ÙfhÓÒZËÖªUš4OÉ�K§®ÝxóVÙ˘߿GóÀ�9w.ÏÈÿ(^l²±ã‚|ù">d×îdŽ/ÞÀ¹³ãÏ C4ˆð`àÀ#V®›±µ�ÑCËnœR%Ë•n«|c5�œ:ÿ*4hn�•*Í›*ÔãDZ2к©«W°_Ç’5[65Dè¹y3ÿÇë;²y¾Ò«ß=˜Œû÷“'Ã04dó“}ËŸ»¾ÿÿÌWši§Åä¾¹–Ñ|úWJ·á–{pùN“ çSqÆMx”rI�—ƒsO�ç–tÔYÇvÙigwÝygâ[ƒ‰XÞyæ©·ÞQ¼½_|‡1Ø I÷E–ßjûñWÐ�L6&à€è]‚ ^$d“Ÿ=(@„¾G!M^˜¡†–âåQb¤©¦ˆ$^0cU(n¥"‹!¸h…Žéø¦ â�w#ŽèáùåL>º—¤’ôa9AçM¦%¢ˆ**i€°¥C­Q‰¤±Mj’–ÒIwfLv† Ü|z�ç£:¤æšãµÿ¹gœÕÍÉb#¸æºªžoöÉÜŸ|µ¹j`­JÆ¡JNÊéh�.ÛŸ§MÎgé¥ydºZkËB[¨¡2ÐjC¥®v!¨j¸ê·y¼š&›$Κ•œÖÑ™«®xò:£¯y»—°‚Ul¡Èò§¬³4Kp§Ú6X O{š[[¶œ&Ó´yBïÿÓ¿>ÍYÒž.ýàÁKjíß {eÕijeÅŠc¬q·_ƒì¢©$ÃöÓÙ:¦ ñÚ±–ØöÆpË=/ΩíIÏyïYßé�‘Ñ;!Myáœ2M°â‹CÝxj�Gùjçî´å„xÝ1Øb×E¶"f…²[©­.Û§cž›ê«ÓݺÎ7ÀîçÏbMâªY´ï>à?¢{ÖJ÷~8â‰/ãR;^ äÑW”g1æ9{ �ÞæÄ…“Î�æsÖC[ÊF·½Ò½ f´ øè¥#{™èux;ŸÞÒÇ·õáÉ}ï+Àr7¸Ý R¾s–þfÿ©€ f@ï!ÐcšÓçÿÊæ9Ÿ€N=¢[Y™óœî…ê8Äë"⺻õL„² – u„ÂöÁÏP,ÜÀ±d¸Úà/3üÌ/Öø—¢å8‘ˆã\(AÇ:úF3ŠùHš´Æ>þ‚K�é $IHdò�ÄH¤"­ÇHŒë�Œ$ÿHΤ*˜Ì$[ÚR•F>2’�lÓ3FIÊM®å8ŒH¥*Q©ÊTF.­ˆe$9AËZ®Š:Ôá™ù˜3ÉZÖ²5C¦0ç@Ìb+ ÈLf%7�Æf:S$}l£{G9Ê¥Žv\ f6¢G�`É�kd% YÈCR‘‹ì¤5 JHŠh™äd&5iJF®s.í<‚(I9ÿJSÒ‚•­¨*_yŠX¶b–¾äDÊP\jE—!ä%Ê ` 3˜Å4f¡’©ÌJ>ó£iŒ¦_¦IÍÜ4rŽØ¤„o¶¹Šn*â›àg ã sž�İg$šÏwŽ3žóĤ?uÊÓvCÍM+S)PW¾Ò õ%CêPˆ^Q¢š¡¨E/šQb“£aX&HǪ8‘ƒ¤ÕÜé5SºÒmº¦~äÒÌ|cSdà4§êT+;Û)¢IÒô/Iª NúÊžŽ‡Ÿý¬§R—ÚTFª�¤èTêÐMXµ¯MhkDÔÕ9|•£b%«hµeV´št�)U©6ÝÚM¸öQ®*¢«MïJÔÂÿòu<~�'`ý"XÂî”"²�p‡+X«,•�}¬,#›ÐÉö@D—Åmf}¹Y�ç³ äh·;)³.d!SÉE^ ŠOHÚ…¥˜!"ÂüÎ?Fh®¾±‹!�A_c$²¶…1èA�€YÍüu·n<åx_iwŽg¸ÄU¬[ޛܧ.÷’�,t!*"–j5#Ö½îFÁz˜®—» ž�w¿»Œð˜¼GÈØyÑËMê%®1„$I{ak�øÊõµ/^{OXB¶¿‹ù/`üÏÜ´Àü=0‚mPܪ0x±­,*(#<Õ ë²ÂÛ¤(K.’aæ`™ã‹CLfÐŒø»&æ±^yªâº°¸ÿÅ£ù !I¼Œ &ƒ ðµñ|ë{ßÏE¿Æj�u à¢Ø-G¦H ó²d&+ظŒÍMj;›ÏXúÒÎÑ¥/ýfŽÌx%\î2^X Ö0„9ÎeNµcJ;Í´¢›mMoke3gÛϱ]M]iëg¹VЊr`])G2¸Kn² žì–IwµÒ›.@¦Çí°t’ŸöE¨EMj°†VÕàn «ÝèêµÂzµ²ÖãljýÝ[¿2Ï76'¯ÕlìEã%·äÜ-0”]ï$3§ÑÎ�ÙqQAð‚;;£ÐÞô´™Síkã1ÛÛî²Ã5óíp[šli«O«×ÔÆº#³ »âîÂÀ».»ÿÆ)~Ë \éú—Ѐå·m[þï%\E©-¸ÁSJévV{áyiø6±SP[DÔ£:+~ñ‹�û�u6+ÃÒ·Òz�t.ù\NN‡”£så¾¾-°ÿ lÞÛýF6‚on�œë/fÂ1-ajG{â‹�øÑ‘ŽwÅ0½éá6kZ2¹ã^Ÿ¢Ž»ÄÌN|’€Æ'4ú~ LŽâˆÊÏåí¨ˆ$CûÀyexþ󊬼èa“‰˜âôµÌ Kù"ã>êBv^yÞ∊ˆtÌ¡¨U;‹ô°t2­)õdHšú¦Ô“\æ•oqÁ£…ðQ%â#ªøC0Þñ�ß­ä]Ñ_þíš_(ÿçûðyÐ'rô•/ý,NoŠÔ'3¬‰_{<Íþ‘Üåí—˜cE·÷Ìñ{ˆ|†Ä÷ó�|KçQÌ×€á|Í}ná[¯–x±x^àx�÷‘·}Ýgyr�yá×ãW~žzè§~ìç~¾·Mñ‡qkDA%{³—¶7¸×…òø~8€!|¨^ö Hq è€Ì�v‡GG¸¨�ÙXÛw èß§s#X‚&ˆ‚£§‚¨GKªç‚{Ñz1{3h5Iú‡ƒü‡ÆÒƒÜ¶MÀ„xø°¡%“¤„€LˆI…GoÒ…Ô÷ƒ××xUÔÿâ}!~�´y�÷…ç—‚¥·‚dèƒñ‚‚èzj8O4ˆbnxƒÌ‘ƒrX(t(qÛC¥6{è$}x?¨ˆJ8ˆÉPˆhnQ¸ Sˆ}¸[Ô’�x "8‰âW‰å†¢'†í·‰-g( X:r6xUû÷*"2‡«h],åŠ`‹Dˆ€³hFÏb‹€' ìhVv¦‹=ö„”€eRh}Œ"q…ú6ŒEe e‚ÊpWÍXzÂTKì·zæ„4¡˜I£ÈrÇ–a?�Š9à�ß8Øx1tFEÈ,´8fêhqì( îTð¸fæF�¾h�( .ù’W7�ñ4Y“ýØ\“ÿ�™~Lyz 9H ig•uQÁôk"2‘qX‘ªø�ç‘‘ °‘øÓ‘C!¹Ží˜qÀðŽÑWu¤’¿Øx/ “Û'“GQ“6ùJþ¸P:‰SiIKi†B) Y�Au”H©”ãÁ”ܨa>r‘Q™‘T‰8VIX™•7’%9O'IPa9Õ·ˆ P–.“63“jù7)U9i‰è—1—œP—Òx—�—iÈ2|yQ~É?1 ªÐ�O)j“T˜x˜McŽ‰ŽµÈ˜àæ˜\é•�“€Šx�d‰™š9/œ©–ŸYKÎõ–£É“ré“t ”vù‚¬ù ¯çšÿ…”C›y1›ò깞Ùe¹iRÉ›¿ã›Wù‘&œeFœ¿ðÆé„ÉY†õh™˜) Ï™+ѹ–…Ñ–=`�`¨~¦‰šqC )ž¸Džæ‰èYëÉž·éžx¤›Ž'Ÿ2DŸŠiŸh„ŸàFH/ .:;9zUYã7~·p£8úŽ}�ÔH˜Gž7Å0¤DzWUpÿÇÉd™â¶F„+«8q)A$°q©"¢�·|*º¥cÅ¢.颡£*gd¯D£5Ú8š£&¹£iå£o¤{g]DZ¤8u¤—¤±¤Ì¹�%ÑGOº.ß(¥(ñcÄ¥†Ê]^* `*¦_ÿG¦…a¦5š¦7ª£…xœ=ú£H¤Ì1§Cj¤¯„¤ö~zJ…&ᧃ¥t(¨@¨.t¨®º]‰º¨R1o&©6*©”j"=G˜zQššœZ žZ ze¢ŠLLZªNzª€¥J÷S<ôóªÔ*Z±ú¢³:¦3r\gÚqsévªspj]¬Ãº…xº £Š�hø§-¨Ï­õQ¨Õz¯ús­aš­�º­KÕ­ßšázãZpåz®œš®‘ˆ ëÚ®Œ¨¬¿¯©ª¬:­øz±3DS` ¦´ ̦A6Ó6ˆö©oŠ”½Ç%Æ23 ÔJ�±BMÔîÑ{G�ù»ÔTM­B½L-"çÕS]Õ^Í¥W]I“ôž€²\�Ô_�ÖøÖ�4Ö!ZÖf ÏÙÕj]×®:RyÖ©l×|Ý×~ý׀؂=Ø„]؆}؈�ØŠ½ØŒÝØŽýØ�Ù’=Ù”]Ù–}Ù˜�Ùš½ÙœÝÙžýÙ Ú¢=Ú¤]Ú¦}Ú¨�Úª½Ú¬ÝÚ®ýÚ°Û²=Û´]Û¶}Û¸�Ûº½Û¼ÝÛ¾ýÛÀÜÂ=ÜÄ]ÜÆ}ÜÈ�ÜʽÜÌÝÜÎýÜÐÝÒ=ÝÔ]ÝÖ}ÝØ�ÝÚ½ÝÜÝÝÞÿýÝàÞâ=Þä]Þæ}Þè�Þê½ÞìÝÞîýÞðßòíÞÙÆV5IØ;ß]ß+qßx”ßúÝÉí ^àÐpàÞ­y¦æáa)à?<àNàžàgºàœHÈbFÓ>Á>á~à žkt áàŽÅnà!>â5V&¾(žâ@Ü^wu 4‰áÑxâþà4¾¿6ŽS8þ:ÎR3þãÛ«o^› 7ž–�¹u\q~äH¾»JîµMÅ{ ]!å;.ã=^åI¾[Kžå±å]ãSæbnådŽåBîäÒ)i^âk¾×m~¯úvåáeæ �æQ®æ_®áxžçÔºçoÿÞçq®åONç�nçƒNå†Î˜€<á~…�q\èç„«_IoÆ«:é‡Zé–ŽéG¡éè×éžžO¡¾£Nê`­Æ– ¨ª>z¬híôêUë²®¢¦>á·î¹.z»Y äëÀì ÈWèçypì•G¸Våê,&êξ¥Ð¾}ÒNíœÞ™×ÞëÙëÛ.ìjí‹nìKÕMAÎÀ¶A©íçþìéîíëÞÇåîLïòÞ�æ^ï”~ï’÷ííÎïþ¾Ãóð’Ý^ðùžÅïž�ðe<èçÑì ˆñè´åsAñïº7LïCBSüí …¥o»ñ&Ññ/qW ÿ/"OÎëûÄ‘¡ñþ�òEw+Ÿéò�ÁŽþ/1a¾�äé­À¶—§`%¡jÔ^à”Èåâ] Z¿õKYѺ+æDOàFïHßJGLïôèö¼EןHõ}dõ …õ\±õ\ÿ—^o±yöÁ0öÇPöypö‘�ö;üôLÛöhM�p¿FrïKtOv¯õ]ßÏ__å|ï÷€¿‹§@žjOuÛÔÓ…ƒ‹ßøµôø‘ “ŸÐ•�ä—ïG/I�œ_øk¿ Ò¸økäOqcú‘ß{öúã­ ¯Ÿ ±¾³ñ†û.úpÏû6ãûvü«/ü’Pô®Oö°oö²ÿ�”5LÈôèö¹ïG$ý�,À­túl¡Pìã–ýbŸý¿ý�ßýõý9 @Ì $Xpà/„ {-dHËáÃF%š X‘ÑEŒ‘4nDÕÑc�!W�$YÅd”U®dÙÒåK˜1eΤYÓæMœ9uî´)IR0 À„#šËh¤O-e:ÄéSBQCNIÇêU“Y«$àÚåW�/*d¸ð!D‰+ZÄxq#G�©æ YòdJžyõîåÛ×ï_À} &ÑcFs!Í£”éÒ§P¥Î­zÕªV“]½‚ ër,²fÏÒJ«v­‰¶nßFŠ+—jÝ‘Y¿¦]Ûöÿmܹ:´èѤCŽ<$*¡�a”/ßÐÜ9æ­špîLPØuìÆ´oÝk4éÒ§Q§^ͺõ\Ø«dãÕÝÞý{øñ÷ò.ì;1ðÆÂ‡7>9Çræœk:é¦ãL%ì²ÛN»î¾+­ñRc¤¼ÖPA¶õª“oÃù|òðCŸqDê84±=ì Ûî!Æîþ,“ñ*Cj´qÄlN{QÃTÔŽ"#$o5ñÄ+ïEštR¤‘‘2«N´R§ÄQįô°…ZÑ¡‘z1Æe´ñÆ-uÜ GA RÌ!‹û…Þ{ך*È#ÇÝQʯ²a²ó‹Dæ›ïNó´9ï\çÏëš[ôÑ›Á;ïSW�õd\ßW¿Çd§¶ª>7Ý{÷Ýqà!‡ný+‹æøš5jÞùРFzxÎbr �*²§½Òqo8ÞûëÄ»¥˜�Uµ‹ýnÓ>÷qâwS Þü,hÿ"ûá/yÙóž= Ð]üݲ·=¢u¯5ª[�÷:òÅjç«Kú>˜ê$è:ˆAÌ‚´ $&‘Kdâ\–“•¶„:S¤âlh"Ý…JiŒÑ— ¾ÓÅ1qcäÙ\ºs4¦‘B­9BÝ8CŽÊ cMAî_€]עȓ ‘ˆDIcÃÈÄ%:Q9Pü£JªøÈoäGYœÓ‘2Lf²‹`ŽÉh1ð�±�Xc\ÜøÆ8αŽt¼c‰3„’¥§@�ÔI 4ÈcŒò‡D¤"ÃÀHZ’ÃÔ&ù-&�1™Ôä&¥ÅË1Î�g¡ �.Ké‘Sÿ¶Ž!�c1VIÇÓ�Rkë2Ë`ÞÄ–ØÁ¥.yÙDª<Ñ$é&1©’cŽå;–Ì31éÌgvr‰Ñœ&ëDYÈkv$›GØf7¿©ŒpŽS�®" :éI“uq�îh/ã¹Èy^Ôž÷¼â‡t·Oe^ÒŸE4?é.ð=H—ZèBªÊUFÔ•y„e9MvNé\´&F;GY-Às*ò¬‚PGZE|bñ3(MÆ2WÊÒ$¹Tš d�LGIÓšžò¦Þü¦NÍv³‰š³¢AêLˆúŽ®**JMH›*Ò§NQ%FDÞwÎB)«& œì(M&Ë‹�ii ¹°žÿ‘K«õfb`îB«àšEÛª;Í£%-\�Ú§¹&ò£¿ )=ó:E]ÄV¶|õëh{U–Vvˆ]¢bÛUÇ¢‘)‘uãd‰PYV^6³g‹Ìf;ËÖ¶´¬-iGkÚB¾SµKµ«S_ËÙÎÖˆµýk™;XÝB�·Dð­3›–Çž‚¸m4.r•Q´µ,­Í}ÍHž«zênº~ª®u±_¦×—ÀÄÝ'GxFþ¢NxcK[ò&ϪÌìâ#<üáôvŒ‰-ÖbÝ \ø ²lÌf}SIÖû*W³ýåìÏ<ÛH&´2²îuG×OvÁÐ!rtì¥�%ƒœÿˆ°„eä/)ǺÀp†oËa}}ÄÃ1¬zGÜÛÿp^ÝåŠMÙâÉÚ×tÍšñTHòß®@ÇMÃKrBvl™CãÀ*~Œ‚W[d"ߨDuFÈ’› á ³*Êa˜r•É{åfJKËñzÛû^‰Äw¾Gp17qºf"µÙUp抜uä¨|&„0„YF«]�ËNÄZÖ¾ u­ý%‘‡<´›=àu™2 `;Ø™ v×FòA)BÙŬÍ�Âf?ì¸úÕƒ Eµ­m\ž%1‰þSŒbŠKñ8BÜã~Ѥ!ìYœÝéÎBi¾>Ô¸© ÷º‡Ml| ªûvÆ7»c˜Z3ñ×ö6ÿ±Oyl7'{Ù“êXV i·Ö²Žu+,~ñáÚ!º–#¯{àë¥|ø6ö*�-%e+‚Ù´qö³Å&Ĉ/—Ö¾öd_¤m$r»Û¹xèÎsîq‹ûE"¶ºÑͤ'ÝÝ4|¨¼'KïTˆßù–Ò¾ûÐïUþ[(_âÀ np7"\$ W9ÃMú™‡#æ§øÅ1>�Ó‚ãÅð8È�no’sMì€"ûÊÓòg Qk§6ÍCaÜ›ã\çÝîùÎ�ô¡ýîÁNºÒ³ùî¦sÞõþúÔ3¡o~û;4§µÀC.õLÜä Gù •j„¤�ðD,¡&ÜnñŒG$×ßÜu¯‘ÿèõuçýg{§KßÛó£˜3CùËŸ=bL'¡È {ñÞþ¦ÏOîá=Ýü©<Òjbg~•›�zç§ú«‹¾,¤÷…é'üÔ‡}õco}Ù_ßð„°ùD©ýí[‘ûFؽUê½�û½ÓûbÓ»ùã»úó»Ý‘ä[>åÛ¿cx¾Ôˆ¾`+Ÿk¼n»>¡Ë>Éã¾îû>ðÃ:ñSòC½ó«ºÐ˺ÑÛºÒëºD@Õ;¹CH9ÜØûý‹8\ê¿Û@¬#´;,9ÄÁãƒÀˆ“À ôÁA²À¶À@`ÓÀ�ã@Åð@G Âuã©§è>> Að;A:JAó£ºC°:¤#­ÿ®#àƒ¿d½t½B‰@ ìAi{ t;”† ÂŽó½XˆCa¾? ¾Wi@ÜHäkB'Œ9P#èAa³BÆ«>Ç;�qk.D7/t 0œ‹\ÃÌë&Ò¾‘KÀ?@?SlÃ74ÄCŒ¿6RDã;‘PÁÃå; ÓáÃò¿?Œˆ@¤£"4À÷›ÅL@B:T Bˆ˜ÓEåëŽIl–J|ŒuÃDê[%ëãDqóDK$¸P‚Q¤ŠR|(d8GtDÅ%REásÅo: ös?¢»Z\ÀâcD\œhd^Ì_Ü`„»ÒFe(ÆBœAtCD[ÄGÛHˆg„D ”Æi$†j4Dl4 ÿ,4ŠÇóFk ÁâÇ©(ÇoBÇtä�TÔ¾vdÁô[%x„Áö“ÁcœÅ9¤¿:´?ÉEˆÜÅìéÅÒè÷{Œ!Hƒ”Å‚cÅD´ÇE¬ÉÜ ‡|HWsBf�Èi¬H„œ…ò¨½Cƒm\‹NdþоpÉ�ÉU"ÉsTG"`GVtG–Ìžx„Éy¤Å#XH¥Œ—ƒœ”6¨ìG¢ùÇæ H È…Dº#D¢\ÅdTÀ$´ÃÚhJ§\¨”ÊI¤Êc¼ÊÊJŸûŽ®Ô„¯ôÈÈK� Ë:2Kd@KµLÌVTISlI7ŒA8¬J™”¿Å´I÷¸Ë¼|J'äËfñKæL¦ÊÁ$ÆÿA,ÀƒŒÉ¢DÍ£œÍ¥Ô ÇtÊÈ �‰¤È üÆ*\ ¬<´Ì�ÍìL‘ Ëî#Å4G³4M”\KÕ|G·tIyD½™dÀºlDdš¨|β�Àòêd·S؈ŠP ‚¼ª(?Ä7á™Z«µ»T””[P-ÝÙÇê :q£ uÿSEOð÷ñ¸¸…[x¨îX,Ë`¢‹‹KDJA±6¾Â%ÃPÇŽì†?åÑ¢T9²Q¢(ÖcUT|cT7sÔæ€TžXÕIuÂJ]‹K}˜L]Š'5�(í…:¢Ò�°R UV1Ð-½Ë·‘x�Wœ‹1‹l= .¼PJé¦nšU‘«UÞ¹Õ%Ã]¥ƒ^ýU’°AkËÖCMÔ_MN�Ôd(T lØÿ…VzLØiýƒ eŸ1ÍÖˆ �$e¦%5DM�NÍO­RP%ÐuÕÒvu¹w�Wx�×¹ÀV#Å×üÔ×2áW9òW‚XNX2T†‚=XÔKQ…­6†õSeRøSÖb`ÖcpÖ§=Ìh­ÇåØGõX{Ù�­OKURL…Zý ×q-×O�Kuõv=PwÕš­Yœ»Ù�ÍÙìÉ×4íYŸ]2³6¡X~ͼ£]¢MÚ< ÖCXØIµØ¿½7©¥ÚÑQ>ÇÅÚŒUDjÝkÅ ÃÀY°ÝÖŠèVùÖýÜT(íT)5W�@Wøk['yÛZ{›™¥Y›¥ ¾2RWÓY³7‡a Ÿ-ÿ¿%ÊÀ…Ó[ܦ+\"8\MÜ¥ …¦5Ö«EÖ@Ü]VB%ŠÉe†ÊEÖ¬�KÌåÚjµ Ã[ ,ó=ßÙL*Ùª<Ù”]ÙsÕ¾ó=ߢ%UÙ•Û¹­Ý©¸Ý"uµ·Ñ[Gx¾úÝàåÑáå55Þ‡B^åE@¥¥CÆ%ÓíUÔéÍÓ��XÄÈÞ VAi‰ÌÝÜ›_òU¾ù5ßô[’-[“WÓWÔ%W:RÝ`]t+áB¨ß-½_Š™[YÐß�àßùô_�`6¢ßZ{;àØdà;E\`mÞç}Ö‡; nVCuZD½XÖÚF_Í_¡a.ár›4ÑEŠÿ%ëBFÙÓUÙÔ][‘³á¢õföa�b¨bŠ!b‡`ŸEâuSb\mbg(QÃ}âå�bfÚÆÕb‡…bˆ¥Që�X,®XIæbóë`@ù`12f>c-£”îX² qß7†ßÕ•ß®cè¹ãuÉ㺵]>íßVûß�·"^�#¾= åP[%Þ¢ub_…b�¥É6Ò ¦d+¾dŠ]¾gNWO¦ P® áRsCåÐPåÖ`e†cžR9&8:&C;¦e[Ö¶¹àãHÜå!îåd#danSbXc&ØD®ÓENæF^f÷læ"­f¦^KžÚë­Ú,†Þ-~ÜÿEõâ�íX0¹W{Žîh.øh�F‘iJ )8i”^=Xé‘ni—~ébyi¸š&—®ˆ¶i€Xž^™þi ê¶ j‘¾Š8êÉŠXêŽîh¢žišŽê˜jª~j¡f›�îé% èjH°ëk²Fi”Öi´n€«f€§k«i‚êh ¨k i¤xê«@¾>êxkÀì—F˜¾ˆ¶VkjŽé�viJ¡jª6ë“Vi–ì˜~鍶閯i¬ÎjžìÀj¢6j¤–¥fjÄ~ꨖjÇŽÏéœÖê­Î¯þê°k².kÈNk�^ë¶kÿÀŽëŸžk»¾k‘f ½¶ ¾F¿nmæ~jÂæ Ã^Ä~Åþè—nìÕ†ì)�l=ðìÊvé˾iŠÈiÎöéæ&jÐjÑ>�¤6‰¥ž�éFíÔ¾�Õfmæ~m­æj¯®mÛ¾íÐnÝVëŸNo vë·n™n»Æë<8n:Hîå>o wéçÞ‹è®n.ðìúÖnîön2�éðÎìñÞl­žpñpm¶qp¿nï*xo ×ðÕnnüîiýîjþNÿþïÜÖmÞ&j·ji¯kwp?ê Or‘®p½¸ðê†qÇê•înÊþpË®iñ6ò.q ?q‘&ðŸ^o¿öëÒž�ìÿú–q¬†í§íÚó£pð÷qß>ð��kº^ðâÎëÐFî¾Fr%Ÿp&Ï 'Wl(¯êŸžrq,q-'ñž6ñÓ@q¶þs:€ó1/ó3ì4¿ï5ÏoÙÞo°Öt¿–ó´îñ þñ§r—râFãÆô#ÿëA—ðBç‰C_lO�q¢ž×§þî–ñ‘�æòóöòÀžMçô'Gó©¾u6u/uS?TGkÏ&k7bu¢V‰÷~oXêžvf‡ó§æõ GéÁF‰[é]·nh�ò_ǹ`·rð~ôb?�cŸô.¯tÁ>÷Mwï¥îtÀVt%ŸöÙëk?�xxˆŸpÿno#ojp÷w¢.÷&øju'j<y’_4v§pw÷–Ž÷ Ÿw„j`'jaibic/oJ_ Ïöø£vvDŸwiõ…çoM‡øˆ—ð‰?‚Šê‹w�jŽ7ž·u�—w«&ù’�²“oé¯Pù•×èV3ø·þô Žù žy‘®y¸ydoneì©÷ù�·ê—Ÿp…'õ7‡s£x‰ën¿s 7ŒÏø='ò�çis—MOw«j¬y“?év€[<–Oôh¯wm»wG¿ÌÞ÷µèwžFÒ/}Ï~û·Ž{‚7ógïuûNx¡Ç{†×û½ïûøû4ømÁÇøÿ§ꨟúÁ§áþ¹êÇǃȟ‚ɯ|˼°oýƒ÷õ²·w™Ç÷a×w›ç÷ò.}ÓlÔ·jÕoñ‚‡þ±Ï|اqjwóÙó½ÿÛÇ}Ý/ˆÁïýŸþ}Ňóà~á/þŸ<†)hp B h¸ð!Ĉ'"˜a‘"ÆŒ7*$ãñ#��"’œÂñ$Ê”*¶héRcI„fÒc|ü¸òoÅ‹€oìëQäȘ„ÿ¯têT£×–0cÒ¬yÓfÎ� ÷ÆÐ8µêâ)?�Ñ"êaÃjT»¶-[¸q3Ò­{×Éxèí›1EÔÀ‡?Ü�8dL“Ä—OtÜräÉ%+ϼŒ9¥Î<<÷z.z”°h”¤­žN­zµ’Ö®‰ÀŽ-Û€ÜÚnã–¨Û°ïßÌ ßÏØøqÉù‡Q¨’sK@ç•t$QÇ�u‡d¦ÝfÜe4^h£yGFæ�·šz®µÂ{ðÑ&}&äæÓnùõ6``3ÀH€ˆ 8cD˜R‚ ¾”Ñ�Äe·�OÝQõÝ`á�4žiš‡^z­Ç^{ò_m)®ØS‹.ÂØŽ+Õ˜ÿXIaB¤c�:ç£d@*¶Ü�yᆊ·a“Á=‰^ˆ¯Áf%–¶Ý¶e p}ä¢f* Ñ�:Zân'H:i�Š¢™ƒšŽQt§xú©tÆ©gF‚ž†Gr¨gjf¸Êa€žXµÞE¨¡!º(¯8ê¨J2;l¯—êq,²õ8§| ª›Êí7*¥Ò©ª�KâY^«¯‚µ˜¬YY+·ÚçS®¼yÙ«¢¿6ì°Â‹&²Éf´¬DÍ>ëi¨þQk-F¢z§ªyNä¡«fÀ:X¸�kk}Ý××®ìšéîðÆ›pÂ*5<‘±õê¡ìšÌvºo¿ÓjFª…×9ÿ°¶s‹Z öñFäš+1‹ø­ûWVYYŒÆ˱«˧QÈõ’¬©É΢íI{X}µFÿ¶L‘ÀI¦Z•Á!ìm” /�’ÎC4ñ¡?¯4VCSTtJñ ‹´Jׯ4½"?ýXÔûj�²FWc�‘ÖsºŒ-Ì19³E5ëÙ(¥­â¹\úœŸÜd6é¤*54zU�ú�©«.xD˜Gtì î†c³Í.Pàʇïp¬§ÄðÁË=<`¦À€žÿº¤8ª¾úÔ¹ì7Èníµ_p;îº×Æ;p¾£¼ðÄÏ8;aÆ»�¼ʯÄü Î?ï„ø MÿPõ×÷•ÿ}íÜCå=]Àǘúq„|À3ßù°—>ã±o?îS üä÷<"à~ ÉŸsÐ#ím�0¸Kç"ÀÅPP#äa¤Áâ10ycùóRh¿‰`Ð1»sX1Œ�å�ìƒø„!g2œÈ ã‡%2‘x+ü‹úÈ>Ä1G8²ˆ…DðˆTHõÈÅ€¦Ü0‡8Ü!EzøÂ#QˆD¢�‘$†‰MÞ%¢Å-JtÇsá(bE,j‘‹1ô" a'F2ÆŒgt‘í&¢Æ@fd ÉŠDÚD‡ÍEŽ&4`DFw;.ñR½ÊcDö8?®�‚tÊU‰€.Êðý‹#¹ÙGQ‘”È$5bIà`2"šì'¯äIŒÐñ!¢ä)ýp©ãÐa„4R FdVJq9T< -ShË:¥Œfô%§Ò¨Fa ä’¹›È1“¹Lf‚"ÏÜH4§yk•)‰¢+—wÈZ&Òzl¤#ÑÙA`®³’í$æ;3©IyΉõt¦C IJ}"†Ÿ€ñ'JÚ¾5V0ãŒ�sö˜Å*T�=d'Ü BxNt"t)©DšÉ�Œâs£h¢¦G9’�žD¤$)NUrRƒ:F¥X`)$Ó)Ɇbd˜Œ)&DâiÓN&õ!:UÈ=5’ÏŸî³dƒ*6Yhº!ù ,"*±üÿH@e(DÁ�C#j˜£â›‹F2jÔx¤£G C.I² IƒR¦À²¥J•-["¤¡PCKr60Á“§…Ÿ\ê£h„£H‡(Ád‡§~H­yÓ!ž =yVØZA‰’¡=x°AÖF޳e¨]; ­[·kcÈ�[¶®Ý¹s�åÊu¢_ I Ö£g‚á !+XÌ”©;7Åz(ê‡å¡C‘hÞŒ)ãÆ I.8Iº´iÒP¡bXÍZôÈÓ°cËžmp&Õ†³òô[ÆÅ7¯ÞtH�´¾\SÀòÍØ^È0ç’�YõbvA¹óQ¥CŒ§ÿ–úã6 «X³òõ 6£Øºgs¤]«ö­ý¸xcØÝoë%zýÄ×VM$Ø`…–X‹)PÜc‘‰E™e8lçÂfœy÷YS*ˆ–܇ †(∥”uçå¦oa”ÑpÄ'ÂqÈ%÷\t767�MÕ餛v˜uçxâAEžyèé¶ÞWB…5VYñÍGŸ}oá‡výçU€ XA�€˜a‡!¦Ø†"@È�d^¶†šyš¡•Dâ�xæ©§‰4¡h•n&°è›‹FÀ(œŒ"°ÆÚ‡9ÆÔ¨L'òˆ“�Ùµ���ÉáxSùéPz=-ÙžïA‰YôÕGe[VÒ…eYZÿØÂ¬-t9 ˜IÐÚ˜ ¶`ƒB¶¦„EQh!œHÈIg‡vêéì³ÐšÆ'’*f%èoÁЍ¢«1ºŽßêéMÖa×�CašÔR›Ù©¤IªÇ{Mº÷$YQ¢šêª¬¦ºÖ~\Æj�®¶ò…«®¼–ù+šj¢Àf±nb†¬²ça´güì´žâ资zŶÜzû¸'‹Û§¤åþhi�F ÉîŒ*pZ^Ç j5/“.8 ß©6øËïþþkWÀZLkÁ}˜+­ +xfÅŽ ë0±•EœœWçk‡-vˆÃ[mO ÷¢¶2r‹�É05wÂÜtG·#¹”žûrºEmÿá÷ºáµûÔ‘8+¹ó¨¥âßY ²5t¿SÚ‡ôJÏÊ4�N#L¦Ô 2lõÔùp,×Gq`ú²�­úêÒÞ�›Ç+RÔ¢Ú…²]œÛp§D÷î¼;àûï®Oz�Ë?]Ú÷ßßÍì”»7›}•á[ÑÛ³½?/Þ¸ª� -y€üÁ÷à õæ¾Nl„“….ú›¤G`:¨7Ëúüô—]ÕÙ»É>(í"“¬hîà�Oð;à�«GëTñ`æ¿mpEÜ»î÷3•õã¸ìík{zX€À>§‰‰|fêÕÒô9¬QftBÊûâ6úÙpuö{ÝÇô‡­µÁÈ‹²ÑrÿØ»: x-S`Pè@ .*|]ÎL ªz‘ê^fY\®w€ÇA®ƒn™œ¸DÂïæŒzSÔʧÂó +}êS_™ #ÃÓ­ðk£¹¡Å–ÃÁÎZ< ™íƒ»ÓXõªù�NÊ~zõYþ¼ @‰7”�…sE¨BIÓP‡>T¢õÎQsQŒ¢@£ £<ê�*,1#ÕAIwÀÕ”J…¥-•ËKÓŸÌ”¦7Å©“ÚS1ýt;AÕ6ËYªVT©;ejS9ðÔ¨"`ª†šëU±šÕ#<µ°_�í�ÂÊ�±ÿ*°¬^!h ÓšPù±µ­+x¨àQŠÎµ®Åë :º¿r.°ƒ…-TŠØ¸¦ |ìF"kÓœRV3>ÕP3ëÎv6µGíR 5ZÒÒÈ´¨…‘jWˇֺv«(•­~CD[ØVoKt�YíYPL´·¼üm[»Àà—Æ=ªm©\æbƹl„®Ió;ÝÃV÷ºŒÍnEhjîÀ»<¯eÅ‹Yòzż›õì‚Ô+²Á¶´RE¤ŒC_>ظ¤¯åð~‡,›þþwš¸U‚nÄÛµž¸+h°ƒ‰ ¦¹†`Âs¬°^ùŠáj˜°¦.bAÜX hW#&F1*{ Ëb&ÿVr‚1vêÇ;ÀñiuŒÞŠöÏAî*‘ #Ë% Ô0Z ¬Vß>¸Rfðƒ«|ÜÅQ˜,]î–›RÀ’tÂîðªk]Åb÷œf1d¹«f6 ÆÍIöOœaLg;ÃÐïͱèüçšÐÀ.�¡c€è+ºÀÅit‚ Ò(Gº “.�•±\&-·å'\ît¾,Ý��:?1X¬^S ƒQF²‹Sï~`-8{Gεm�}½¼˜Ö´®YÀ|W‹ëãûߤv±“¼äÄ4ÙÑi‰Ÿ�éLSZ–Î2¦ózí½rú¯Ûþ4˜CííçGÜ'·¹ ƒîø¨ûUdÿ±¥d$3kó"j®êET¿¡rï¨æÛm3ȹÎñ\H€û\ 'k»s{Vd7FÙú4‰ÂyÇð†ßàá�xµ'®éŠgãܲ@¾ýñSË´"#Ÿ@ÉÏrr”«|åh9g_ž^ÐÊœÞ5{JÍpsné|ç?îùÏôÛ]ÉEß-£œô‚,}wMo8˜,te©ÆÚÀöÅŸ«ñn ä ˜Ï<¸Ayǂ݊ç¶i{Ëþª³¯\í›EÔÝsލ·Û8$4¯yݵúð<™{ç{ý{h¡ ˜è|² _šÃÓ-ñ/ã©ýxª[x(]iåµ€Ìk¾ë!î¼ÈAOrÑ�–ôX2=ÿËß cÕ¯¾õ2š¹Üeþöÿ˽î›'ÖÞûý÷€>“ï䄳dá‘ætO§|ÛÑxñqi6�iÏ÷QÚ–uwyÖ÷›çužWnÜ'vÞ×TàÇâ'¨æwwèWêgoì'îwwðDò·_Ïq0ƒÖa‹Åy@±hfb6Xùƒ1hW@(<ÖÁnÒ>H±¨F¿ñrNø„"±l�)P…)àÜ¥FŒwTíõTOø„†b8Wb(†íåz7†_\Ånh\5w’r-øo/èƒg0ƒ9147¨9¨ƒ<èxxAhWáõ0”!��„N§„KÿøMø…q……Sh…W˜…b²…Õ…4"‰qP†aH†¢x†éw!OU‡¬ˆ1wèƒz¸|ø8XS:X�(ƒXˆuˆþ‘ˆqâŒØpޏ„‘ø…”h—h…XYZX€\8Z^(‰¢h¤X†¦H‚¨X#¦±Š­ø�{²ƒ‹³hµXb·˜‹$±‹¼È¾(=CAò8�PQ0Œ™VŒLè ˜Œ±ŒUØŒ7õŒ˜1WžxùV�×h†£…†%‡à‘óóŠ2¨‡åxŽ·ˆ‹#…‰UÈŽÅ%ïÈW.0�ôh�ø¸QúxÇ…_£ŒTÈŒšx V�MõTù¶†'ÿ…P:¹“:‰“,€(ù‘9”|$ŽxHŽüÒ‡Hð‡&X™y ¹bˆ¸$)�õ¸ ÷hI(&�‰ü(‰þH™‰Î(&3Ù‰ÒH#7‰“<ù–à“@éBI”v- ƒHù8™‘6õ”QÉSÙf,†WIY™[Y]y _¹’N˜oÑPe)�6µi¹ I‰$á“pÉ“r)#AYswYš¿´hç5xjCÓ—~ ˜xè/ƒùjZRFp˜‰‹©\ù(&¶)'>)™A™/�Ü…™™o9wm¹†Ÿ¹“>ÉœtIš¦Y�xò©¹šÙך~h‹¯É‘ƒ(›ÿ’¶‰›ÂÈ•�è›eœ8)œ@œ˜h™€œ™¹œ'Ø™nùœ�÷9ui�ú!•�«IN®™‘O) º â©jDbåy•r‚,º2+5p¡j›ˆœ®1™ U™Çis…göyoÍÉUú¹Ÿ8)�¢ñŸú¢±1 h§�Ú�Fn&–  ª  JSJ’ 'Úš¡e´¡íÙ¡Ãù¡Åi–7EŸ B¢<É¢øéœ)ÊŸ&:�÷£^*2ºr4êE爣ܥ£;Ú£?ñ£¤ôèZ¡Gz¡*#š:ð “‘%¥‰A¥;i¥#á™Yº¢ý¹.ú¥ˆÊl,Q�ÿШŽ*€€B%0©”j–z©€2›�a!ì$'à:)¢ê¨ŽÊN\"'핆*ð6¦‰ðª°Ú^ Ò ý6–‰z«„ÖŒJª�©ºAN—¬`>º‰ÛÑ©2ó©¡:ª¼jª‚ª£¥ª¬:Ï!«³ªµÚ’¸º­D¦« Á«½êt‘êEŠ©ÄS¬©¬ä©Ÿ:Ë*àê¬z­M%­BôÖ:«ÙºKÜÚ¯úå­2®¾šäDN™:žc!¿éˆò®à*gêE¯ïc¯´Q­£u­Øº�üê¯ËO+°âú«û8ë  » Û ‹P¢ ¯¼ ± %±¦C±Ôº'ÿzRx–o×±<Ë:Ë«Û#K²çº¦'‹)‹+û-û°0±Þ‘ª@Ó*Ïq³,�³:[‰=ÛµcS˜Žj›ã:´«R²>z´C‘´G±´:Ip·0«T2Ë4kµ6ë>©µýçµ~6`;…c[Fek¶ö(Eú4³’}иŽk› è¶·rû´1˰§˜gT{¯*�µ[Û·ºÐ¸bÛ¨d+²†{¸º‘¸bâ¸�[F‘+#oI¹p;·I%'®UW«·Kú¹\+ºÂ«'¤;¸$T¸©Ûºâº� ¹’(¹@»`»;…±¹»¹›·¢q§Ÿ;¼àÿ;ºÍ¶Æ >$F蛾©»¼ªFÎÛÐû…ÒK½ÖKØ›¹ºË¹)á¹À¼áû¿R¼¦[F盾軾ÛÁ¼‚ñ¾ñû„óK»õ{¿Ú¨¹«ª¿À¿À Àì,Ñ¡üÁ¶ITDE„ŒÈ’,QÛ�2òTtHùæ�%jZ\Ã?×ÁìÁ!,ÂE@Â%,1p"gu‹(,ü¥ñ™«ª!q¨6ÜÄÀ†Ã9¼Ã"ìÃ?,È"Ä)ÜTDL#-|H<ÁJ LìÄdlÏa›=6WU\ÅW cC¼Â\lÄ!²¯c\ÆvšÅ1š�ÓBíÒ…ÊÓ=½†sÙ¢ô<ÔL=”:mÔG}RIM6ÝÔVlOÍ-QÍUýk¨K}Õ`-Y­([}R]]Õa�Ö±5Ö¬QÖ,pÖ_­ÖrMhl½n ×A=×zMdu�wÝ¿h½×‚=Ø„]؆}؈�ØŠ½ØŒÝØŽýØ�Ù’=Ù”]Ù–}Ù˜�Ùš½ÙœÝÙžýÙ Ú¢=Ú¤]Ú¦}Ú¨�Úª½Ú¬ÝÚ®ýÚ°Û²=Û´]Û¶}Û¸�Ûº½Û¼ÝÛ¾ýÛÀÜÂ=ÜÄ]ÜÆ}ÜÈ�ÜʽÜÌÝÜÎýÜÐÝÒ=ÝÔ]ÝÖ}ÝØ�ÝÚ½ÝÜÝÝÞÿýÝàÞâ=ÞäÝÔÏ‘è�ÞäAP–Þê½Þ?ðåýÉçíÞ ß?ÐÞö�ßò=ߌ\ßî�ßúàðÝßþmÇþÞëý”cÐàÎßËqàwœàè „ îà á/!á¾ö�ΑžááNÆÏÑŽ qá®~â6\æÁ‹,îà.nâ0ã2.)4.â#~ãžãáK½;Îã…Xã ä*!äCN»E®â(€äc®$PåVÎäàKä;åRNåV^åXîµÔ „f~æ\2WìŠIîæ¸:ævUæg&i~TkÞmîæ‰ ç%çfNç¢æÉŠçLªç·Êç7ÿáçQ \ò˜ƒÎynè^Šè ñ`Tèzáè™23‘.é/Jé(`éö�é@ñ•qI„ºž~—3ê¢þ¤þ¦®¨Î!»ê:PnJn&E:ëQë4së¸n�º®â¼Þ¾^¡šîDþ³ÅN”ÇŽQ±˜ì°ìºÒìÂn«Ñ^šÓŽ73híØN+ÚŽMÊ£­ÝnšßŽ@Ö!îòë�xç¶íéþsÏ�y»ó`ÁÊ%½AL_ï«l·?fÖô.ÑŽðû ßß/^ïqï_�ïÄ…¶èïÿ¾��!µ6Fð˦t ß ßŽß!ï8ñ¿øN7fñä†ñÿ–­ÿÖ'Ï#%Ïð;ÿð*�/Ñòsóòºa!ý>;ŸË]8ÿñ†·óNjOiòAŸòCOô*aô'€ôY¡ôK_îu‹gï¿þwò¤fõ>>â#Ž2K¾õ!ñW€"öýNöoöQ�ö¿ók_]RîöpŸr?÷,?ñ._ñI¿Kl{ÊO¿aªþ÷jø,5øn?âq÷‡O÷‹o÷���ù¸›Ä”ŸóÑ!@˜Ÿùm¿ù°ßù†ø\Ÿ^ö=�÷½aú˜ Æ©/õЬßú/ ù°ß಴_ûpûŒöÆ:‘Î0|ö°±ú¼CüÅÿúÇÿÏùpëùrO½^¿£ z÷ÑOÓÿ̈2‡Ö_31Î47ÚoüÇŸüË/þŠ?7ä/æ.ºðQÐà„ #,d¨ÃáC%v X‘‹àØ‘ÆG�'DŽ$)òÅI”)O¦`ÙrÌK˜1e¤P3ÀÍŽ9uîäÙÓçO A…%ZtçM¤Œ.eÚÔéS¨?A: ŠÂêUYlÕ a ‹7aÅ2dÈÇìY‰¬e{Ñ-ÆŒ“Þ\Q×®¼y¯^åÑ×o À�³†€ÇðaÂY ,ÐØñÈ‘+VŒZÙòeÌrçfæÜÙ3æ©U÷¢¼õ@ׯbÇ’�pmZlÛ¾…»‘ãÿÜvïæÅ;…ß¿�'†`Âøqâ‹ :v|ÄùóÉ?O§ÞwuìÙµ‡và»4W¯U‡eÝÚ5رe? ][sRÝuy÷ ¼¯ðá‰�#O¬ÜóÆžƒ.:í 4P¨ëTpÁ¦¸óN+ðR¯¼óЃm=öhÓè=¤â[a> |³� J4±SÜÏ8MôÀt.º´ñÀoÔqÇœí»ÓÂh¼7(J7F/RW}Ö[÷m Øc'´sÚ] —ÜsߘóÎ òàw2‚bx‰T0¾IÈ-3üɺmq–ªåíiÎÛ ôR ½øü/MÖ“\å²'Í €w_ñÞçÀ>ñõuåóÂùÐ7ÿõ­oEís_¬à?dMp ¾žðˆã©y ÖfšÖ¡æMKqЃÑôhÈ# À�€Á·g�îUð‚�É (FуHŸúØGBÛÅJtòC"ý|`?üé�2ôß™@P‡Ïã!àdF 2pˆ1(bMÁVÐKLaE)z°Š²!] Ç-¦p~_aáý\¸?öÏ6p\ é’CìpqY;%uÄ9ÖñˆxÔ"ùèÇ'2S¤÷cÈC*ñ‚[Q¡@ÆŠ †3ôäP,€Æi²%œdK/JìQ{¤$¥)…ÃLÚÁAšŽQeqMlÿ¶r W$¡3GGËE®° øÃ%$u)Icå—Ádã&Ýøœb¦³@• å2™™Ç n š�“&¨©JlfÓOªâfû¼™ÈZdœäÌ_.wYFyþd�#&Kˆ¹–ˆj‡žÉ¤£=ï9=ꓔќfcªÐkJ‰ …ÄâAcÀEÚ„¡ 5çC'™QŸøê ;åiã.ðS "A¨C½èpZ™ †Í•Ñ?ŠÇ�‰�$õ§IŠÒÃÆ[-àjW‡:Ô „U¬.…©g*ÆH’ñ¦Gõˆ@žötd@ êW‘PÔâÆZ²–¯’6¦ÚÇ©OÕ\T‘µÏ¯ôóŸ€Di"²j˜­v•ÿ«vE‚XÇ*Kᔕ‘ %'Zϩ֣椭óyëGâºSŸÒõ”Å+ õ*¾†Ê¯ Tj`�3XÂÖRˆˆb­ÊX¬>6²’¥¬eÃJVEvq³>8«CÑù¿ ZËZ�«ÜܦÕìæ§V §- B —"Ð/õÚ;ý@½ëÝ(I¢"•–"²ÏcñÐüæ—™­j¹`©3$! YB� l`*uEÁmHÌ�+DX p…E÷SK¥ˆ\@µ,=»–ò*0ºÒ½uKb]`· Ú½w•+N€W¼æ$oy×zÞ¹Xk½ìm¯ITßøÈ—¾À±o~õKJþ Ê¿†ÿ°<àXÊ ^0ƒ]àà"@X®°…ñƒaÓh8V«‡s bóšmÄ$V’‰Ý«’Æ©˜Å.ŽéwÞñÚøÆgËq¨v¬Þû8%@Ö��ëSßÇ¿ûM²˜õß/ÊQ–2‚§Te+cYË[î2…/|� £hÃ?íp>ü€C—�l^’›G‚b9f»ÇI¨Adœgó ½KòM OðÞùÄ·´Cö‹} «¹F;ÚK�v²¤¡\iK3Ó´ÓôB¶ÌåN:ÔõJ}êTSoͼ�«Eâ=Æ:³fQwã;Ï8-zÖõ\ æëh•Ǹ0 ±ûB¨c U´[2ÿ›üäC»ÀT^0µlíkwšÚ³¨ÇLê2›ų́Nsׯ­$ߘûè® ºÙ](wÛ:Þ¸÷ÏìM0|«D߯í÷¡�ðc¼s'áÁ��p…3\ÁÏ2Ä9�í/ƒºâܾ¸·3îŽ ); "ÔDNrï}šÎ^¼5�ÝuÙ7÷. qˆ3sËÖ|/Ãù=O$(‚Ç –å™´�µªª¡wÎçd¹ö$Nñ­(»Kd«™Í‰fˆNì&_£@å ViZÑ ëßÎÉkmç…àÙëû�GQ‚Ù×ì‰A»X h_¶¯è©&‚Aë]w¬(„[ û³ |÷?åý+{gH|ÿÿû¿'}ÛÝþöÆ[þ.¤0Þñƒ|äk0y &}ëËízZ¾žx2}Þ_PýèSú°žþ±©ßÏêKäú×ïüoÌ™}í�¾Ü3œv¼_Èï��ôÊ+=ð?á'`xµà8ìS—äûšåã–æ‹<èÛ#飵”üÐ<ëã¼Üí# Té>ïƒðã7èA=di;fb=ôƒÚq¾Z‘½*�ðjA°;È»{ú‹ûó½ô0 0Û?¦ë?Œ+<�;<Ü3\<,‰Ç“2\@­sÀó.xËõI?…L=[Ö@kVgÅK•DÔÿU­ÅÚ¹Ö{ÊÖ7ØVæèÖJýVÖW:�N5‚O$+µÐtÅ€u]@q×TõN£”WÝ W°WÁWrÒW¶à×2;¼ù“€}ª�•Tú4Œ##Ö XØ·iX¢´ª­Zˆí1‰�X­Øh½XºÚ2ÜØGÅÖ›”T(¢T‘%Y²0YW•-W– Õ+}Ù˜�Y!x½Y0Å€V…žW=¢ž�YuôdyÂð–£�MqýÕ¥½¯aUXcíS„¨ÎªµÚ‘ñµÊÉZþT*hGp”,® ÛÎáXfòX�u ‘íµe¶í ·µ:‘[—M׺m×»�•¼]Õ½íÛÅù[ÿ ŠUÁÍW­UÃ�Ä ÅÍÄòëÕÆ%ØÇmZÉuÊý˽\;¸Úöâܹô\®]ÕÝ ]kÛŽ-[m=[nMÛ ×ÄHÚ°HYÙ�Ý1êÌR…žS]˜wżxíÝyõÛzÜñYüÚµZI*–tO¢©22$Ls4GæZ)Ç8 .ê*3Øà}3�¾›=>ŠåtŒ2(aÖ³‡M±j ¡�!Çö¡,p*±Íò€®°é �} Bqa •}‹\yـыѸ$Nb³ì /©Á(’ˆ—54ˆ�$NâVQ0Zi¢'Ž"þ$ÚZà]mà{à›Œàšàžÿ n N. æ`ãòàka>áÆ˜)VVnIF¦�â2.žf †žÎΊÆI ž• Öš!N×"¦�½¨b$^b hâH#‹-�(6« bL¾â®Èâ úä.¾¦F¶.A6ãÜAã f� 6Œ æª 6ƒ.�¡¶ãÀã<ÖˆëZaõiaG®�@¶¬Af€B&‹CNdÇ\äâXbãâXå÷0âKÆdMæäfód(‚ât•bR®bSÖTU¦d/¶càØL#㙤åZvÒ4®�5.€6¶yc_Žc`žca®c&ec>æHfÿ>^f?nfÚéÀhžf†¨f ËalnäÂ|äˆä#xpÖq¾ L¾�rî'Ng.^gQžbØiéwŽgÓ™gRÝ‘VV±Wf›1–å2ög°e5Æe6Öe7æe8¶,Ó:Î,d!æˆ>fŠîâÜŠ?î�þœæÈ�¨á¦°ô¨¦�ÖæfæfËò攤Xi«hé—V‚˜u&Uv¾éR,ž-–iP¦gVþbWcXjô›eFj�Vj‚fjƒ.„þå>�ꆦjK±j†’èŒÈê­>€®þН¶�°¾QÒ6䲿€³V¥´Þ�m†än–äo&ìp¶d–&gÍQ0s.ÿžѽÞœöëSìTì·.�þ4l Fl¡NG¢žI÷ûç™|l’-éå^6±ÂlõI¤Ý"%ž0IááìcK™;ÖØ7=:mÝ[�ðhÖ†�—µü+â(¨€«0ÉkäÁ qžWbR"—~bˆjop)¾ Kâ¥Ã´î.�jª0�íXn{Æg¿ÐçX^웜nÜqì�v í¶îÞ`ï+ðŽÝ2 f*o28o=No‹^oC*í�ÞmL‘oúN�ûÎï°Úo–²nÙž€ÿži ð¹ðÏä�•_ˆopp«ˆp$žð*«ð>¸p ËðÁÙð›øiÿì jðPl×#L?j€¾e²Èn9€í^ñŸ€‡�ߊÞŸ•ôVfGö& ÷® øþqòXˆ ·ïtÅo+Ðoý8r’öopÿpK&ð)0ð‚¤riRpUÂò,¯i/0 çA gq W% H Ϥhœ{¦FfžI2GÆ|sò•s† s0�;çî<ï>o<¢ñ0ÁÞìÝã.ðžˆòàq°&d _m!�t"Ÿ#%3Lò%ì&ßô'ïô(wé)?”*�€+Çò$\‚UÇCiu3ØiXsY/sZ¿ [gÉ\Ç]W­^g�„È�_Oê9�o‘Ï÷ÿÒùnüHv©Š f—gÏji—;¯®vDdEÇöˆïFŸon‡tR•tJ' þfërQ'O (ÿt)uwu+/uSŸ÷zO|×w@Šu ˜uì¨õ‘¹uxq,xº:x²HxÜYøÇnxæxx‰øc¯x‹WvŒôÖxìåxU™vù�‡æ‘—ælNù´òI/òJ÷¯€ùLgò™�ku·yvÇy/y÷xopŸïrVÿrWó}ç2¯3O �@•]¼’jõÄ8ä¾ “54€Õ­¦ò˜©ÀÈ/¶OXé* Šâh•-ÙF»w!©A‰ó�z™¶q/é°ª�‡`yãʯÿãH‘خ֨°TÓ…´ žJõ%¨s;/‘eƒÂ••G*d�ôÔ‰%É ”°Ÿ¬ø“?W Ñ£ÙótO§kç=Ù�…"R׸}]QI™‹Èï“É·€éµ|Ì¿6Í_ÃÎW¥Ïg¨Ðǯш*laðÂ- !0lHða 'R”(ðâÀ‡4¸è¨çc„�"9�,‰â$Ê*°Üè’cǘ5fN¨Éç&N:­ð¬ésBƒ &†>LbTæÌ"C–áôTRWP=cå’¬ Y²œ¨äkLb=� aVZ§"X°�*ܸ æJ¨ûâ.Y ðe€ñïÅ‚Û(lX!â-Sÿ3¾áø1`À/7¾©l6„ÈËC†@�êömÜТG“à4jªQ²>)äõć1gwœY î+ºwéíÛðà=†¿|yiH2Ê—«Œ´�_Œ ¶@xqC‡#VìâÆ˜õ �PÒdëæ\'ÜmÛ'Μ;{þ*”(A£I�ÖPº´éSž!@Õ V��•Vpu€W`u$–y]†–j±õÙhs%P—w½�×^}Eö×`„VXb 1ÖØcŽ�ˆ{•½q\HšqÖÙg •¶#�p¡–Új­¡ôš±D›{3áÅn¼ùÖ[pÂ7œqf•·s*=ÝEÓ”ÐBÙA°ÿwÝQô�Fí�W^mº)¤z-M†ä{6ÅLJN:ðdE}ö50” EU[RÈ(ŽSUuÕIY-±W *ÖXe�•–Sº•!]váEVˆ|½X‰œˆbŠ+.Ö¢‹££eVÖhÖf�=�#=êZÚ�§©Fƒ�CÂ&‘lHz[nM^¡³ÍF Ü”TVy%–d4·å_^Væb޹�™¡IPx�„œ›o¦·’œ/ÑI“�ñå¹gŸÏ*è~Çú7Ij%:à¢6šà‚’R¡¥!Pha[›Š¦!‡‚A_\¾Xª©§¦¨˜ª¬Þàê«“ÉHc6ÚŠë®)‡Ök¿ëÿÚ°k¬mK*»l³Ì>k@´=T‰rÕZ«ePgTuÖa'&™ÔQç]¶iŠwn "¥Û&œìÀÞ»5Àwç¼ôýd/~èÇß¾Lõà­ŠÈ( ŽBÚ•D_Mú`¥LˆéZ ë(W§~ªÅ"ºŠñ©6l¬êƒ 댲–Lë�:¬rÊ,¿ÌZwÆÒ¶¤ÍÊæ¬ó³=ÿ\ÞfCdé\ÑQCd�uÝ5ít PK'µ¹äEPuHWç ä‚íÂ0|LFß§Zj…m…‡>‘h~ƒº`[Úæ­�¨€ˆà£ FZ·ƒ.@(á¥fêw®.1¨…‹êªÇ‰oÜ9mv¿9É&w†ÿÿ—c®+‡8$$�Ño6}8 A‡›ä9et*ØYÏ(´0¦nuغÝë`w�îЮƒµ—ë*P.¬ ]Wà S¼­mdx0(ÞñêÃ@,¯y5y¾Ðf¨ëýK{p“›÷èf»Œ| 㛦þˆyêCí«Èâwª0&ö‘ ]82Éé*üÀÿþÇ£Öe€¬ªbG˜@ÎÐ�Œ–ù¦– *çZ­ÃàC4¸ÁŠt0\g áK¸ߥP…Ás‰ ahä1°†wqÞ} g6éQo‡ðWöƽ¹1|w_Þöf¾¾aH}jâÄ ?V%ŽŠAÒ#“Åámÿh“ A­ö×?%б4d”€[„F¨ñ€ „BG·€e2“Î|fG9ÇÍXðŽ]ÚŽ9H»îÔë9A�šÎ5È+D$ñ:b¼Eʰ‘óaÞ#oÉêË’˜lÀÞ&°¸ì{C ßø6AR†Lœ §ÊQyl…®¤,¿r$P´¢³„A-3C9[}± ½Í/ƒù˜a³ÇLfΘÙÌg:3š3¤ãÐX�$›|ÜfEºéMpNMwãLW9ÍyȦÓëddòùHþ©lg«çx˜I}n2ˆ�üç'ª·ò1¬”¡9(ûj8†²Ê¡Áf,+jÑYftV¸ÿ¬Ü:ÊË�Š&¤­!à+iSÒ“2Ð�*]&K[Ç—R³ŽD›)kªAm:�›õñæ7qGBqZ�œ…<'Q_¨Îþd†Jeê½¢—¯é*ª—d›[|¸O Ì“E(ÑÇ©S"4•c}QCÍêωDT U+.ÚÖ[æÒ‹»L]áòƒå2· Î}.cÖ3™‹¡º"¹žt2ƒí6«Þef\pµÝñ’w¼¶‚J]N Þ8ŠHø f_rÑŠŠ¤OfiN Bň|Å…uòI‰šÓ®`Ä(Yüˆêã›<5ë‹r„Õë¨GUŒ¼íˆÝ¸Ê%︃0„O‚ß j(v�ÿR¬a‘'qȽ—/Ð¸Æ ±q ã³G?>þ±ç’d›”Çnv.Žéµì ÉlaÁ’[æ6÷¹Î�n»Ð™Åêáº`Ó.w™åÝ€7eå�Áy�Þõ¶÷5ï{æKÑúÖç¾vß~Òßáýw°JÌ’'áÀzHðO¬“óïÁf¯Ü*|â pÃoípŒuc7‡Ä%>qŠÍ°â�´øÅ ÎÑhXvcçxÇ:îñ�cdþئV­‘skàæú»ÞÁ“}ýëÐûÃî–Yxì-[7$ØÍÓx�Mfh§ W¸9Ω é%\ÎÓÕöœ¹]goß¹bá·×jòçs &ݾˆ�]ˆ`÷†ÁÌr0À=a<[ßÖ7ÂgÕoµx8ë!x§ npQ‡=¥f¸Œ}ôðUßÌÕ¯žLÅ�|ñ!ÏÄÖUZÇ?ò‘‹¦ä'Oy¶YÞe—Y1ó³E®+›ãüæ:o³Þ|¿ÿŸgqÛèö·ñ|t>“[)L/€Ó õBKýÐT?‚ÕU€õ€¸Þ®Ø¤ÁÞK�Ý)e§=ˆ9­Ojíû~û©ãUÓ]YvÇÅó>Ú —ÇïÆ¼—ì”&ƒ¼×„'y°_ì,gÖ…Éfü²fŒ¹Ì»¢|å/om7c›ó.ô<è‹Þ—ÑàNK?}êiÞDÝðL]¢UÝ¢]]£™�íq]î)Á¾qÙeÚ‡Ú ŸÚyŠÜî%ÜÂ%_A1ß�Õ�ÝE_Þ]œ TŸÆý]µÞöñ”}_\0×zA×ø-ˆ–µžO)̕ט�™Á_ÎIÀzí\ÏmžP‡–Ç“ôÿ†�šè陸‘^Ò™B¡º­»½^ìÍ^ííÜíõEwPZŠÝø[jß٠ܧi`¨ŸÂ™ÚÕ5ÜÊÌÝ:_ â�ôIOLô‰ ZÚõµ 1Г ž  ª— NA|]” ñ ³�×zWæHåY²Ùüe^ý%¡A,!r4ácZ’Ìö‰[ÖGyôæ\² pgòtc þÏ€¢\(†>”ÉHe@¦Ç5Ðèá!ÆÅ¯¸Œð=`LupheÜLI4‹Z€ãÍD$R Ö×Õà—JÍÌȈO¤‹YÌË¡íYÛæÙM}•Šö‰ÿ€æ´æÆEUMœIÈœµãžìÉo Ír”ÇΈ"÷qŸ…)™ŠéèHèÈUèI`h†ž•Dl(‡z¨Z8�ˆŽ(”h�\ Šþ…Š‹¾�‹V)³Ä(„Í(Ÿ¾i:-Å䨎òè‘t„�Ö�†€�ö ‘‚¡‘ú¤ )·)©®9E“²Æ“þE”r•r€•þ–f©l)—’�—> ˜’阖)­ŽŽ�ª) °é…j(-±¨œ‚hÎÔéˆâ)°œh$¥¨D¬(‹*ªªSȨªÐ(¢j–¢2*~9jÄD¤.ª›) )‘NX¦Z'§~ž§~(“öŠ�Œ*F”*;MÀ©¦*æ¬ÿj–º*—Æj”Ìj˜Öª­šiÎäêl®€…òª¯b°†â§Š�R¢�Þ)ž¦ÄaвZ³r¨³Âh´ê´ªØèµ¦‹ŽÆ€¶rkeüè·Rj¸Z긒«éW$i‰,i¨r‘@é,I©¼R)½Ò«¶ªƒ¾*¬"ÇΤY™:®-®Ž¨®ò*ìŸ+ƨÃÚ©±J¬LQ¬Ç^¬Œd,´Š€´®µ~l¢â¨È6ªë˜ì l›€kòˆëtº,Ì*�ÌͲ«“n"Îf‘ÎÎ+ä©£”á ¾ �¾‡Ñ’)®$nY>ìò lÁ²)Ô&¬=.lîÕF,²6• T,×¶¨²¼ÿè׆-cŒ-Èš­›ŒlÉBêÉJjÊVê�\*¹òÜÜÖ­`Üí�´«Þ’jΚ*Ïþí¯ nоjáÇᆩâol2.jdó ‰Ór…ݸÐDüažÌÐ_g±ªÆza-Ám®@ÄÄÓHDyìFì5 Ä1‘�nÙr¶ZGêº@·Nê ìÊ­¦žëéÕî¢ÆöœbÉÍ~oGìc}”ÀëGáJš ír T³¤Ùõ"¯â2nóf€�T@/*N¯ V/]/Ãůl¯ðuïE€¯AxðR�/Bšïª¡ïk¨¯µšn›tB¼oü¦l ô°Ó/‘®ÐËÞoÌvêÌîïiôÿ/ ü/ñÄÿ„7YÏ&pޤ™¿rŸ3 ÿ•'îË�7okh0ƒ' —'��p «÷\ wDøZÀøêFù2Ëù.Fúzlé²ïÙc§­ê®-ë¶møð·Æ¥ ñì±Ý"q(1ð»@ûÄï@÷’ŸW7Ù«@«Ô£L//³†³DôO#Ç«ESðŸ@—Ø%×ñ_A«ÀOAcD�®ïçµï c�Ú²m˜…"÷0îN˜#1ÝB²þª+ÿÂM%ðpR0IpÕÒÕ'ÛJ(ïÀ(—23�òâ>¬*cpWØKÀ¯ø~°NXï_…ñ-ç²Öv³ ð2r¸°-æL0óEs òé_2_Ó¶23;ó3G³£L³¹1º16'±6+D;1³‡3ûnà^1(�N™¦óyE0;{ÓžÆg°<»r×sõͲSÔ2ãîó ˱ÿó ã´H´ô û±1{ëB òèðê2u3'òDç­4�KƦbtþ€íR²G7ñ%gò”’4'›tr•sgœ3KÛŠK¿tò>l@!ù,"*ªüÿH‚ÎXÈ¥¡C‡."J„@q‰E3ZÙÈ…Ç� =~ dÁ“¨\ɲ¥J0c:™ù°¡’›BrêŒÁ³g�Ÿ@9v ©¥¨Q*H“2Yª¡©N�—ôÌx¤ª X³jÕPa€W¯ ŠíÙ³†Ù³ZÓfmĶm…·pÈ�KÂÔŒùèÝË£¯ß7€/ÌDìX²1Ä(^,¥ñÇ�#K˜, 2Ê˘3 ,É9@åωÝÙ¤æÓ¨S <˜áÂ5JœXñ"^B7†Ü�bäΧ] oS&Íš7•<͉8Р¹w=šéখ ‰z×FÕ#WÕfÿåúÕ«‰óèó¨_®ø´mݶ¯0—.Åî÷òõÛ7°`Â…Ö@s‹1æ˜G‘IF™eª5èàƒFˆk­½D³¹PWT·áo ùœfÕˆ@q0ÍäDlÉi×Üs?åf…tÓiQ�uL9µwÕªz~ôĶÜ2êhv;ZÔÝwá©%ä�å �© ›æ¡¤§D ï¼PFYª¤§ZùÁ¾ü®JÇ¿óËï—ŠIf‚g¦Éë «ù毰É9,±vâùa²Ë*ÛlÁAKŠÓ>Ô¢¡ˆa›- Üv{ã·ÚE:i¹i�{©y™¶û®§óÒ+ª½÷™Šªïë/ÀÿýÁމ`™ 3ØðÓP—PTËÉEV UTß}§§`g¬li_–�Ç zœÈÉUiO&ófÇÜ)o›T xc‡Tâ"ÿÖõ�æf5³º5oz³V[[”³¼J’áøãÍuÈÆä”­Ãå˜]tÐG¶[d„šÓQ—nújSW-'ÖY'¾ÄßG|¶Ødcv6Ú+·"µmó-UÉVê9·u?qwÞzƒ»]ßdÁóx‚§»®ÍóÕUìÖ‹G0ÄöÜ?9bÜsOyåAcž¹æF‡¿ýbž‡ºè£Ÿ.éR݄լOì:ì²; 6 µ3Bp—»­Í!msóà< ¯xÇkAò”÷6ž8/pÑ+Rá�¤$ëÙ)*ÙSß¼ç¸æˆp|“³œùt 9:¤O}ìƒÌç : ŒWóË!Ãꧺ åoXûû[ÿÿþ@”Àé5H|�KtG¨Þ夂1ˆÛnX·NÐw͹`Ì´2¸é®zt]ÕGB2˜P}(dƒ Í׆/†'˜á jxCÚqW<¼ßê°’5<±kC¤]il±$"‘ˆL$y7²åýŽ,R SfÅäaÑo{^S¸(½ ²ŒÖãâDXÆ3†/�k<ÑÜÈ=8Ê‘Žñ»£,Ý”:=ú��­Kÿ@6ÿ ²3„ì€! ™HEpwls¢#¯Õ@¹Ñ­ŠHÁ›-ùÄZ0“[ä¤�D½öx¢Ì)IhJñ¡0•—kcÐDèJ÷Ñ~ ™¥<%ô€zÚ/6ƒ!€>¯×ÿµ½ìå²8ã’ô Å³ŸýÖÀP~•‘�(£’“•X´'‰+Àã8B¹ƒE¦ e誳iî-\[káw€Â€–ºTI rb¦@Óšf�8ÍivÊS£•±FZØME@Ô¢*à¨H5På™ 8õ3#š§TTÏܳ&ùܧ�ú™›tv,IAjЄ*´ "u( #Ñ R+½F·¦QÇqtr… H« R’2Á¤�ò]TTZ–º´¥0u’LÉRS›..§:åéN}JÂ¥†d¨E%*R“4Ë‚¤VNÍT�5ÕÒž¦ªW}HV ÀOÄøS†ùª/À±ÿ’Õ¬ Më¾ÊV"¸õ&½(O2ºÑ�tti Úk_•òWä)O°!ì {ØÄÆg±=i,Mo YHv²Aûi�„ŠÂÌjv³ PêxÝ™ Ð޶l¦�ofPÛC‡¬¶µdymcûÕ�е%d-kÝΊֆîv­½ý­‚+×áÒµ¸V8.­Ê¤\†ú°Ï­fJ5·R¥C1%cµË]È~7 ”õžg?‚ÙÌ¢7½�]ïgËäÞÊDU¾8.}miߥ蓵[umWa ÐþŽí¿, ðbC`Ý~€·lU0ƒç•º’á®lÈë *ïfël”;Ÿ Ï{æ³icB`‡HóÇ?v]O @lŽüÓÐ`[�²ÉæF1Z¡FëÉã":žä©¥9EÖÁB+ÒåâèŠÌq°§£û/¤Šú9¤&!ª`»Tw÷Ä­&ÃÉP ìz¯@É/6šlwcoe×Q׺æõY}�7`ëSØ÷Ù'÷»Ç½îÿÞ{ßø_~舯0ãÇ÷ð=´|Á–8Ãæ|VàxEy+@6Ô—Ö§uØçuvÖÆ}ç}!'zâGzä§7;�zŸ¦z Àz£æz0{±wîð÷wò»Wö‡¥À¤ãw¤;*Â(8ðƒ@ØG¢p ZçÉg5\à*Íe7ALw(Ïñµ½äõ@°…\¨^ø…ÚÑ!¨‚{i¤j´Vc�†jˆ{¸W+²u&gÂs6ƒýö d“x˜‡E¤ƒGwL=x#@„Y3„DhFtH8p5ÁtLˆNÿXqPhpRTX»q…#‘… Á…]ø…^˜=bh%dˆBfcÓ¡†kȆyç†_u6¸0{ȇ²Èƒ3áƒ�ˆBx…hˆ4v„-‘„ÁˆÒ„FO˜#éŒ� �œˆ“â¤>cÈ�(䓦h@”Ci”p)O¾ÒÅ„H·ˆ£2*M™ »•RIùx‚i•l•=LwX-%”ø7Ùƒ‰3i @–ó"B¨2–y™”ZJ–‡yè�ß”/ð–q9š:4—uIw™—Q²‹FК®Ù—vV9*=!˜W@˜e˜‡˜  ˜É˜‹ã˜�™¹1Fáãa—‰™“£™Æ™xÈsÿóÒ9�£1¢IšØi:¦Y—©©šsÁš®Ùš°ÿ™26›QR›ƒ©>½Eº l¼é›;�)“Ã)™òÒ!È™œ�™Nµ™Î �b3�ÔY�ƒp�Ùy  ³�ÅÔ�Þy–‡á)ž…X<džõ�ž·©ž½Õž?öža±˜]3Ÿ_I�ögŸ€Ÿ0¢Ÿû¹œýÙœÿÙoÑ) ?@ Úo‰ 8ª+ šHëÙ rñ jãÉ-ŠŒG›| ‡~ ÈšœŽ‚ŒÆ…œ3ÖÆRL¸…8NÞóÈ·ɼJ6_\{aœÉ›ËÆ—kŸp]CrM×€=šv}×Z�×ó²×”#[ØŒMš7Äs^­Ÿ`]#idÕÝØ˜���Ýo‘�œ“=•ÝÍD�Ù¤—›mo�}™¾á`zC– Ä¥ÛFyÚà^à~àžà ¾à Þàþàá>á^á~ážá¾áÞáþá â">â$^â&~â(žâ*¾â,Þâ.þâ0ã2>ã4^ã6~ã8žã:¾ã<Þã>þã@äB>äD^äF~äHžäJ¾äLÞäNJ(�2—¯ _OÓQ.åÅAå¢�ÜWNÏY®å0Áå¼íå_þÍa.ædŽÞV~æ �æZ¾æÈ}ÙnËp.år>Ôf^çv`b»Xå|žÌUUU*¢"�ÿRŠ¾è»˜=Þ=èÃ[èõtè3‘è‹®è�¾8�é£+é@éN MÒté˜^ˆ"ÚKœËžꢎ7¤^™ž3²¦©ŽÄ«Né­Þ¯ëó2ë2Zë�ësé-R/0,ÙÓBiˆ0“1�ÀÞµWÇ(Õ¡$ÆŽì‹£ìcÀìàìÏŽ³Ñ.íHAí;sìÂ’ìš³ì ²íÒÙíÞ.qàžâÞsaí9ƒíÚÎíì±ßîñrAïóbïéŽïùž®û.íýþó^î×~îÙ>ðë^𽚠Î( Oí}4/׊Sƒî�q&/ñdJñ”nñ ŸÈ//Ïÿðßì/òeÿJò‡nòýŽòY£ñËñÿâñ¶¢î? ó�Jó8í'ïÆ)+ßò÷óB�£D_‹7rñ8?1:�²òÒy£Oo”QߎSôRœôKßó.ÿóÓéõ_ŸŽÃ~# ¤ â*iÆJÛ;—|&t>séé�âésé@Ýö§ñöÕ÷s/ u¿Nêƒ÷®ÜÇé}}/é/é�߃Oø™aøI�øNB÷Úe÷Càøy÷Ê‘_“_è•_è—Ï™¯ù—Qñ7rÈñQFf> B  º{/©_U«_U­¿¯û'!ûÕ�¤úHB·Ï= ¢»ïœ½¿_OÁ_OïÅoüÿ�üI¡üÒÆü‰ûД¼úQýpý�ý°ýÆöŒþ]ç=Í¿=ϯŸÑÏ™|PÐ „ $ÒÐaˆL¤Xq"Œ5näØÑãG�!EŽ$YÒäI”)U®dÙ²ä@'1eR¡YóÀMœ1tî$ÓÓ' A? !:ääI_,eÚti¨QQ$¸ðÁ¬YklåêðaDˆRÄŽµÀåY´iÕ®eÛÖí[Ž0eƬiçÍ�<}ö *ôÃß¿I•:%UêIª­^ÍŠ•kW¯DÀ†+¶,\Ì™5oæÜ٭ܹJD�¾‹7oŒ½|ûr X0RÂ_dÏ6 •#ÿܹgìæÝÄ÷ïÑ£;~\#²äÉ•-[ôÜÜùsèÑÙ‚–\té§Q§^ͺõÑ×±gË®�àvnܼ{ÿöm]Éð7Å�GžF¹ ùõ_–Þßÿ9£.&÷°Ó.52ºû<Áį¼óÐSo7öÚ³>ùŽ«ï>ýöc.@CqD�0è7.R­+`€ XbÆ%|*ª¨+rô`G sàG ;Ìï"‹ä(¡„žPrI&št²(£4aJ*°òJ,­Ä .w¢ãËSHá2OXáL4ITsM6¥3± U­Ea”‘Fo"Ç+xìÑ) �„0$$Z’I'›Ìÿr*«\4Ë-»ÔéK:³L4ÓlsSN;eëÍâäbÅ_Œ‘Æ{ÒsOýôÀÇ@¤BY8TÉDͲÑ)…ô&.ñðÌïÄ,ÓÌLWðtYf›- TQIeÑÔ;gÌóF>]}ÐXgý¨Ö[ŸÈ•‰Ey5ÁW,#vRb[3Ód�•wÞy¡õ-ÅQç,ÕNT¯Å±U? Ûc`‚½õ¨VV˜NËåÝ+Õ¶Òb/%3YeéÕxã6ím_ië<OUõä”S˜à� îa…f¸‡…XK`%��RK�Řc ƒÑc�õ�–_’Éø—Ï+RN™¨£f¹åÚ>RÿáêºhŠYf†kvb‰Ù¥Ã¯Þ%S?M…V{íæˆ–S :©í·dV™v娥žÚ匮V!k*¶vaf¯{½9ì�¿$ÛìÐ>“mÈ#ÇÌí|áÞwdkéf`ó†zê=øÆÈoÀ'|ׇÏyÝÄÇ 0ÆÏXrÚkw‰ò�åNzél]õœÐE€ô¬Mïu›U? ؉·¸ñüÒ¶}zêIÂÝh‘«MUi¢6ïÓwσ¯Ú#âë2žÎEcT‚ÚwQÄ)uþXÙ°ÿþêó×£ë-?óíñŽs;ú�ø c5¬ok§ÃÒúbä¾÷ýjy:“ßëþ»è�é~øÛIÓÿ�ň@„# B MXžA¤P…üé K>¸†5˜Ï ¡¨ÔF@‡;C}H)J96 b�HÄ Kdâ„f€/|½HŠ ÈC­Ø,fq [ä¢{hØ(!„q';›„÷gá w8Ä"ñ…P�ðwÀ#ýD:÷¢Z„®ŒcgAºÕmw¨nõ•c�äZ7¹B=�ò¯_�Nóvo½Ë~ï¦È|æû®ù„Úžš·û/ûê~‚»W„MzGßžLÀ¾�ØfOá³ÿtx§oZñßaüa¯'Q³ïÜè–âä3·u¢t]å¥fù \þù³‡>íÔ›KLØ]xf'äÓ\i¹×™=´‰^Ä_þl_îÿnZÞÿÆ÷7³•2ŽªY¼â;¾I¾X> 9Z5=Ñ–W{µs“ú»LJ¨?yÈ@}ƒ'ê>'ˆ’(9½½?†!?_Š€ó;9?92Y¿‹X“…K½Ñ�¿ù£?û3ÓºÁJÛ?þó?oÀ%@Æ#À¢0@T@U#è|À€!(\ ¤¿ įmÁ@ ä5ÉéÀîA(AŸ A:1ÁxBÁ¿@¿ecA4 „6ÿ Œ¿ ¼Á´¿”5þ»Ü4 ÂÆ[�ÇS¾åCÂ’»‘&|À(„¡)„ *´3¦È@Ø@gY8'â¹ðÂÞÃ!Có;C|½2YÃù |C%ˆC˜Cû«ÃÜs¼*¢>$¾\ ú#DÉ[@%l@WqÂ'LÄEtŸFl²¥€DIlJ¬Dõð@LÔD2àDñDJAËÅä5öSì>TTEVÌ=W_¼Ç`tB},ÆöñGËÈHäµ�T“Zé£(¬4ÁáAƒ×xG0B"$t«€FXJõÙ‰ˆH(a’5ìF�@«Ì ú ÄPºD?oƒ˜Á¡¼@ŸpUÌ8U\”¥l„¦›„R�Šy@m¢¹‰¶Œ�ˆà½ÜK¾ÔËÔªÀ L 9JBÝz=û_éÎËü΢TÅñÐò$ÎóüÌô Íõ¤JÒtO¬l‰œJË8Ö´"ׄM�ØOþlUDÉ´ÌÎPJI¨1hR'=P1Ñú¤álQ¼tо„•@á Œ ¸Ð ÝÐM¡E’¯µ­­Lÿï PÑl‘$µRÏ,%ÐtÑdê´QÜ€O�œ­¢@̓ÍÏØD÷I,#µM$%OÝÄ&'}Ò¸DPW™Ò©Ró ãÔR áÒñR0M�ÄLÃXLêÔI]ºmKÓ‹[MŠÕxÓ8\Ñ ƒÖ;”y5õ¤�âÓ>ÅÑÄÔúÜ´A-Tý”ÍöQÔ\€[ �[ uNQ½YuíÛA ž­ ÿŸýÙÂÚ¤@ÜY�S9Ú:5£;}YƒÜ�q2M•@Ø QØNô6íÈ8c�ͬ݋­ýÑUÒÓ�VÔ�T³•�Õ�¤“­¶�]¢hYouÞg¤PÂüRÜÝ‹½%Þõ]ÀíYÁÑ4Þ{=\ÕWùãW:}Q;�Q<�Ûç��qZ¨` 60êeë­Fì= ä*,¹Zîõ\­Ý\ ßñ-_:`ÒÔÙõ•$µ¥Ò×]à•�ß·�_®ß e˜PÕ_Ýå[v=ÕùÝš^ÂEÃ�ãÝWäUÊÅ]Þ2jÞ6È Ö ¾`¼k­¨­Þ©ÅÜ*ÒŽ¦¤~X¬%aï5a‹Ýÿ^ÜÓ-¥�MßV¦¾ÔÎTÙ¥]ÛåáüµY ÅÙ ÖYèX´Ýø ' L\˵4ì0—ÛmI 3ò!)"JjÎÛ‰„Š)ï }<ŽE*¢á&n²+‚ñÀ™Èš œ@m1#8hå�*Rk!Âä2 JÁ$Fº°y¼d�x9³{2»Êˆ„X�&`:^Ž�â3Ÿ n*'™p’ý›SõI¨ˆp�`ö Až�Àe‚Ñ0D^JE. FÖcGžH.#I~J$K»¼ÈdhÚä[YO&&P¾QV#R™€¢©>÷ÂU.£V†ƒW.©XžE¢å#°å/Áå#ÒeÍ;fÿ_Î5`®%aFb6fwÞ‰d^f§hfYzæ&‰fòœflªf§˜�kîŒlÞænæ•on„p¾‹q¦BzdÏ;‚tf€u®¡v¶¾Ó€gM’çC¡çÈød" å|Þç=ègèöhWaeW†e �å…îåZŠ[~�\N¯]îh®.%³ûežÒgŒÆˆa¦ßàh¡Î‹�î fV#gŽ hÞNiŽj†k^k—ž1˜ oþfLZd^id�&;žî¡I®d¡hlŠ)üÈ,©çõ1"¦e§†j(’êÂî°jƒÆj­^†vh:€h#’èÈ«É6ë³Ö‚‹>Õ¶ž�߀kí˜k2¨ëÿ ¸k'ÈkË&ß“æë”öë•S@ÞŒ—`n&l™6lïd¼›n‘œ6ç�î韦¡ Ö¢Î¢Ê.µÂI{^ê+¨«Z*å˜ðg.mÑ^ Ò>hzJèuÜê0#Õfí"rmê‹l²¾oìCkµRkÛÖh·.æU=fÞömànñ.Ýↀ¾ƒ¿bælçŽéF™iLJæênÎr^‚snl0xlvöï¸fh3¢ìðÖ€ñVjÈôÆ#õvövom‚¾j„Îj…Fí²Îo°Žh±žèÿ®hÚNë héÛÎíÿïi»i¼.i½Žð ¯ðåÖŒæÞ&Ñp*áðéÖ­‚.hÅÆnÿÆ¦í¶€™2� ‘‡¦wqäÙCõÑìóþŽ•yêõŽê°»�`yï¾H(ùž'ú>+¹Ë�ò H!‘þNÊä]Ê�€ó®æ¯mŽp"'Ÿ× èÑ-!Œo’(yp,É8í¨-Í#=ÍŒ./â/‡îFÑŽ/¾2oå3ñìæ¤5oóö²ô#€�9o+ºó{^�=÷l|©¾@ÏqøÆ¦BO‚C¿E× Fwt!ù�yTÜF¨ôÁo Èt%ßrNk4Ý<ú£QO R§òà6u(Aõ+QõÓ`uouuΈuš(dZ§[óÃÊu8ØõWsÈŽ›`÷2"ö7ö*BvÿóVv§¨ñÿógG/¥i¯öDÐE÷ê‡F mïn× íÍ_â•w ÖVRA3Ú“·àš„´œt2-žÓåA�»~º (¼'Èk艈rm¾j‚½šØ’¯V6j£­©f¦{ºá¢6 ·Üs×m7«xç½wß|8ǶÞZ8Œ‡ûªx#Œ«“�#+üUU2[¹³µÕœ¹o›çí9J ¿ ÿúפݦÑÞ$®Ô-ÍNM#�º`'5ÙQ�vV³Öp'1Ý)Êk¾ëIØÌ36«Ï.Æ{™Á’Àp1¯m ô¢wªéQ� ½‘çö‚’ìio{cÜQd£#Â.2’ÙI,C¾“‘Çq¢q’¿z %æXÅ}1›€lúFÜà ŠÛ‚çþÒ7”¨D ú;JStÓ¿�”n„§ KÈÅs0]¯ëӟȨAI PôÊ�½xgÁÑeð24H à±ã1Àc4\‡Nè0´¨ÐD,œË ÈÌ�†6C¨Bu#âj8=Òw"Ä�,.SEDß�8—Ä%V…50k–BE+¦ ÿ‹÷óËÒÅ/%ŒQ#tþ÷-3"òIS�Y‡À7Æ.Žs¼Z³V<în?{ì_ òÇr� œ�ÇLÒ·bšÐy(,U#9=H~†×£dCh8„Kf²C›$ÊÿòÉ q”˜)Ÿ)‹È$Uú‹•hâ+áK-õ¡Š8¸¢‹²ˆK¾qQ%¼$ƒ/™Ì ”aGC£v”¶ÆÕáÉu—‰Z ¦Æ�ªÑÑŽZ£f·Å­ ds Ûìæ­Î#ŒSaå|:ÓI¢GÊ%’©™ä*™=zÖ3#áäÇ<>¡ŸDb@É3м%Q ^ý*]ÉÊA‘( �åCkÑ[~ —)ÿ±(èÀÈ1^�ŒÂTêÒ(Rï�´u „ãìäX»ÛÝq‚y´¦L?RSÜ´ABŠ!iøX’ì´§lsÛó‚*·p¶³ú± Q]ØNI¾3©ñ´¤ ë)§bª2Úg(ƒxUR”B§Dn¸�®~Õ«a•PBËj€³ÞÆ¡5�DÛJQ]Â5,r]5`¬Ž®�yÇ,à¹Ès2”ª”¥Ðté4 [ÍÞñxd;ÙÈfo²K¨,ßȉÙs>l³�åìggZ£¢©Jõ[j›ÊZ×J•/‡³ªL–ÕÞä¥ ámoëDXòmŠÅ¥eslÉ-.÷­^Œk/çúKªL÷®ÄÌkÿH‘™ÝÞlW·Ýu`K¥¹µ˜nK±æõ#z©ÞDz·oî…ïä«ÈÊmb\82’“|ä$%ɽ6x2”ç å)g§ÊrúPX å-K¡Ë^V­—½Ü[¯º Ì•‰ÐÀ¬[… Ín†œã|J)mF(nv3òÜ›mÑY3B�2”ÃÜå–Le84¢Ÿ h$³S iÓÌHHÒfêt±Ð–®HSšB7$GwB‘~ìQ¬ ê�ºÐVþªë —jÎ`ÎÔ“±^óš)ÐºÖØË^§îÜf>ðº×‚–‚•Ç"l$ ØB5²’“ÍäÎ8Ð6˜2•­\e,¿nÖ˜=f5”Ùg^MšÿÌ9] Îr.bŸñ`g]ç {NSºÿìì_z"ˆNô¢�ÜèGãáÓ“fL¥-M dš)›>r§[ói¡„zÔ¥žÈ©SÍH¬ú³:¸8Æ k'É!µ¶5Œä™k]÷Úׂö°‰mìt";ÙI^6š hhKYÚÓ¦öµá–í0o»Ûß¾J¸s;n]›ήNM�%Ín=†Ï Júœmz³¤Ð÷>´¢ŸÀè¢~†ßþ.¥U"ð�\çB°p’4Ü ¤�©«Œê/¨ú>ÇøÅ5nžXwüã´¾õ81Dî’óšêÙI¹ÊplU¹\É0—y”inó¤a9祢w~�lÿŸSÍ–RóÐï\t88é~Vú�ÛýîæÄ›$R7¼Õ¯žõ­‹ÖÑÈë·BÖv-Œ˜.øÙÓ¾ö%´ýíqÏÎÜ뎨»ã]ï¿"MÇ!à÷)žo2<á ßÄ[ñé¬X²ƒ$÷º—ææŸÃä[byËc^á ÏæÍÜyp[ʽœë“J�¨“[õM‡÷Ó�^ÔÍÛÉU�½É^¾qÁ¾ÝÞ×í^ïý^¦߈i€§åÞdßá@ÄÑÝÄUœ~à]ÞuP–|ÅWD_§ÄJ¬\ÉÞØYYûuŸP�Ÿ’‰Ÿd�ßd�Ÿä¥ß ¬_εßû=EüyÛü]ýMÖýaHþ é©êáÿÓ)�þÙÔ½^ž@ìÝÛìé×Ù^…@š.Á¿™DÀ jZNpÚV` ¸ÂÄÉ�ÄÅ ÅÙÝ‚` � †� bH�¤àp`_ɵ`•½àÊÉ ¬� ¢]TÐ`ØàP…ù â ÛT¢%òàµùà&“XE^DŸý)DàQG²ž]¼†{¹Y¬â)•ÔÉ› ô�—I"¢b²�¿¥"Ø1FïÎE²m ç¬[ˆš1Z�$~ˆµåÎòÕ!Þá�Qà! î!uôaÆü¡®Y™$¶Dû Õ!&¢n0¢#ÊF$ Üö�…%^"&Â�&¾'‰'â(¡(ÆÿIé¡âd©"+‘+ ,Êb—Ñâ¡Ù¢’áâíé"uô"Ù10*™0æ 1£¨%cµ™Þê4’�4~…Èñ!�ø!atQi£ÀÍÝÜuc:}#« !ˆ£ ’#ÍI"%¦ã¬#;bÞ:Á;†F<À<>ÖBŒ"c”"s †>>?fA+*á+ºÞ“ ¤dd’!d2!Sî¢I0¤ïœCÊE0¦É0¢E"£9êU,ã5£F‚`G~¤W„$u à5–¤IjJZšJ¢K6’KªLÊ$ùÑ$´Ù$:â¤N^On¢’u¢A|bÇ…b ¥I %U(%Bèb¬¢Súÿ#T¤TÆ"ßÌâZž@-òÇ-Q.î£WXþ"YB¤YJ$ZR¤E¶%FÒa\>c÷]†�]2^ò…Œì%_VÙØýå¦ æC*bLÒà8BbM¦æM¦ccŠH;Â_dÂãdÊceÒãeÚ#)â£.%1‚æSš"Dåšæ ¦¥µÄj®AkjWBÂæB2$mRAY6ÇY‚a›¥ånºåÂ¥Mlä\Hç!aÈqîErîe_šsBgôHgmR§aºbN™b:NædwÀwaxåx eye=Ù=†F>v&l~f?’Ç?re@žæ@¦f~î'‹õgWþg/è€2ÿG�º‚¦¦2ö&ƒÎ€ƒçQ gqšD…ÆÈp(g†NĆb^ÄàÇ$"’ÁÜô-m”cïm§% ÕZÜDÅÌ‚UFP˜§›õ�1ên�sç@™ê¶0 jÔçŒ�jõd²ýéNäç,„lȆ$c"~•ÎA¥*Jˆ�¨2d¨t‡‚Ò™’i~�Ü�½ŒÊ3¥âQ[X„EÌ*Ι ‘©™.Ù²¥©B¬iv¶éb¦#œª…œÎ)Ô)eÜ©ŒÆ@žòÍž‚NŸ‘¤&A ’Ä >Y¡šÁ¡I¢ÒÚ¢² À=*d&ÙµRê§^*Qdª¨mªWuê§Æ@¨Žÿj/–*wœêL¤êaÙ«º™«ò¬ÖÎä!^ûÙjE ž¾Â)¯¾¤ãýªß©éC°éعi%kZ$ëœ2«8« ²Y›é©¨ñ)zø©¤fël« të·†F¸NÁ¸b¹Ö¤*YºÚO¥²«¸«À«Èë§Ö«�j‡˜ª®î+¿®ªàéZÀîÅÀ>PÁ¦ÜÁ"¬Â-ÃâG¯ršFl°Nì°Vl±¾)ÆÎ„ÆV Çz¬¶‚lˆ¬�l˜ìŸ¢¬Ê²lš ª](jÞ0ª£Òì¹"ÙÍÀ¼ê,Ïú,ÐVªÐ­ ­f‘ˆÒR¹5mD<­N¢Ôbžµµß UÃæÃ2°Æÿ€°&f/ZìŒ-ÙÚ„².«( Ú¦¬Ú²­ÛÂ- RÅÇr¡jÝ‚ëÝŠkÞ’«¥™«;Ú¬¤ªkβëà:,pªÎÌëáÞkÑæ«Õ®L/õþk›AîH®Ò÷v/æî$}dn:mîtž)Ä~œÄÒÅ éš.”-«œíOXf´Á´†Eµ’ǵÊmÞÜ®·æ®Ëî.Ìö®Ìþ.ß/º/ÎrŽà¦¦¦"¯ò† ó6„¨­ó&.ô.n[Poõ.m«˜Óìäv¯÷Z.ø*n}¹ï–•oçâÞö L™}‚­‰Vb ë–­0òÚ©£|Ý�¥¥þœR—hTšÅBH]»µÿ›ÝÕ¼*D„/x&™n‘†Íë�cK(çWÁ¤nô×§VpÛ§jE©’Ÿ1S/öjoú‘0÷~¯c†oôâ°–±ðËu† ó. Ëp�k £hÓq'"ˆ;)Eê�Œ ñ¶±B qƒÁ£FávEª#&ÛO*”¬ ·]ïå#\—xq¥‚±¨Šq=‘ñ©¤±+Sï‰Æ OžÓ{§ kðØê°€6^’äñï±”Í0ûë Ãi×ñ7k!¹1è,r—4òO±³E²$ënjT²_r=e²’mrt²'ÇŽa`1Kh±WqqT˜2ç ²¨r&±ÿ²‰¼ò+Çò«Šðöºñ-ŸE?ò.+s/»Ü/£Ç ›3WåèóÄal2³!3³!;³®AsXHónPó X3 aó$Û7Ç@„f 8KqTP19¯9ƒr:‹ò:“òn¸sÞÀ³<Ï×1K¯=§ñ‰:'­Òª|ü4Ôò?ÿ³ûÒ/7žÖâ±Aë1BsÓ°:´P=tDwl3¯ah"Góp0rWó#_s$¿Y—µ”„ôH#.ÈFˆsJ«ô�³¨…²IŽ2uv±]Ì+M÷ñ_äµátNŸñNÿeOSPˇPç2.˱.;´@#uA7ÀAÇuB3ävÞt:Qõ2[õDcQµ�þðV_tWOóWotXwôX—5YŸõòæMZׯZ³µ[¿5àæÍÏuK×õKßu;çõ£rMŸ�åv`Ã2NòtaÈa5?+¶?;·T›H@!ù?,*°üÿH°àÀ¬X!¡á”‡7H”X¡¢’‹j2‚Ù¨¥c��B* D‡“ ª,¸°åŠ/0cʘI³¡M rêÜÂó‚Ï)V¬pñŽÑ+Hm(]z¤iIiHeCUˆÕ«A…V0Ã5¤WKÃ*½AÖ‚Ù³hÍz±­Û¶0âÊ…C·n„»xqèÝ›±¯¼x9L¢0‹ÃãýȸÀ‡Ç�ÉHž‡Ë‡iFÚ€hà�Ÿ™¶�MMQP¬)Ñ×F`t¤c^�¤@I(¥4Úm/åöÅn¼õö[N8Q„¾valhÈamÞ&âˆ$ö†Ó‰)®Øâš/cX3–äÜ�ÐE7]u>~¤ Ü IdxG"™ä’p¼ƦœB)e|T"feXf¹%þy) ™¬¶êj‚ -ÿ˜šƒ<¶Õf…°�álÚv ÀK¢ zž˜AŸÂ¹(^qÇ%W(T5>—£Ž‹Vdv`©¤jQZ)\Iz rº©§éMi˜¨÷]™Ÿ©[¦Zf«¾jï½®šÉ jÊÚê®oê*Û†´�ä«KÁ ›§‰|Ç"�F2;(SN-¢Ó*Êãµ?j+$·E~ nyã’›ž¹ç¶÷ie¡²`~�eùÁ©ò‚@/¾8禾³ª©•¿jPh!†Ïip�+Д0°2ÓáôÓÆ"û°²ÃxÅXSÌœÑÙh#Ö`±µ�âõ(·f%¡öÚ"_ÔÇÛp—,n¹æ¢ ˜˜Uiߥêÿwª€žw€:nøh<£É/ FJøïÐpÊY°‡¢µ¤ôÒM?íô{Rÿ©UÕ‚^�µRÏÒ €×R�-6Õd_’Ù�ŠåÝÚl· wÜrÓÝ©ÊéÆ7¸Ë{oðÀðÄËüwà€ÿ^ïáÌ7OPâiÖÚZÐn'¯¦‡fùLK£�¹æœ;ì9u�¶ÖO™Ž: ªïÈz�®{ìKÍN{m+qûÛr{ {Ê�YÙ`~<áoxÆÛò’7¸å9ï�†ƒÞâ~6=¡åjWëÒ.—°ï=-|*Jã@g¾Ñ)§bëêÚ'„j­…cò» ýÂÒ€Úð~ø³Ýþú÷¿0Ø-0¾\ÿ8<ñˆH4âE <:ñp¤U¿*X½ÈaïhœÑödÐ=n.=�ƒXQ¬v>Ò¡P}+ÄÚêFØ:¯Ìo†6¼áýj@Ç:¾g}èßöÈG”ù°=€¤ ‰ø��IL¤–ØÄ':gQôùw+È ìzÌÞJ´¸Ë‹t¡ŸÄ¨‰‰nèãš@ÖÇB2*~o¤_kˆÃ:Ú1=xÔ#÷èG( r�D4äÞ©H$2²��Læ˜ÀÌfÞi МÎDpÈG¼øQCÍ4 BÀÍnÞéà '4ǹ„�]„èœÌRzÀÎvBà�ñÎxÜx—SÍgø4H7ÁÖÿN$ø‡I‚…À–ƒ‚t9Ëñ£æœvª÷¼[Ò!U@ÑŠ.‘�¿óÌïfÀÑŽ²CXT¦H—ÙLf>3šÒ5÷hM”a“™Ú @7½)¢pŠ“œåô–ÐÉu*¥�î„§DäùzFÀž…Á§÷‰µ~þó~(Ö zP„A¡ m¨Cш*`¢¥èEƒ98ÒtÔ£D©Z_UR“Šhœ)Uéýªy—kŽ$›Úœ)7¿iÓà4§ki O}j ²ó�ˆgZæùºznéžù,S'àT$4IR�U jÕ«¢l¡tÐêVïÒÕˆ‚5¬c=`FGsVŽr­°%S[pÒ%ÿÄu¥Ch©¹^*€˜ê5|µ)͹ÓtJf�†E¬bÑÂØõ±I�,A&[ÙË–'³›ÍAg±ª9ÑŽ¶´%bXźÀׯö¼ç�mmo;W–ÖÕ¥w…i^õÜpW§ƒ=îO“+ÔÕ-FE* ”ªOnò“�þ´,T1»‚n–�Ü}šw· Þ‘˜— ©%z7¼Võ¾¥ÒÄ­n9Å[ßÒ·¦}½o`Ïi\2 ¨Êêb‹ÚØçò²K5pSüTÚEµÁS}0#ÌÐ-�/þjZ ’ááqøÉÊl¦MV´¢¸jàÊØ¢[¶<[ÏôNÓÁaqŠÃSž&§�HótÎÒÑzeÿËp‚R ,�˜€ l N0ß6 =å)þlV�œŒ6p΄²¢ÑS)7„Ê>±2–±£e.·5¦ÝãwÂ|¿1¥Ìè<3;Ó<>ÿš¥Í„ŽÀ›ã,gDÄÎwž@ž{¼6>cÍÏ!—Úã!ÏÐyCt¢Mlµ6š™S†´¤5�å“m Î]Öf¦5-I¹ÒÎÓw5DÝR¯ùÔqsHXÝê9¿&±–õ¬÷œž>o$׺&"¯ÍŸ&òÐæ.¶¾a{l$›ÊËn6`8í¶kÚšæôµ=­mn{;+lwªWgaŸû éž5Ž|wƒÞ»^`kG>{+ÏÕûÿN¹Hûýï*§ôÊ̦´³ÃPð’|iÔ®¶˜j‡«âàVƒ¸ @n‹×ݱÖ8Ç#àq�Ë[ä$?«ÉñMg•[ý‰,´²_>é¯T:³½yÂr®ðµa»ábAóσq¡O|ܬ6:`}g¥s¼é¹9ò¢.õò’5Ø(¿ºàéL˜ 6ÆÒ̃âe–œtw¯{‡g‘`P¹@&E Å©I=¿dd\ÖóJúN‚€•4” ôª’Põ�€´„Œ=_?øÚ£·ð_ˆ|bSªø<0^,Ž|ÂzßûÉ_¹òq¹ ”¿æÅù€¾_¤IêÌú�}ú¡}Ù·Pª×}Òµà§aã×€OV~‘w~Ї�kì,î—ð'ôg^�ú×ü‡-£×XÍ$l8€È}Ãã}ƒâ�‡'�y@�Àg�ˆ¸�È×� …-!0„D‚Ÿ'.¡%x‚‘‚ˆ¶‚�Zø‚ (ƒV8x4ˆxÓÑ{8¨~:x�=”÷ƒ��yAˆDX„oáyj0‚ر„¦ÇL*¸PÛgZT8lW˜‡äçV¹�q%]¸é¦#B��aX.�ˆ•†C˜"Qÿè4"„Œ8鿆˜‡œ1‡š#3ö&wzø‰ú–…ýW�¨ƒ¨#†è~C‘ˆ.°ˆŒèˆ�ñ4‘ˆ†ŒhX=P‰HhEó�!lð‹À¸D�x XŒŠ&Š»÷‡¥h§©H|«¨ˆIˆ!‹ ‹#!‰ih‹¸èÖ#9¼˜‰ˆŒÁ(Œ¿FDžhŒêx{|XîøŽ³ÔÓ�óè|„øŒÅW¬èŠih�ظzÄC�Ük–Ž(Á„á‹äˆæxŽ”Žë‘j…{ï�³T�›‡‘¤v�ø¨�ú(�åA�þ‰FDiXÝø�³Ž›¡�äØ��CH)‘4IxíX‘eÿ�¹v�‰�ÑØŠÓøŠ<ñˆt^t’@•’ºˆ‰-9Ž “€#“ÄX“V9R8YV°•\‰hc®T$âá-P–fiÖa!r*Sx@sð–péG~„-»´GT‰‡�z¹—¿srùv•€[1Å•]é|_–b9fy–hijÙlé‚áWr‰2tY—w)&~ ƒ�Ù™�4˜„i^‰6ˆI\m±˜eÙ˜Žù˜‘i‡“I•i.—¹K™&›Y…ž™›Nš„I¾ù›‡96‰ù¨Ùªù˜ZКHÉ€±�0—ØQ—CP›ºY�VÈ›\ù›ÀIšÂišQœé†œÊÿY’¯9Î �_±€wh�ìƒØ¹•Úé›Áù>Þ©àkâ¹%mÉœæ¹�èéêÉz¸ÙžjuïiñIóÉFPã!3é&…’I<{¹—áœz—œY šrš _Iòš%Ú‚®I¡Š�š¡Y•£úö¡ñ¢–2¢%ª'ª9û9<+Ê¢ é¢/ú—2Z¤ÄÖoÍ” ¶ø_##zð¤P ¡±&¡)ê£+z¡A*¤w¸¡FÚ¥‚©M³¥¤†eKt$¢# ¥Qj¢SŠ¢Ëi¥Х䍥[: ^Z§Æ¦m%¦@E¦5`¦NЦz ¥wF¥mú? §À(§J¤vÿÚ¨$l\ÚŸäˆ-§%Ô¨z�šº©/Щž ZÒ¹D´w ?z¨Žzª�©tÚœ I©[b©Œˆœ›Ê©žÚ© Z—¢ R¨º«1¨ªx)Îéªü«i(«³šµj« ª 4ª¼ú¬µç«ã¥#¬ØQ©íA�Æ:«Éúwò[1­âÚ€Ò:^|ÇwØÚÚú˜ÇЬÉú­z®ã:¯ƒ'l5­çuéÊ몖íÚ­ð:SòJ¯{uJu¯æš¯ K¬D¸­´Z«ÛM[°«oËQøª°ùºDýj!ÿú®"®ÚT±$[l–±Ëw«ìz¬²ñ:²%;³Ov² ÿ›²Q·Dp —Èi,ë±Ü4±4;´ke³a…³*»@;û–={"? ³+³D;µ#e´…´9«´KÛ´¿ñ´¹!²¦Aµb[¯GH#7­úz¿5[cÛ¶2h¶­…¶êé¶t[“p{Vr»€u»·º™·üÉ·€¸‚;¸„[¸†{¸ˆ›¸Š»¸ŒÛ¸Žû¸�¹’;¹”[¹–{¹˜›¹š»¹œÛ¹žû¹ º¢;º¤[º¦{º¨›ºª»º¬Ûº®ûº°»²;»´[»¶{»¸›»º»»¼Û»¾û»À¼Â;¼Ä[¼Æ{¼È›¼Ê»¼ÌÛ¼Îû¼Ð½Ò;½Ô[½Ö{½Ø›½Ú»½ÜÛ½Þk½³ÿm15¾ ñ½n¾—F¾êk¾m‹¾%¥¾ë˾bë¾x¿B+¿4K¿òe¿R‹¿C«¿½Å¿ýë¿3 À}uÀ'p¿\±aG"ÜWz²ÀÿkpüÀáÁ\À¼|Á½Á¶Ì« 2,ÃÒÁà¤' ¨:Â$ÌÁ&ŒÂm¥Âu:[PÃ6Ü8œÃ)’"1ÐÃ>ÜY8‚#w¢À2\�4lÃ5œÃ:¼Ã[àÃ?lUP2Ä\ÄÖyÄH¬Ä8ÌÄMìÄ1ÐYQ,"DLÅžiÅ7ŒÅZÌÅ] Åí�-a,Æ�IÆIlÆLì^¼ÆØÑÆn|•pìXÜZLÇjÜl<Åy|•ÝtÀ6ŒXôÿthÑË%Ø‚å[ÈžyÈ}•Èï´Èl—ŽÜ�Œ’Œ”\ÉÜ„È5¬ÈÎ÷m�œ�lÇ_Ê0Ê�iÉ6…É ÉËÕv­,È |“,ˆ\Ê—|Ê™œÊŒ¬ËžìÊ^ËÀ ˜´N¶ŒË2¶Êj°ËIhÌÜÌ ØÀ»‘"¤V$ÞPÅYG`#3Ò9“�Àê¼ÎͤͭÂÍ4áÍiÎi!ΨIÎXcÎu‰ÎœÁÎþ¬¿îÌ*ð<ò|ôŒö¼˜ø<ú¼Kü¼ÿÑáвµÁñÌßáœ$ãLGåœ%ç £ž!Ñ$ÝÎ-&-}Ðg‘Ðf¹Ð ÍG‡%ÿ-Ñ'�ÒMÐ=Ï]Ï}Ï�Ï �™H5MÒ7&Ž&ÂE¢šekwÓvYÔ£aÀ}Õ=Ý:,)œÔ²ÔMí|Oݘ2#Õ­ ¸ªÝVÝsÀZ�¬\Ã^} `M"NªYÖík2£¡jMÓÍÔÖY½4[M"]=ײÔñˆ•×YbÖXÓ£‹©«„:n½4—�0…½‡�ØW�l ±ØÎרdýØ{}g’=Ó§cÙƒ�0™,›],מýŠ=KŒ�$Ž­�=©-Òc#¯ ,Ã�±]"7ÑÙµ-1…Ä5Ü âªÉ†…¿HФ|ÝÊÞÿýÝÐýhŒä]ÞÉZZüŽ-ñËË ÍíÜ£‰ª™nÕý× „ô£ÚM["ÒÝßíÝá=ã]Þä}Þ •Þî¸Þ¢ÜÞÌ­MÎíñ}ókõí÷�ß+ºßwâßÿàNà®9^ Ë îÞ߆™~gNDú�§%µáÉúßÞHà. •]ê½ì½Üï�Än-6ï1óÑ¢4ã¦áa¹Ááß½…î7o�åZþã›ä+0äµ]ä6|ä�äX³äLNN®¢ªáý}ã8nåćåZžå\NU^æž�:aÃÜߌi)’n÷�æj¾�yÿ™á4ÞLZÜ­E"ç½GçuÎGOä ¾'þ<Ñç5üç+n�>è±Vèiîœ‰ÞæÚtÀZ̬Þê�ž(éZNéNcé$Žé™ÞàÀéàé›w¡Î„~݆nêå ¡êLÜê®�®x²žå´N¶Þ¹®ë¼îë¤ì©É¢~g¤ÎäÆNÈŽʾÃÌÎ꯱žu.í{Té]~é+pí(¾ë9áçdèÝ.èÂ>êÄ^êˆ~ì+Jðçž"éÎë>íïþÓ^í¸žë|žï�¾ïŸì[0ì¿TìOîðŸð<±ð /??ñó~ëõ^°ûÿ ¶zî¨w¢ð¬^vj“nxgÈyÀëó[g0ôD¯ÅÓsc8¢Ò<¬ÈŠYðô`s*‚Œ”ݨ3³a ­7ò9Ÿ8Äó9èó� ô¨#ôD?ôFŸH|# Kßô‰øôYõ[2õ¿XõvzõQ›õϺõ[Ðê:Ÿ`ï…b¯–dï5föikmÿöp/÷tÏv�x_§z/±„ló"‚ó øƒ/ˆøù˜P"¦ú‰_ôL|ôkßönoÌA÷. ùX#õ�Dõmõ‹ÎL4¿à}ßù\ÿù^?¡oŠ£¯–¥ú¦Ÿúh¿újßú�û!û´?¶¸ÿ«ºåmÿÕû&þû¹áù k=6È™üÊÏüg°øÑø®x<)Ôõµ_÷·÷¹ß¥šÏý%  PÐ „ .dØÐáCˆ%N¤XQâŒ)42àØqÀÇ !“ŒìSrÂI<)m¬dyÒå-1e YSÎMœžáyÁg A? ÆèQI•z`ÚÂS YÁÅU4Y_ž$ÓÐW aÅZ$[ÖìY´i”ÑÖ- ¸qu 4xPí]¼yõ2ÄøEcŠŽAŠ$i¥J–+·Â”³¦Mœ7ݺåyÆç… A•*=ztËgÐM�B•J5äUYÑ,îJæ+ ±c÷Φ]Û"ÿÛÉ2âÊ�[· màÁ�÷ý˜£é #“”ìã2%žÄŠ·6vü¸@dɹ+_Î tsÒÎFA‡íAêù©ƒ­bÕºµõëØa…ϧ¯÷äÝùãúPßÿÿŠˆÛÈ8ä”cι”ŒcÀ„ãA­»»ÜdØî§î¾ƒ!<5Æû¬<óÐKo€ªPS�5¯ÀŠ@[|è¾·ô˯¯¾øsñÆÚæJ@@ÀTÏ@Ã&xNÁ„ðA ±“£Â 1Ëð;=ÜDG,‘½ÕÜK¶qô@Û’qF¿°ñK4ÓÒ‘G ,¬¹Ãð ²HŽDÒ:%™ì ÃÌ4ŒÒC*EDÎÄö^zOÅØÒTÿ´!þpôQH#}´Bý °ôÒÖZs`SN%]ô,þ�TGIK5õÑRUU¿Z%êU:M°`VZ«ªJ \såð^›ª‰`»l(å”ãðd“ÍtÙÖžBïÕ”KÖ-ÉàõHè`Û>õQO-•Òü.ÅtYN;�ô[²BõMRRÅ•×QUWͯÕ *VZkµµ‚\u ïZ_i–a}"¶Ø$8D‘ÙL�=Zi‘¥ÖЮ®Í–ÛnÙU4Üy'Í­Rs `6ÝM=õ˜"wë‚w®�å­7UV]Õw~ûµà_€Vb×^™ú5Ø­†ýˆá†Ã{â®$.íÕŠï¸Ø¥Ö4Öÿ–Û•Ó9frw+Ùd¦[S9ëˆZ6èe�bwæjÎ÷æœûåÙçŸÚƒ¡.Zá£v¸Ú°�qá$¦­ÖjŽÉþrë�+¬òë°Å^WqˆÌ.í�Ô~ôÎ;gÛí›q¦Sç�ÿ¥è# .àà„/ ÜX¥gZpŠG2ckyÝkÊod|^ÇE„# Z6-Ž/ c†ñ˜(>Vô¢k)"Ù¾�–4±ZéKµ:S-§= j.�:Åó„{—ê¥^˜ÕSuõqK8Ô fÖÏ¥u¨3pï pnÜ“Q+¤lãb¸þØ1öÿ«ˆýYc#»XÊ ³�ììF××¾_­¶f7³?/dÜ åpiãW�‡Ü#÷A¡Æ”3�µ`ù²¼„�'ÔñÃwpMî/Ô¼œF÷ªƒ«Òv¯Zñ¾ É}ðKçÒ›Þö®¹Ío^!×ฯƒÍ0h�ç9•>o‘H÷°«÷Ð=no³q^™âú]òÅç ñ�ÿ×Ò—@ÈENr“+å*ŸAË[¾`™‡[5¿y_tþÑö¡{M`|ã—¬ ×ø¸¯ÜGˆî‚y+.L¿·¾Ÿ^Ý¨ÓÆ­\ }é«N¤œ(ZO ×íu��ý bïÒþp{Ü›=Èh?‚”¾ÿºw”7¾ñn‡;Çç.à�Û½ FÏ»rö¾ò–¿<æ ™ùàñ]xŒÞŠ>ãùĸ›ÍÊuóL“ÝZÏùÖuÎõ�[¬ÔÒ›¾ê©Çú«X�×›Ð�=íÓ;Ü˽‡;;h#2)�4àc‚îkJ»±ŽC> È4n30+û6-›-Á“!“°Ð;7¥ZÀü>y :X Y3?C¿Ý8±ç·[�ùXÀø#½Ó£¿bÉ:©Ø:\‚®k�dI–þ Ò±½üÝ“¯¤¯D²\À­‹Bº“À~é¶ Ä2pk0qÃ>S37vq+>ÁîA["Áñ±òã§ó“3ù¡3ÿ;c«zyaí’Á¬A <,6A»•úAd Â$B†)B#ÀÝKÂkYBüjÂî{ÂÏ’Â(Ô6®Ò´ ò6,¼@Ë@ùÙÀrëÀ/Tª0CÇ[2ðc ñC�6;­ÌcÃøqÃöƒC…xQ€:ì¾ä<ÌÃ=ìC„ûÃ@DB4ÄbAÄ#2FäG¼,H>I +J¼´$° ¬²+L°,t0 ü2œ;5/q«ÖÚEr$½\ �ª`¤ƒ «§°%[Ñ,ÔH–7[ÃÍ£­¸G”qýЦÔ&,Ù�<ŠrŒ?Õ*¬W!�xD–×x –ø¬ã¦h«Š$Òaÿæ�Ç�‹ ìœI3É‚l¼ÖÒ¢HI•¤5¨-Êà‰+ˆII@N‹¶ µ|´¨ÎyApüqd­‚ÜÅs¼™t¬ uŒ�vd¤wÔ€…¼ƒyLÁ¸¨­{�|ÜÇ2éÇ2 5ýÈ�4Š $½ƒ”„Ô™¦lȯxHÿ +‰$2Ь‹ÔŒ, �ü+Ž$-�´µç ÉI3(IÆ;ÉRÉ•,±–¤­—<ƒ˜¼‚™¾š$²›ä²œÔÉàI/l‘Ÿœ�¯Œ¿¡Ô—¢¼�£LÊ Zʦ|J8#L©ÄG”±JÁJÑÊüàÊ È¯ Kh" …¼Šd1K@@Ë´\KújË·ì—ÿ¸ìƒ¹\‚ºä�»T¿¼I’,G“d-”Ì`I—l‹ÊHÌÅ|>+³ÉøÂI”¡3¸˜ÌëIÿ¸ÌÌ,½Í„–ÎüLpǪ€GÜDÒ¤N{DÍtQ;xAýpÍÝ`ÿüO�ŒM¯œÍ{BHÛ$Ëø¼ÝäMÿòÍkÎàœ•á,ÎãLÎ64 ½äK¿lÀTéœNÓ4Lë„I™4Ž<=î­P 5ðDñ´.ò¬óÈœØ(Öce¥==ª�-ÈŽ%Ê� TÐT’Í™ºÖ¨¬ÏhY—}ÙˆYјYÚªÙÿ¼Y4ÍÙ™ÚÙMíYjýYv}ס�€¢uK�IÚzýÒ‡]U2=WÝÐýÐ 5X¬ÕZàZ_KÑTÛkQ‹� Œ�Õů\[ÎüCÕM¸•Ö’¥ÖMYE]Y¼Í½Ý[ÿëðÖHMÒü T6Ü]l<�U:žýŽuU\Æ��x­ÈÈý>³WUÅW¸ÜÌÅY X•ÎÎ¥-¬=Ð]* ݯý ;mÁÝH]·XÝC[×åØúS ž™]³¬Ý ˜Vyœ[ݵÚE½ÛÞý]¾m ¿íÀõO¹¼ÒSÞÂeÞÃu^Ÿ…Þ Úé…\B²Þã0¦Õ^îåWÍ_Î-XòýÜ�TXŸ‘Sú ²:å2É„ßRë‹i]áËLØUOÙDÚÙÐŒ[àÄPÙ{ì]ßÕÛfŠ^àã &=æ'ÕRÄMÅý€èÍ`ÒÑ>óàÊa¼IöÞÍ_î‚ò=ßÿ®:õ5N`…aɬmšíb;¾ãÓÛÅÓSÅR¬Ç»< ‘‰víB.ä-þÙ“�š8®˜‚€\©¢Žåˆ£\0ýø‹\ÂÿK>ÿb‰dÑÒÁ‰bsU:å+N¥•GΠô;–#:ýŒºí·è‹Îù‹®I� JºÒMÿ¢Dý°8à™Ç+’VÑ+½BàzÔÂ+Lv ˆæð Ú¨ã;¶ãÌÜcãèãÄúc¢ ä˜äB&äCÞŒDVä8.ëQH¾ß�d�õC˜ÓÞ¸°d\Á俉M.�N^‰OþŽPn•Qf sÕ�SNåYYåheW†eÑ�Y®eŒ¸eÿ�Èe3Øå‚ìe³üe) f;!æ%3æ@æèPfgæÆOtfö“�h¦€i®‹j†«kÆæ¯ÔæÀàf!ðæxg-çq.g¥8gEVgÓÁ•v¾Á¡€g· ÆyFÎü°g%ÀçÁb˜}�~¶�ÞŒ€n€�^‰‚Î�ƒn€~Qh†ö;‡NÕˆ.5ŠN‹ÆèrÔè†äè(ôè#éýi’N “®¾n¤Yh–fjž k¾æl®:¹b�F žöiC®^s;tNgÆZç£V¢Pj`4¾¦… ¨–j¤©ê¦¸ê¬VŠ­îjøêÝë±6jVî>W~€³~شƹµnë_ãe'ðeòæüˆÿž�¼Îë•ØkOŒŸe^é–~i»Ø‹^«ºÂ8sEì%»< dvgrvì †ltöí¢fç R Ìn½ÜlèìBÌdÒmd1´~å´£R¦7ƒV>„¶²v톎å-˜m[æ\æ*]¾íŒÎí�Þm)¬ï¶àn�cn nfîë¿ýk—læ8ç®éª‹nÅM쫨îp¾nìÖ j Yð[aío˜dN¬d�¸äôÎç$XoòòäöN6��oi›o–Œ ÕVe/ë–‹m7îïe–èmðŠð‹&ð·6ð¸Fð(Tp:ùmXqð‘†p GiãVi Wîßl wëÿ‚\^z“îý¢në¸âBf$ Á:¯s Q) ºqqojý ©>A5ÚÏ2T÷†�h–ù¹M]mð^h€í;–»$‡0·€¡/�÷5ÜÖmÐÂi,/-'Šàn“¥QJÒ1Çp½hn4/G5®+[¿u7 8'd9ÿŽ:·sëÀó,ÿn?½ì�g¦6o@¯q t`"ôBÄC�D—o‚&Ìú¶»ûÎïï¥ô°ôøÂô¶Ðô'çô(÷ôçÿuÉó hpyðÄàz¯÷TWu æ¶HnWÏ X—ò4�à5WÜ[Çu¢“�]ï�yÕ™_§ó;—'wßóÿÐoü+oz†‹eïgG:h�Cçq @t"SôkWÁlwt±&òHOÓ–wÑw w¶†òXŸAºRwòbwôpwx7yg‰z·w%S|Oi¿ÞwÀ†i3§º ÊY«Z/x0¸b„WÜ8¯ Òixxx[ŠxŸásÆJQe÷™@OÃgïø�_¸YyG³v¯Æv°¶ï”Oè"Ÿô–ç•K÷ÆL7 Mït*Àmácnõ)õ}áò ¡ §÷{/z 8îVWú´p«ÓË㌶§Ÿ‚¨/xªs«çu¬gø†çzFòú€qñÄDZ'-•ÊxZÙx°"/+˜}ÚO{Úc{Óò¸×öÿ¹Çïºïö»?‚¼'µÉ�yÛF÷)ümüv§–�xo€Ô‚Åç€Æ—׺5{�áû÷… y†ç)ã8 $Ê—?~üû7ÅèS^¼ØX†ár$¦5ŒlQÔÉÉ“^ x¾åüŵ3Ñöicµ…Ú?‡Où !tŠñÜÚÊ?[+4rEoy*Òa.=&™N?µºGd×®wWÃ;yòæIo|Jà' é˯¿g§™ö¢7Ú6ïoS÷Ps?¸šŸ~âmàÞÙóÝ7Ÿš±à¾¢á ž¸Œ‹7>Øã+·ÌáË•óv9æK6»9ç�ÿUè=MúqLÇ-Ôy \ÃWrÈ4-hÁ9O³PºÚ$»7UÍ]¶îìä<ÌwÀË—ØE¶~ꈘZuƒ5ï@pƒ^P¤W�MU¯=דƒö´Ç½î p" _LZU8Yî|z!™úv…2_¹OrA² ‘Šd9š)KY ë\ EÖ`¨ŒùßÐx4ß@ Œ,ÎêÆE&6Ð1ç‚`Ô®3AvU°và¹]î´¶;®ÕK÷ú•0¶&Ô§„'T[ •·Bæña.œÔó`ȇѰ†7Ìaövè=.�ˆ‹U¬ŒX+$šL‰ŽKY›S*(«XS¬Y×pÅÎiÑÿ\�[ÆÒáF[§ãÒoÊ�3"�\ltàëà»ÙÕñ]Ìã·Ö5?~ �a¤ Y¶/Qˆô�"ÄÈ=rRO8':FIøÔ°—Ääöú¶IΓ­%‹D‰¾Ñh}‚i_äTùÄšD13ó»\,e¹+,Öò–üËåþ‡¥^�€1&1Ó˜Àì¸Qщ ÔæHµÒXíŽÏÔ` 8È;‚Mx!Ü׋gB´y3yl{”#%I 3�»Z'õ,y=xÆÓo=ü^=Ã÷I|ê3F·ZØw¾ÃF6”1Öш‰XIpµ«ô£_Bg©³†"DM]ÂÐ8Q- ˜dÿ4cÒ¨Q‰HÄL+3Hå˜l•kÔ]½ö»–‚ä¥Ä3$MQΛº­œêé9Õ™©Çµó�DÕd±¬ ÙÍ ¨³Œ´HB+Z|’VM}ÑœNÕ¨:aª |Ybë�«–!«¥LW½úU*ÆR¬?!«Ì Ñ´m­¾lk—Þ:̸¢qht�ˆ]{„×8N�¯4)�þªÇÀRs°Öt)6aªMšm¦ÝT¬ ʼnS癲¬u‚‚È#_PV¨x#jX0[¤ÍrÖ³ŸE�hG[ZPžV/©�Áj£êZ-ÀV¶³½ªmOP™Üru·¼­¢o}\áæ’¸Ø¢è/“{Q¸ªÎ¹Ï�.ÿc¦»ÌåX׎~…fJ¥ÙÇ?¯°á=lyiÓå­×±Tc Ôr�;¸´–E€™dšh-#ø4y˜u?Ò¤ñ;‹ã¦JW%Z›ôG-�ݬ|àÅÑoÉV®sý�]Óáqx“™r�ëRÁºØ€ ²)ðªW% ÙÎ.°Èªlå¢`ù0™æ²—Sf1‡–Ì$¢KÈîÿÂæ¸Y’\ˆóHæL‘:ûæÎ%ÈóžáÓç?7 Ѓ.ôq�h²,ºÑ{|´€"í¡IW:›—ÞA¦7�ŸN«åÓ#õÍJSꢜÚx©6ѪkÒê.¼:Ö²ž­/gkaãš×ñõ¯·l’— qà."´Ï'm*_ÙFYÞ²Ž\’m_m[EcÞX™_n¾¼Œ»ÜpF·º§Àî¸Þiå3÷üü@GeЄ ¾  hFË §�Öˆ¤áSpñ<á—á4L< jˆÚ4wBÅÍ{q˜düïø>ò\ÕzÉ$ƒÉ{�²”«üGo¹È„sQΜ5_ÐÍE€mß|™:Ü΀·¤xÿ¢·ùœo†!º[�ô¥7)ñ^ͼ§^ïªßë:Ù·úÝõƒ}½ a_ÍØSv-+m ï‚Ã!®¹Ñ¼=îÛÝXÝï. bë½ùÎÿ{àQþë• ñµÚüâ×øÇ+(ò“�AåÃìónoÌÙÎÆ¾¸;ÿ„ÏC/ô£?��{„g¤lê}“úo¨«ãYߺ¿y]À�ÝÀ‰�Y¦ñÞÙ-\Ú5ÜÚµ�Ä!‡©å ª9Ý…«µÞ9Êô™œôÛ��Ìi¡_öÑÊöQ›ÍYÎAN—Qž¶YÞøa^ù™Ÿ\¼œ^�ç™›û•�Á_»É߻џiØß¶àŸoèßðŸë•ÿ€ƒÉžÖ \Ü\jÚú^ßF©I ÅQ ÅY F$Ÿ.ŸÇu ÎÀòZž‡™�`S™à ¾H•­O¦][ÊÄßìZ¼ ˜ ŽhÙà ‚[ªûÅMw숚 ‰KDÊüEý!Ä@ì” a (!šNÙáæEšRìa îˆâY"ubh¢êàúñàH8¢…@bKHâRbZ¢@`¢&rbëy¢ÊF“R¡ºîÿÀ*2`+~áði@ñÑ"gØ¢>Yè"/ªaÞùbÒOà £C~�1ã­” .# R™BããL£Ž¢Š "òe£ n£"zc €£tˆã�cžU¢\âN­ãêí_;æÛë�J(Êã(N!V¡Ú#âc±°âÁ¸"†áqL  Ô¢¿ýh墯©ÅA:ó)$2¤É=ä0Fd1"£()£EÚE3ZŠ`@£äõaþaGVãG^cHf€6V$^pã".L#êÈ#zI$È$ª�KÂ$$ɤ½ Zÿe—ädŒÍcOÖã=æ#îãýb?þãRdSbTÚ�TÖÞ©ÙXå�ÑÿŒ&ijå²qå x¥�eXŽeµ=£F¢%Óµ5J€5¾6ÂåHÊeú‘ÛaÑ]N@^>Ç^ÊA_þe:Æ$½ æÕ¹c· ¦£­EíÝÞGä^Iœcv“…¨]de,&åV¦¤Sâb€$g"¤gŽÛ¸Y¥h’æhšæ« ¦jžkZ¤k® lîáF¦emÞfnÆ%"ržov#p§Î gqú!Kai|`NŠ`²a6atàNÒãO6æPz”tx§ð�Zx€R2%`]`zFå.®'UÂZ{ºgÀçåÈç|Ò'Drå}ºo†eX"˜•ÑVX� !Ç@€�k½LgØÿ›Éˆ�ÉЀ”:\µFVdiéLÕ KX€˜‚À¸I) Pi])š’†b(†™H„S élÅT„�ÖésÙÀã쇞ò€K|‘VœÂiC ê©TÆf%\ìÈRü)q¥�£>jÌ‚¤2i„%ÉX˜}4^ãyæ“vjS)u)U0êqi’Ë’¦D“ö…§â™š©•¦éhh)—z)„©˜²Ù«~š0*V¨éš¢A›FÄ›¢©œš@�ÚésåéžòiKø)‘úê•jC*e*¢*ªR�êÐ<*¤‹¤¥¶ê‹ÐOã‘+ºÆ¨¾€¨N·šêT))gPª“¢ÿ뮎@•Fœfi©n)UÙ*®Žé”òê™ú*°®é°Ú@±^é±&+�Þ)³îiŸ"ÄŸJkVP+CX+`k²i+p+rx«£Fꤪj¥¦ë]˜ëÌ¡,ËŠÒº¶« ¼«@ i¼¢ê¼šl½’ë½æ+Tìë¬ök­É—†©À–)ÁB€´,›þˆ›6…Åb…ÆĦL³:ë@«Õ=íäÙQ�Ær,²y,ȇȦɊ«É¶¬Ú®íâ½, )‘jéÐ,É«Ð+«ÚëÀâ+Äê•ò+ DÐVÆÐ‚iÑš)Òìh«°2-±:íÓJÉÔúJÕN¬TìÓr­x-—ªf!ÿ*ˆmܦUÙží¸²-ê¦.â¸-ÜZ�ÜÒ-Ù-ÞòEºîlßꫬj­þ«ÐÞ*ÑêêÞöªâjã&ìÂJ«ä.+Õ6«åb®Åj.ç~ˆçZ芮릕†Œ,¸–ì°™ê~/øâëŽêèîÌžê�¤j÷v@ζªíú-–þ¬ù.en®v€íBÀUøªA(Æ19Æ�Þ€#/†LîŽTí¦ü©ÃÀ)ôjletFØ¦ÌØš¯@ho‘„ë醯£îøºkùÂkÝÚìÝâlÞêlðÞnÏæîî¾Àþ.þž°þ*…´öobüoðûjòÒÕãHɦ×£iw®G°¯` qeÿ¯Ùn/Ú®ï?ñÚvpÌ~ðùÖlúÞìú¶¯§¾/îþ­ü .ï®ï.ð-߯0ÌpAø/=ß·†ëˆÃg smôzˆÝñŽ 1銬é¦-rºJ±Ã¼®ki�ú®*íê­óìø¬îm×ïßoþîo Ò0ØðDZ”Œ2)ÿpZ9 ¶ ±ôq¢¦ w« 3q2-Ÿ i!r¦(òT12;2œV”…R^pq {q%Ïï%“�ýîÑr2œz2(?—ñ“²5×ñjܱƒ¤²;0e@p+1–Ú¡•-Æb0!ײ:ÇÜ-ÃE�¾-U$r¿ÎKí"gO#³o ‹R0çÓ0Ÿ0üþêû+ ÷nÀ–1â:3šBs°4çp ^3DG…) *c‰*ó1+‡®+�39—€9S+:;ñ:�t@!ù ,*¶üÿH°à@lª[ȰáBb#¾›H±”Å‹R2jdDZ£¹� ì@²d„ Rª\Á²%º—0ª‹ћ͛ÎrÚÉ¡'�Ÿ=~LGt�ѣ[*­©Ó›7AIíÉ!‡ÕMXÛiÝ ¯«WF`ÃÒ„èÔi´³hç©]« ­[pãj™K—•Ý»còê=÷/UªÛS%C¸pšÃˆõê Ê$È�EJžL¹²å˘3kÞ<ù$B™2Ç£Xñ¢E�;þh¹¤IÏ*W¶d 3¦CÑPmæt¶ÕŸ<³I4ÝQ¤J™–•–Û›TPT­æÀºi+W¯]Ê»\Ú´kÕºÿ}.]ºˆ+Ó×ï_�· .L8ýáõc„¯69çÿ(à€œy† h·�EÚD¦�†šú­Öšk[J³ÑV:¡�ÕÜn½ý”jCuÜ:I¹³T8Ý5÷\tWee];Øe§#¢u÷ÝYá‰7žå™wžö¥�_{|½Ÿ`=ÑWŸ}øEèXViå•XVf ‚ ‰¶à; –ò „$:6¡k^˜á r˜ MêÄ“O#Eœ‰Ç¥¸b‹¹½Ø“tÔÍHc�7âÈÝr;FÃÇ¢Œþd�`À”VZä‘H*ß|ô]ºžpý…Y–¤–jj�žugn_2Êè °Æÿ ª¨g¾vÒ… x ë®mÖn¹�8'ÀIY܉(&Çâr.NõgŒÕÍèk¡9.§¤«‹J'�‘JZ©¥P®‡äÙ”kî¦M:é©b?´ë®¨¡ž*ï¼ô”ê›5±º ¶|Ä*+cðÖJRš±íÊ놾 •°¾Ñ\™Çž¨§re5 ݳÓÉhÝ´7V[ÖµØjk·‘Núíëî…¤¹ç2É�“d¤œ—»ïÂ;j½8ç\eBG©š/T !4¿þº_À•QX¡g'`°®)¦˜0DÍÝÔ[oÀÛX‰Åg”8`¯¸gSݔݜ’"ç (ÇÚ‰võ°Tñ›6É�šü­Ìì­Ìr6ñÅÿ3Þ4·‹´Î„þÏFùLµ¾ï=ÑEMkÒÖbùåM?íAÔIMMLÕ6½ HÖuÞÙõQ`‹#6Åewsö{iw iÓüÎaûí¢ƒìêÜÝÚ nzøÑ üð{óÝ÷6ÛçÆòÌþÃà†G/}gõŒïâ@Oä8äþJ/å®]ŽùÉšsîŽç {#:éÇuÄ뤾ú²Ò´þú_±ËN;¶·ãþ¶îŒš[�š†·áooÇCžº”Ǽå9zÓ‹`·Å}ŽqÛÃVÑNà=*U&u©Ÿå2÷4ó¡të#�PÌÑ5<ÉouN±_nÐ&2Ù`®êŸír÷¹‰,H¾£Tÿ Hƒâ%pHLâ~èÀÀAP‚P¤—�(ø�*ZQa7 ÚÐ4¹ÕÀkK!ØDX Ì„5ú,ÖÈÆfm…-ôZüÂC²•��l¤¡¶lˆCFép<ü‹µD2°�D,"�—D%®†‰nxàä¢HÉyM±zF±â=„Á-ºjƒ„ "Fq�ÑŒ»B#vÔˆGX¸Qkîca QGG±ÅðŽ­Ô£tøx²Úé0�q Ùx²"A2‘Fdd#÷°D&Jò{•Œ&©  m4ä(V4�6oÙºn\.D8O¬@Î ˜³%H§:‹'r¸ó�MIŸ7܆z¢bFàÈgXžbÿ“Ö]n<‹J�@ÿË”T³šÈòU5ÊÐÍ e” �3˜¥ •º¨FS0®?È i(ýSuªs(Mé¥ÉR�QÓš ÁfµinúÓrà'¬Èésf�&E;BSšÆ3}ô´'>õ ~z㦵(4JP�ô  ­CÚ#ˆbA¢²£hEésQò=m£í¨ d³¶z°¥p�«e^zÍLÎt›vìæ7ç¤ÓðÔ§@5éPRT¼Ê3©`¸§uò Ž}õ©eû§[:PX­ðª=‘B·Z ‡z¬½ ÒXÉ*2Œz­E’G=ãV·Êõµ°-]cj×oÿ5¯PÍ)]ÆYÎs²$¨BÝ›L [Sæ µ-õLìRÛÔÇBUªTµìÖÌ�Ymd;œílW#º¨‰Šv´„)ë·4‡Úq=±µ7‹­zÕ;Û…ÈÔ¶x­_7½‰S¾îv§½ýéoƒ:X†÷±UC¬b·ÂXDzô�êd§ZÙ\6µ®fµÊYÏr—ì+xÅ[)ò¢Õ¼“zIºÞ¿¶½êxïmå«×ú6¬¯õí €Ûß…ü÷ÀF®RËTF8õ¹ Ž®ƒ§[Ýëz%»þê¢2üÝ —Ö¬+/’΋^[9®(Vq|ç›`ÝÎ…·=•1p‘Å�°Ü¸jðr | ·…ÿ²)¨êGŠûÙ¢OïÓ ™R•†X #¾²¢¥™åÚ®˜Ë{}ñ}ýšßÀª“Ì 1sa|“4ëX¹øÃRñó{üäúÒ€,E} qyñ%Ù§}CâyÝ÷}~â7~¹ z;Áz®W)ê·~ìç~kòG±a{|!�ç±k× (€.E¨8Ø—}ÛWkÝG�y �X~x~H)ˆ ì¨K ¨"È2$h‚t�‚>¥‚,øu/˜…Pƒ3ˆ€ øj¾‚b8†;�>H�€`�é§~G˜]ü²„uÒ„)ñ„æ…²C|ûW…ÂÓ|Z؇cÇ…ÖG^hƒC†c(†e~g„i(„kÿ({ÈYok¸Ç„ Å{t˜ vØ-xX|zH|臢¨oâs2ÁXÁƒÝ†5rˆb(z°ø€f(�å(è÷;ˆÑzº8„•2‰xV‰uÒ>¥Q<VMR8(˜H£ØŒ¤è¦è¨ª¸�p�Øhˆ‡‹à§ˆ´Ø#¶È‹E²‹·ø-¾xÀØ>ÂhNÄXÆxŒ$׉<ÅŒÎX�WVŠwŠù”ŠØؘ�­èŠÜ(‹Þ8~µø#åˆ2öA޼H)çhé(ØŸ7Ǩ ñ¨ûG�öØ‘ê…�å¦�àÀ�áç�ÿØÚ8†ɃÍq�ã‘�ãHŽ}´($‘Œ1‘ ÿP‘,s‘$IÇDD”°’¬&’$Yz&ù�)ùŠÜø Nù”ÍáU^Žw³�2ÙKØR“ñKë˜íHïa=铈”By–-E”«f”ÔØ�Öx’K‰ù”P™R QT‰‹‡Á�3ÉZ)]ù•–5–d¹<‰–ŠÙR>—ƒæãŠr9�ÜH\ÕX_ ˜éw‰¿·+lð™ )r DZ™  š�šªé.™\Ëçx‹›rÕ˜Ý÷˜)™±H™ni™ ‚™Ð ™wÙ™ºršŸ)šÇCšÁW$Äɪ¹ší"›Ði�´ùy¶¹�¸ ‹ºY’Ëq™™Ù›)œ°œÆÿÙ7È |ÊIœÍ™š¬�ì)ŠÀu‘Õ©’×)zÙ‰”Ûٛݩßé{žIœã÷gžö±œé)ëÙžú‚ïyŒæs„óIŸ…U™NÁ�¿é�ÁÉŸÃéŸí/ú{çyšz  :¢Ñ· Ö ì÷ PŸ¤× œR žâ¹¡¢Ò¡¾÷¡¨™ž"J¢<:s&zP(:{*Ê¢yТã($¨9 Ù!5<º7‚£Ÿ¹&=Z¥�÷£Õ”@Gè “¡ØJ®ô6H|Jú™L RNZ£PêE’HTj¥pºoXª Zº¥BÚ¥EŃ`z¤?’¤O³¤|ѤÂó¤,¥öᦧŠ*lsÿZ§všOI\té”{*¦}J¦j¦�Цƒª¦…ê“7yˆ:‹ZªVÖ¨Ç󨌥J^1©ÏP©W3¦ÀW¦lp¦v�¦¡R<ª’7ª-aªÀª^¨Ú7ªšO¬Ú® «æ7~j0€z‚J„j.»Ê«¾ÊÁš­ŒšN>Çj 3”®âúG¤$p®èJ«ÏÚ‰Ô‚Úú®Y¨Nݺjßê$MC®:d®èz®êª©í‘˜ð°õ(¯óZ¯ôq¯øz;úº¯ýZ«H°±~H°Ýj°…Ñ4ùÓ-E²¯üš©§9.²I±>g±„�±5$;˱šÓ®X(²0« ÜZ°ä3(ÿ»G*k-KDî³@;vÀU²5k¯'“±‘²²ûêSŸˆ«o´P+}À¥–Ü`³G›²«³Ë´æä²Œµ`+vS �gµß‚´�¢´èʵàµO¶p«oc{>·™7»K9›ã¶n›^qû·Š6· Q·wy·VaCE²·\Û·$¸Žkb‚‹„+•†›ˆkŠË´Œû¸œ+vÉÔ7›ù¢;ºVPº¦Ë·Dä|þ×¹¬[�¼º£Kº¦[º¨k@ª»‚­›»£øº±+º³K»‹›ºª«»ÄÛ‡¯k#ö³Å»¼�w¼‘¼/˼ÒÛ¼¼Š¼Ðû¶Ó›½cç¼q½Ø«½àÿ«oÜÛxÞ¾æ+sã‹hÞÛ¸çÛ¾V–¾`·¾î;¿ï[½Ï+¿ô›¿±¿ë˾úû¿À<À\À|ÀœÀ ¼À ÜÀüÀÁ<Á\Á|ÁœÁ¼ÁÜÁüÁ Â"<Â$\Â&|Â(œÂ*¼Â,ÜÂ.üÂ0Ã2<Ã4\Ã6|Ã8œÃ:¼Ã<ÜÃ>üÃ@ÄB<ÄD\ÄF|ÄHœÄJÜŒ¯vKl¾M ›O ¾QlS¾UœoW¬½Ys[ÌżêÄ_,½]l3cœ½e¼œ(xƺ›ÆÄ¹Ælܺ¯Ë/j¼ÎÇ"ûº)u®RÇÅwÇx,±z|Œ|Ì(~ÌS€Èqÿª4JÓ&šTEÁP x RQ”H/§È$ÊÈâÈ�É Õ,–\4(˜Éšœ œìž¬I \ ¢Tʾ濧,›©\m2�­üÊpËûgʵ̞J#�©ËÁP¼l¾\|ÀÌÐ9ÌQÌܸË} £ì/²\h´ìÌhY\"ͱHÍPQɰLÊû*ÅÍÑéÍΰ(ÎQaÍq1&(ˆÎ¿¦ÎÏLß|›á|Ì¡\ÍåAÏçüéŒÏ±ÉΠá΢Ï6AÎp!ÐÅgÏ÷fЭÏíÌÏïìÏ® Ðóü õLÐ÷LÑŠ‰ÐÄŒÑ ­ÑÉ Ñ<%ÑÛ,Ò8´«†,ã0Ó'ÿYÓ�àƒ_HˆÁ>ã‚«sūժ·‹+ö¶xßëÒÓ?w"3=6}’8½ :�Ž?ÑÓ�ÚÒñºA=yC}!E=ËыԢÔ2MÓO��QMS½•YcÕÒê·"¡Õ Ê«]_­Ía-ÖÿAÖLmÖg}Ó¨$kÍÓ{Õ?ª[-yu­wmh_«×Â×ÇÑÔ}�>(ØÿÓ;M:n}Ô!×'ñº‹��ýky Ùš!ÙGAÙ•}Ùï1Øœ]Øo�ÕÚ !ÚªKÔ¥­¼¨}êeÝÔN}’hN!:EBØíñ³¶�¯;ÉMƒF ×½½×éÜ}-Ü5]ÜpÓ—ÿ›ìIÌ ÔžÑæ}ÞÐ}2Q0§]Ý–ñÛ/ܬý�ÜÝ0ñÝ›�5â}ÚÍ� ç�Þ ÝŸÂÞ�íÞ›ßè ß~��õ­$øMÕ<°ß.[ä}ÿmÞéý-ëlËÛ.®àãÐ’ŒhÜTñàiP ޽5&ƒ5rá �ᕲá]éSþá!žÝMMâáLÞ�·ˆ¡âLôD-î+0.ã”BãÑáíýáÕ”àDZ¶DjÝà›€k ©9˜Òûa¯Û&2ñÈfG\4…Ö§'„�æ„°œ±Ò¸òá—ñä'"åcÓmecåXNŽZ..HÒåª`îê&`舞æŠ~Œ¯ëÚå²^ç´Žçx–ëO³kòD¾^À�®MÄ~ê©~ìÉ.˜Ë^±ž8’íWë·nÔn0Öž!Øþé¿îŠÁ>êß¾0¨žè«¾è­Þèå.ç^AéN1Ñn鱦9í×þum^±íá×íÃ~’´ž©~ ¹AªIî/Oç¿îÒŽëO³ð Ñð�ýð/ñöÎíÝ^Óÿ¿ïi®ñŸÉñ©éñòO?oë òÍðòîð,ïò‡xï„.óëŽñjnól€ó óÏó³Nò?íBÑ«¡òØËòè€ôc¨ôdÎôæô5o_4O‘oîÍ>ç=owìôƒòáõ�Q<`/öbȃø‚ï+fß:hOP/õT_îV¯îVòî¾õ+ÝõEŸ«{Ó÷]!ñ¥'øƒ_#…_6‡ŸølŸónߺ7Þ£æB[_#ðp’\†°ûÉ•\Ms¶û¨…‚Ë´È’:g�sâSJRÓ?Ó:k ?b“ì šËã|º{ú<šúîEK­ÿ�¯û°?ûõTû·ÿoû¹¿»ßû`óûh'BÂß9Ä�=ƯÈ?ÊÏünàü¹ ý$*ý)Fý®?_ØŸýÚ¼RÐ` „ ,d¸ÇáÃu%Š£ØÈâÅ‹ï4n¬ÕÑ#E�âÜ�„W’ØIo)»­œ×”˜0Ó¤áQ“;œtºq#À§A…%ZÔèQ¤I•.eÚÔéS¨BL¥ÕêU¬Yµ"ÍÖUÝW‰ë(ÂÃØhåÙnhÔ®ÓÖíÀ�7&TÈpáCˆaÅV,›Qî;�CŠ$i¥J–.cʤi';�xþºÕòeÌ™-S­ªÙógÐ\½‚�(Ž,F´+ײuÛ¶ïßwÅdÏžY;�ÿ)ܹõî×ׯÜÀvWÞIb)½�m9ïåâ™6oæÜÙóghìÙµGåûv6¹XqñETb”@ã�SŽ9Å k¬¦Ç"›ì: ƒª ‡42; I‹=ý, ñI(WܨÄbN´·o²ÔRJßyFc¤QÀsn1äqÁ<òM8ƒ*2N:·JÒ¼ÒNkJ>á2¶­¼RË-áër£/] ÿSÌÂŽ;l93dLº«£¬NL-œ3SN�ºSC=õë3JCå¢RPûÍòOØeeQTÆtt@H ÌÁ§ƒÌR ;õU+l‚–'b݈,²A’Uö×NpöÙOólÒÉQE,uÊ@é»ÒU¿ù pÃuVYm$Ð@4ÕÔÕÇ+cö]¨„¶Xc�•@Ùeá­óYhGÃsÉ §­ÖZŒâËÖ¶m»ý6\pÇ]´ÜGqúhõ±ÿúê#²ÖVpºöš°ÃV¯²Ë6ˆ ´MƉ^7\fy¸ã¦ÌÍŒÁ“��A™ä’ÕNYe·|È»ï¦ÙæšsV\ž{úq¢‹žZš¤WZ:Q§ŸŽêÉ¥©új«µÞzQ¯¿ì±Ë&ûì´Õf[ðîâ–{îºÃ»;o�CÆ‚ï‘Õfço”a~e �ùpÄo^çÆw~òÈMè¼òn.ÿ2ó¦7ç|òÏA=k®KçtÔSS}õ‚ÐfÃ÷ׇ@v¸çv·víбÿ~ܹÑ=mú÷øÔC€´G Ø&Ð. œ�Œw<¥ØlyT9,xAÅ]ð‚Ñ“Þ䨧ÿåÀ†|Ð^8:÷¦� +d!\â ư/#¤D mè°n}j3`}8À.Ðð[�üè÷�ûÝo7I´ÿü×?Q€>´G¸@ß½¬Bäò”GÁ j�aÔ §§‘³€0%"$_ O˜B²°….Œ¡ ËBCÖ‡:ô©(ÅzÑwF|d?š‰“g>(šÓô˜â°÷ÐvlÒš„�z¸©Fo‚m8âg*ÍÙÊt–e�´¬%<ã9OzÚÞv$íôé~&±˜øÃÝú7e”™÷4YBmWI†ráÍœD±©ÁŠZ-ÝüË7ÊÑk�ó£è¬ã ÉçN“¥ô\)CZz©—îÓYÜikjSFq™V<(;ÎðV¸)s=ëŸEÍœµ¨bœ(9’ªTQb´©ä{*G¥ºJ�VõŽW-é-ãy…9DVÿ²)-`Wâ;{I ¬W1\PbªD&²®þÓ]N{Xж®ÔÎxÆCWØræڸkCóª×¦g›ü+`™*§ªQõ(b©jGŒà1�Y-ˆd'KYË:³öÊçf‘ÒY|Ö~eE@µQÚ�žv§,U›jßÊZ$¹6±¥ëlk+ÔÛâV·åáí_›FÁ—°Â…êaå˜Xä^D¹7tl<�YʪTŠmÍlu•<~©7³ÕaµÉ°ECðàp‡Ag5õ©ï#ŽÌL|bs¤XÅD¤A‹]üâû)ò Ö0Óqco²;æq�w\ ™C&røJw$'¹y8ÿ(aØ‚Œ–– AÊS6@•­\,g9[æ²{À0œ9ÈÍ)[Løp愌ø ‘ìnÄ1Y9©C�í¬f53„XøJÛN|bÓàÏ&.$„ûåZ ‡Ì¤_†5<Ê"ÄhSs‰-cÐÐ6Æñ�9ÈÁ<„ZÔq®‘‹Ìè#'ÉKn2ØžŒ£)SÙÊUβ–¹¼e/ƒ™|¤&3ÙÌŒf„äy!mÖË›I=çŽØùÎx^óBöÌgëFÅÐÎ’p¢¶è0½ÙÑÑ€ô‡'͆JëdÐ?Àôg4ÍéN:z¢uœM=d#{MÕ«n^« ðêÄÄZʳ¦u­ pk\»G×§ãuÿKÊ “3ó!Í#fsdÝ,¾c§„ÎÊ®³›í€gã+ÚP™öªmS ‡<Ø–‘¶ÁònƒîÛá–À¸Ëí™s3qÉꎻCMjØÄ»kó>«µçd Cyú‚jmt<¹L˜ãÜëRüZáÁfø°^lˆÇÙµ xÅ™­gžðyJÇ%\B‘k˜ä129P®ÆH¯œÄâ¾tw ó$ΜæC³ypþ�ƒƒç>ßЫ!t¢#ËŠ·õ­™§‹êR_øÅ‰ck]âɦ¸ÅÁÝ)fW/ÚÓ¾vT´ýí Œû¤Yîr»?ï÷ÓûÞûþw¹~ðõþ¹«ƒÿk}3žñXVúãA2³ŒÙà¾F8°S l\^"™óÖ»îyg‡Ú¢gJÇßlz‘£¾íaKùÕäŽgØsÆn–Dî·ÎÚÓüöqÎ9ªå=oÂGÍðˆþÑýýo€3>Š@¾•P¾y88H¸Êk¸9x¸Ò‰8º¾¯[ Ðã¾KZzÈ@ ü>íI»‘s¡À¡ò1×c¶ôëŒíà˜ö‹ˆ÷“¥øS·ù3جÁ7Ã!w8|³•Ä;:ÞÑó:/Û ìD@¤:Ë»:Ì˺êS# Ä3!ª@ L ›ÑÀ ð 9ñk4òAI+Aô«;õû ÷³økž½ã;ÿ›Ã½�¨A¬%ü½| >~ûÁ B½ˆ¼#d¾t>蓾ˆ ¾ ¥(„>† Â*<Š+ÄBzàÀÍñÀQÊLÌÄñ›QjŽæàP E‹Ë¬—»Œ3Ć4D‡5lœ64�¾ë»”CPà7¨Ã<ºÃÃÑþ E>4/¶Á�Á(¸Ä$|¾ª‹¾ÈÚe\ÆÝ(¡QÚE~"S±G ›&IœD-ìÀ´»ÄLÄÄM$€NôÄyEQd6RŒ½d?4dA5tA6lÃW´¹X”CZ´EÂE¡ƒÆYëEÕúE½aDBB5Öÿc%@U3fEÁ÷T¯ÝPÔD5ÍjňQ*†ŽÐVý„‡${£W¹r­ÔÚÔ´€ ØtÍTN-¯·R–*ýŠubPvsÐ\ˆ´zåTu|M }5ÓZCÓGõКݼÀ`p9XfƒS�SÇlØ’xØ”ˆ!;K8›xQSœ¾;Ö�!+« �užàX}U½Ù¨ÙÈñZo0ÙZ@ÙGUY$cYipÙ�€Ù*+×™¥±šõÖ›½…œ5¸âYw-�ŸÅÒ uP¢­×£MÚ1-Sç1… ‡†è8“h÷ èu³híÁèbž_Ž>F�–ÒA­‘Þ­Ÿ.‹hvP”Niµf–—F2˜®Y™Îšq&g4ç„@gŸ&é²`çóqg¢£N ¤V¶{îè}îg%‘j©jg¸ê¬®º­6±®Ö†¯&‡°Žœˆv¥‰ÆžŠf·‹ž·Œfë̾¸·†›��Lšÿ‹ðÀHËk-QiOìë¿>€ÀØ7£[š;lœ~�¦‹M˜nêÞ$b!kvg¥›ìÊÎÛb¨gÌVjÍvjÎþÏžõh«)è¶&m;HhgYhîk¯yhÖŽ³¾CMv‹mQ›mU%¢ÛèÛfˆÜ^Œémßîî,!îæ0nýÜæ¿èfñanusn—�î„ îê£ëVŽìÉíFµxFÖ£þî¤^ê¦~ê¨ Io«^o¬nïf+í8íÔ^mù³9ý5þ5ÿžbÂÔ7oÜÎÙ9p0òíFPpÐaðopð–€ðGUµ³Ø / ÿ4 _£œNì�Þpßëd'Gÿí8î6qËFñðVñ͆êÎvqôN õö¾ío®Žo¯žoÕ®oyäñú´¹σ �T ð:koGò¸yÿAð‚ù '¿š„Q)¿æÊæO²+׈€ ¯q mÅȹé séó2â3IWs/j6÷nðp8'o97oŠ@[mí=‡ï�onhA·=Bš¾ã hˆvi/!/p}ûAÍNrf™ôFÞœ?1eÐÙ–wrÿA4Q*G^+_ ,÷VRïS§VT'U÷rèfu1çðnù𔈴4¿µ}x�÷šÿP\Oññfñ9`·óÇó×óÿ…°qt‡ÁfÿûÜi—öl¬v5":lwkH‡IïŸ%‡ow«wrwsG“t¯d —‹Q§ˆRwž÷z'¥/ÅFˆ1ß„}7ó~ÿ°ç2�øM¶uƒ¿l]Oøò. †?Ö`mŸx>7m?Gm‹_ög·5Øèøhÿx÷°öXù#×ö_ávœ9ÎJ/e–—ù˜_Œ™w`¿ì wwœ‡w�?õy7�ž�C|ú1/zX?zÐIú-[ú€'x§÷S¨ot#?r^oñª÷Ыö¬wŠïú{ŒûBoÉ¿0{h@ûÖè:‘ç�l�ômGùn�š•gù»/wÿÞ9÷½O^äþûgxwpˆwD�'ŽžÃÿù O�¡güÊö÷Yxɧ|ʾõ˯‰Ïç8çü†G‹;ÏóÌ×zcGö­½øOËïÔµ²7{×w Ø¿vÙ'y·÷¸/¹ÿ��¨{»Sæ(hP „ 2¤äÄv'ƒwàâ�w7>ë(î#Dp8F(iÒÊ”áV²L™2—·˜17‚ªY§NŠœ)6ñìùí'PbB‡Ê” è(RJ—FhêtÔ¨!Y-³X±R7·"<áõ„ƒ°ÆZ+«î캴Å Úí-\gr“rH¨å+Xvìüèûc`m‚ÑN»Ž¹�ààÿ¹lŒ2äÈ&MF޼q#´Ìšéqî æ3è­[‡�.m·«×°Æ®h½ìزgÓ®mûömÀºœíí»7�àÂ/kœgüøÒ¥W–3áü9tç¦Swêöì)Vìžë;xÇ1F+oþ|ùµkC”æþ}­øò“+Ýnb£üú�}3 €þ1 �ˆx �úé'ƒÎð „§i1…ìq!†’Ó–PVyè }°3"‰g˜x¢lÙ¨¸¢Šé¸è Œ÷�4#óÞ{à�çai¥EA i]S²q$’ª©f“Mâö$”QÚ¶`¿Y©ŽpÃÇŸq!2×Ü�ÑQWÿ‘Ùig_eiF&Þx ÷f4ê�Äž‡òÍGß}8ºç!—óøWG€8 †Žz¨‡ Ê!„xyUáX†¦¡�"…™jJ"‰ƒxúiŠÙp3*©.¦£'2ÒX#‡zJ£ãw|È:k�¤ý(ä�D‰ä‘J†°ÁJ9,±¹QyåoYGÜ;}zùåaŠ9æDF`&v÷©©&›ãÁ‰žœâ°N�vÖbžzòÉåŸ�8耒v(¢V)ê £8z¤È{‚•ZuéQšnÊ);Ÿ‚›Š¤–úbŒö­Êj[®ÂšË¬´Öz+®dX»+¯¾:¬°Åšl2•¼ýf£²0ûÿç³_J µÕ–‰­¶ÛVÖ-yèñó3Ðá \”¹µ`‹Jº8®Ëߟ³ïò’C¯¡‰*š¯¾Žöû/¥ZJ°Á™:­°§¡:<ª©¨ªJ£�®b�±¬î¦Á1®ŸÆë‘dB2°'û=,²¾ -ÓËþ餴ÑÎ,µÖ�³Î�9Öç›@-çà1ý¸}®~}©„NC-5ÕŽXÝ Öûn-uÀ^ vØc“möÙiG¼Ý�6þù6ÜrÓ�«u #©7ßü}ü“�÷–¹7…‹vxN‰/Îø˜ŽãŒfä’7F¹Ï–ó#´ëD›Ëùvž¿úi¢ÃK:Õ§3˜ºÖ�rÝz[Ÿc;ÂzÓîÿ°í©Ú—;‡v—/¸ñÁwÑé˜Çtu7¼�oÈ{`m”wæ ‚^ Nt" ahü`ͬg¦‰°${ÚsIŸ*è=~Œ‹yò¹ ÉÇ󥂡C�zÃ>z�®4Ò”êÆBªù‘ƒF¬JQ°RŒ †�$j’þ&ªÚAÌ5ûÖÈ(:´›]Ü Æ16�dˆñËÀYWÄ#vÈ*Jd"þØÅÙIñlÜèߣ“Eÿð.c]|ÎÆ1бÿŒ%C#ÕÈÆK¹ñpp<ƒ÷@G†ðŽg2äJL˜>òÇ�–dý¬2ÈkÈp%44 ÁI¢Fªc‡õ* ƒ(iKâ…B™|$bŒÈ$Êä“°3Ø™EØ4ŒŠ§‚Q*¡³JÑ´rV¯tN,ƒwZÖ’lÅÃå­Äª2&ì¥N~Ìanýè2ªQ+‘0™&\Úqœ 4h²Ssñ�!5 yH¥%ò(Ú7½Y5I:CœäüŠ9GEDu–Ôî¼TãiŽy žü«b>Ÿ³Ï­ô3nîú ¢*Uk5©Iuƒ-û†P“¦«èPèBñK¤@4'•#E/ŠQ�f”£yÿôhö@j‘þŒ¤�_-PZÍp\Ó¡ÙLÔ›BEœ“$Í3DLêT“<½k;±JxŽh” ÛßÃîiEja1_Z„ÝÅÖŒJUªU=­U šUãmµX^% X:Ö£”5ƒpœè0ÕjÑÑÎÁ­È ‡2å:º²�=.<)!ñøÛ¾zÆ€e¤`ÏBXÒÔ¦Š½ä9'•NNÃC?½eE)ORÒsŠGÕlR�³Ô›4µ€¢mi£ŠZÔ^uµ­uíkµKÇxèþ-€± `H'_9…üÂÚØt ÁN„#›ì¦¥;ÝQ§:#Ó‘gÀ.þp)X!âY-;ÝÙðÿ†=”…³ø>a ³œ·•}I Æ6~íWϲ–{¨&>ÅKÙAQ+•îC1�’ ¡ä%ï µ~ñ mX¤"Š¡ÊV.–³ü» É olØ ˜í@ƒ1 f>ó“ûBÔûnÇúå¯Uü{Ž  ��½‚à±(Øo^‡…+‚a#j¸#~ ˆ,bV�¸Ä¨81ŠŸ¡b¯ØÅa�1qþDc×ǽÙqX{üc ?—DCþM‘�ŒdX,™ÉŽrrš£,e*[¹ÊYÖò;Öe¼…y/c¦Á-Ù,l)¹9-‚sQäLç?¨À99°‰Ü—ëÏ�†Ç Qh:Ñ!±¬ÿýèŠDZÒV¡t¥íóbL_FÓŽât§_ûé�ðØ*£&µ]œvjߤúC«nµ’›|Ú4ÿ@Ö,¢u­o�å-“a׼굘ɬÕaSüIÅØ~Óßÿ˜Ùpv  }iÿ€ÚIJv ³½íCwÃÛ‹nt‰!�âISÚÒ e÷FÜ�xKÀÓ:¦w¨í=ê ï»7ýöп.ðªJ¿²Âîp$Aü×Á®8Ögsæ3¿Yãqæx)ê|ç4äù{Î@ŸOF*)gã_*‡Ì†YîrpóÁv¿»‰+ 0ÝY¸Ïµ™å¡?5ñ—óÇ‹ÕT�Å3þ^'ľ¬ô¯z{#é­&ྚ^,ÿ;˜íRw——«.q“g½ô[7s×]²ñ9wÜÎÍÆó³õm>OÛÏ£b»Û½òn'ú岺;Þ±Ó�½ÿ¤ïè| o‡Íð?G|XÏøÅ;^鎒¼¼(où%cÞQš'çìù\ãjêG=°'^úõŸÿZKJÞ#9˹Îu¹ÈINúbá^^kÉpš€‡Ü)ÝŸÝ ñ}ƒñÕœ}q žaß:èQeLõ)ÊãEÞoL^Ð}÷Á;œˆ‚©ß“„_ŒŸéš»üÚ¯EX„ÔúÍ`û½ßGÄßžÄýù—ý þÉÞÈÑ^É!OÿIÊÿZ~Ç~£ýÿž" ñ-`‹5`ò=àòE`óM`¦…FVCõµÚ¾H–¡.”‘yCfÌšH îŸm  Ûµ_0¹†k¸à˜Á „Éà šÞéÙ 8à 4Ìßö ü ÙÍÚÕÞñ¡a¡¶%a.,¡ïÕÝbKJaºm‡^Іjv!d|aº^”¡fßzÈÎJžÁ‹JÊ‘¶Ò€&ö!ÖÕ ÿÝ JÈŸb"âÙ¥Ýß8¢Z|V†òΊzî�&þZ˜‚äÇ'nE(žÈ(•bà)œ£¨"ž!K¤á+ÊJ,΢”Ô"‹Üÿ"åâ ìb/þ"0Rœ0!1š€1zÞƒ!*£"2£ß8ã:@¢šLc‡}X%^c6ò"…ß!Ÿ7~c8ÞÄ8šH9Wš˜¢Z_*²£;®<*Y÷á N› â†=®>bˆ>ò£úã? [@>â@äA&$ì…êJ FcdH¤‡`Z"ð]dñe¤Lld7vÇ76ÂGÖAHžÁHJßô¥#ä­£J²"Y<òÁ<Ê$ÖFMªÈM^HNâa?:POVœ)ýKw¼G¹i†fü‰—ýÒUñ$” b †6CEÓ1"Y�Pi”�†;\æd”ÄâuØF …CPÂ1…ÿD¶¹�\PÍ„Kf@¶9³(‘EB Éshȸ0‹³ÐG,Ž‘a"Ônæe^ôe`f†`â aÔ!&(&c®Äàød–†d† e"†ebffn&\tæQ|fhBÄhÒƒ˜&µ ff®fc´¦klj�l:m²‡mrIˆä¦õ¦oî'Ö§¤ç ZEqBÃqòJrÒÒr&¦`<§X’tÂBdÂÍdfTe¦ÅeºCjrç[x' €g¶H„hi:ƒyŽ zN†zº{ºæ{ÆģbÔ'ܧ£œˆnâ%æèúù§a¨‡ h�"É/ ‘i‚6ç‚jRc²ÿÓƒFhÆLèTè:\h†Vgj„g:Dx‚ÃxVƒÐÄØHj¦hJ¬èk>HB¸(Œ†„ŒÝ�¤‰Ü¨é(�öçÙðeE¤L© &©‘"s:§’B§ƒžÃt’FuÌu’CvbèvZiwbéwj釶Cˆb˜šÜ‹c„)‡Œé ±&q´§{¢ilÉl"Hmfš¼©ÈÉéÕÕ©¬n�VXžçžg�É�ª©bz•±!Æ’BV“R§„Z'…b§…^¦bh¦¤n(¥v¨¥" ˆŠ§î¥ §6†§¶¨b˜¨^©¶(ªÊ§ªÒ'«Š†«áÙáLÎ*¼BP­®sñÿ©hø©ùê¯ ª‚jƒ°b\cnD²!*„"ë“*k”2ë”:kH@땾C–‚æ¥N„b aötꪈiz†êzŽj{’+<Çg~檶[«âf�Æ©¹ë[ƫ˚̿d¢UÆC0D�í¢¾ë`tÕ°’CÀjÄÀ&êx™È4ê£>ëhh7p¨‡Zëv¼ÝÅrkÆrȽdª  ³ÔÊ€¬ÈŽ,%\ãzÕ�„à§°ìËž-òÄlά7ÔìBÜ,æ,¿"ébjƒƒÀ¢Ð­¯m³Bêd(-ÓVë}@mä`,ÛP­¢XíÕzBÖÖ ×:‡×~­†íئìÀ껢-çB‰Újë#Ûº­À­ Êíñ j’¢“Ï*Þ­Þ,ið­’øí®Iî´6máfkÔºD·Ž J5®ã‡ÖFnL.Øz–HˆÈØh~âhçN¯Á­Èçb$K…è’îß nݪîϾCÐÂîÐâMÑ.«£þm•>lÄÓD®Î îŒØHð ï5o¯©Âg¹&¯×./£ü‰óú ôº�~R/Ú:¤Ìf¯Llo©�ÎúªÎ†¯~�oùöˆìªíRi¤ºo¥J¬ÓÆ/ï®Ô&n[ܯðê/Áð¯¤éÿ*oå2¯h°’p+ð !ù,"*°üÿH°à@¢ZÈ�€Ã‡—"JDF±¢˜‹­hÜÈ«£GU &9rƒÉ“sRªDIJe¥—0)Éœyªfž›“rê¬XŠÏŸ7JJ´eËšHO1ZÊT¢DhP£æ˜JµêÔ¤5#iÝz³kL`ÆK#ÆŸhÓª%ö­[¶‹âÊ…D·îIxWéÝû–Œ\¹0a%j°°áÈ+^̸±ãÇI `Øð¡C§yR4{1¨F�C ”,ù$J•)­æür&M›8uæÔŒL­g+ƒ‡e‰U)Ó¥˜/E•ªÚjß­\½~ –lYÎj£§íÛ÷oܺvMâ5°—ï[ë‹XWÿÊ- ²ùóèÓ«G/™òBË—1Óæ,æ6èŽ U‰$�дIÔ©Y%žk2!Õ•l³if›gäí†Ho¿‡ÙpPgÜ[Èi¥ÜrÌ97}Ò…ußY‡]wåÕÝ*ÕY'yëÅ(ãŒ42Öž{ðÜ|œÙw_~ûñ'€8‡jh`l²Ñ¶`P îa„ÁQ�…UõE}}©%Z_ЉnådA)r·b‹Õèæ›pÆ À”¿åXË�xªF߉�t&B&$Ä „c衪m¢è¢�4êè’y¼"餪©u/äµ¢é¦F!#´a‰¥–[šÕeZaú”ª˜hõEž™¢ÿ”披`ë­ræªë®çÑÉ”�xÞ©'g|úk Z衆&º¨¢Ž> [¤“JZiZ—fº©¦�~ª¨UýDj©� 湬N÷Ö«°4늷âÊë¼ôÖ{VŸ>4i°ÂZ…‘/›˜d½);(³ÍZõ,´Ñ>²aµÖZõ“\ÙÕÆÅÛr›!Sa} îTâ¾E.Fæþ´êªéޏnn°ê‡¦’Åkk½4×ç½Iåëоü+À¾ŒÁX,ÂÅ8ûlÃ+ñ+×BAñ}D]ÜFÆ­t»TÇš}LUÈn�\î[^‚iÈÙh³:ÊÚl³k¦»0“$s6×m÷z8#¥3<ÿë3ÐBFtRF#­4£ ? qÔSƒV5ÆkÍ×ìÔNIEËÂǰhùŽRõ“Zð¨f1ÈmËxþëÚ1"Àå�¬€„žôZÂ@ºLVLÈÿ+HD›IkŽH¢»âŠ&Z≻ˆ¢Ï`¸Ñ�¤xZ€4‰§Â*±ã¦�²•¦DĽHckè—:n(iÚNo˜ÓùL.tÈ£ÃÀÇ>’‰L·A`‹HÈB¾éˆSâoÒDW<ÑQÜÅ_2HD¾0‹[D�Á(FM‘Q+f¼ÕØ 6Þ¯#D‰#^æHG…âŽqOýøGêzƒ4¤.wÉž+&R‘Ž`¢¡(Å R1}±$§09.n²*aŒÅ³J ‰’”¥¼Ü)1Gílg•X¡#&\ Ëð°f–|¬¥-=#Hdòò�ðlŒ25Ì`2r˜�,fU0rÿLdžYc¦3!öEhv²Ÿô”5G©FSºÝÜÀ7ñ‚Î0ЇœÌ9ѩξܲsñ ©HåéËmÕS˜Ž$¦$�IIw $0�i§¶¢Åf"H8ÍiA©Íiž¢Œ ŦC!Õ?Q¥ª`›�«ràˆõé"½òÈGú #` k&:UӲ椑gÅéN§ÍhÒé­Ø…h©Ò At0B*g>¶Ws¦eÈ`O7ØÚÿRµ°WEì›Ä 5ö‰�½HdÃJÙÊÚt˜ÍìfsÐÙ0~öŒ¡íTJ °Óe7ª5 k/ÂT˜ÀYP¥­mÇRÉè–·ödìoƒ+†áŠ9Æ=nrÏºÜæÆâ¹×$¥hAAÚ·˜–®¨Å.^W«Tîòõµ°Šmx·GÞ¿Ó¼‰]ë)Û•ßZ‚½|r�d'›¡øêd¾h5hgñ ×^ì·¿nù/7l”ìÒ°ÀbèîK¾¨ËËÁ8.$„w+a ßÄÂV¢Ѐ¦aÉ·²nbfuQßæ’8ºü�®« àë¶xÀÚ…±Œ+Ac!Ùxf93wŒ^ßþ6Èœ2ÀŠLÜ7ÿÉ®Xr“GŒ¯ êWº9 ®/¬«Ï2¯Xj­xºÌŸ/ÓM̈&dBλ?øWœ·ˆ´¤í †J[º7ñ�¯8—Ì^Õ`M õ~÷«¦ÖåzÙƒªíªNðð©e‰ŽuƒáK:º²�–t¤)méJ›à×ÀÎô£éÈé^ÄÓ µ¨G ŠRøÔLõª'Új¹TÖØ¶-­ylkš›9ºÞus{ík`ÿZظ&vf;m•O+[ÌnvZLMTDÕ{`u-]}ílû{ªÛÆâ­kšk]Û÷Sæ>7ºµˆQ½¸*zÔ# A6ïg×;Ú÷žö7Õ £{œ¼o´·ß„›á ÿ�o#Ùð@?œ*ÏãÄsàl×Bû‡Á·¾ÝB¤Žüç‚ y·™IòÊšåæVùÊ]Ñr Í<æt˜yÍûiï�èœÚoéyn€Îu€—t™/º�!“+}åM/令K}s1¶8$ª^�¹IëƒéºÞËKÝ2z[b7.Ùcvã.�év„1Ðèö—SÜ€¶ùÅqn»ßÝ4>ß»æ ¹ã¿o*ðFO8Òƒmø¥§ý|¾`|Ìßù¸K~î7ˆå/o’Ìoþöì|­Á>rtž)…¯ìáO¿ÁÅC¯ñYÜé {Êfö´·=:Ýs›÷Döï—br.?ñç`ÿê�¿zÇÓ|ùr§;A yéSÿýu³¾À{¯}Ñ—=áÞ7=ø].~ÕGœõ‚ÖRͧìwwîh7~‡X²Ð€Ø’|)÷fš1�p�¸]f�6|r+ ø´BFâ]£“€&˜hs〈È}ˆdX-˜�0†x"¸€!È#8c%x‚@ˆc)¨‚²�üCx/hY²ñ43x�hƒgÓ�¶ò�;h=Èe?„Zh[C¨‚´Ò‚Œ|J¨LØ„Ox7ˆ76UˆWk[‡µ57B+ª1z ƒKh�fXƒh…8fë'3" $ø6r˜ˆSE‡»a‡Vÿ�‡&àa18)MØ g(iXk(sSˆ¨qˆê§ˆ¢XHŒhŽXäb˜I{X-}q‰RÈ`ƒ87´x+p8ЏO¥Ø§H©XÀŒ¥0ŒÄHÆxŒNÕF-Þ}'àÍâíßuYãŠxã&!ØN°5Uà Ý#ÞäS±à«En!G>a¹í.îä0å}]ܸHå`åŽåZ¤åèÆå­i@Ž}BNäCFnÙø}æ]‘æ9€lÿ¾–¨�•ˆp.ç9Nç`ç†çÑ­çífâ}.æ>�~Ûƒž^…ÎÛ^Žèä –Ö·oá©N¬…�^ÚWNz•Eé™fé?žéAæ—0æÅQæInè¦.ã¨Þw ¨ênÁ꿇¯žÜ±ž‡Yâ.â¿uëUæÏÍéÕèd.èNè7ìO~êrxÞ¥ˆlZ¹´�îên(±‹ì†Àê(;™±5ï$3äa5VæJ$ë 'º\Mr6d@„Há(LÁEÄ|bò�–ƦzãÌQ>¿Ío|k‚ä.38sîë^ Ì9ð>ãÞCï$/ssïøÞúžDüÞï]{Yt ðqÿ!ð_¿eXÂð•æð­ñ— ñáMñu„/¿¦èÎñ´Àî3 ò‹˜%?ï'Ÿ)¯òkºïÎîòù‡vð>á5 7Ï9gQV<>>Á!ôNNôtaôG±æ®ôÏôN¿Äò6õ±Uõƒqõ+ï-ßï]Ïr_?óaßc_ög¯F ¯ö Øðkúð5-p讑Ÿ€uo÷5¡ñÀôMïñOß÷Q¯K€¦@£½;ø)_ø‡z‰ßD`Kó*Xð�rð’ðx¦kßö¡¤ù÷üXô@ú�ô³°ô¿÷=p@~ÏK­ÿ¦áûù“ïYÿÏò[�øòïcö*Ã�ßû8ÿû:¿ð•ßó—ÿó™ñÇÏùrß'Ëñ¯‘/¬îÕ ÅŠõ ØCÌA„†~-\(Iˆ%N¤XÑâEŒläØqã �!/Œ$yËäI2)UšbÙòÑK˜ŽdÎPÓæMœ˜töâÙ“ÐO *Uæ ZÊQ¤BeÉ:ÕÔ)#¨Q'M5VµgÁ¢EmåÊË밳Ď�õÒÙªÆj­ÍZô W†�äf¤[×î]¼yõÐ×ï_À�) vêôÀaÄ´§XРƒ þr¸×òe‰À„R$É‘'Q %ÓÒ%çG3iâdmS'¦ž>�þ$M¦mÿ¤IU.-Ü´,Ô©“Ò^%x›kׯaÇŠýÍè쥴kkÝÎñvkܹ˜µoçŽ9ðwðƒ)õ>…8ñâª� BŽ<™òÃîñ1jFýÈ3HСEߪmše}ÕdjmÀ×bãi6ÚH»-·£”bª·æ‚Ž'¬Ú:n+¯xë�å˜ûí¹èغͺE°ƒD>SL10Zt‘=1ü�<óSŒÆZ�=ɪLE 3rÈúî»!¿ öã�4ÿL0À[+Ð@ ©mA$/Bª¬¢°8 /ÌpÃgiΤ£ŽD�tóM½‘sN_dOFÂz«ñ€st Æ‚ÎËæœsH"Q3ÿI%ûóïIÕ¢dmÊØª¼²-¡ÐÂß$ô²— ³ºp‘1•[îL´Ò±-6’ëDBc•u"C嬳EñOÏûLOG‚uïÇYóªD…,ò>F÷sÔ4HW“Ôµ�¨DðÒ¬2Ý´0.…û4T­ÄLŽÃQ…NÕéF.W³+vVðþÒlz륨ÞzÅO~ûU2€ne`‚�$æ`eFfa†�»ÐG‡T�s^|7 ˆŒ3v*8Öðøãõ­™àüv(º’î‡\ âù‡šíýO“¤ä—ÈÄ:�ø‚â}¦HE+V‹ÄÐ"ÁêpÊ.& «deÅ8F:¯#ÐS#×èÆÂa/Žr\Ú¨TH¼;¢"�r,_/÷ÇôÕh8Ô!èx˜Œ¥…q‘[iäþPQŸíÿ¥%-”¬¤{.‰Éæwe*S'=óI)†R”X¬Ï)ÝY#m�•­t¥-`K͉œû‹-×ÂÝäc¯ hý,¡GeôòB¿Œ[0«¤G»qs’c¼yÊ´Lü  à(ÑþWO{º‡+A»èo–MmC¢Â°$ÝNîFmü‹9C‚NW¨3£¬�)OÉQ ‚BžóHïù3¦HŸ4%§?‹PëåreE¨B�ÃP‚9AeØJ�Ê‹v(h̪G_M0Žq¤@+©çNª¸”ªT¢_mWaª™ê‹©³°)HpªSž¢f…Aåèö0ˆ £Þ³ŒDÑR÷º§Buÿ„RýUº¸ý`u`Z� WæUº†u9AËèF;:´ÿT­[!©XMz«H¾´_ Û]c*Ι2µ¯7ø«:Ë™ÁÖ°L,, $Ç>V,‘…ê=fÙËÒÑ4v¼ãC‰ÙÕ¹†¶7m½a&ÊŠÚ³Öoµ‹híh_[§Øfm¶G­­mµs¬qê¶7QD'`Ù)XâV¨Š;lqÇxÜ|ÊI¹�õ§dMp`º•nK¨ë9ë÷³ÙýªhÇ⹌~W©¯HYËV׺¶Š“$…ÙûR÷Z¾¹¥én{ÊßÂ$¸A•0Ãü;¬ˆ!WÀ^n�¡ŠàÇlÁzl0K´ó»Üÿ¤ë/,,–;RBÃ&ÝxË{áóº(½X[ï=Û›b‹ pzØ+yXc5‚¦ùÛ»‘M"ñf§Í�@uF�k¼0�‚F€4DŸýÜä Æ×¼žû]\ot£9Â)``4P ñèËbV4› t¥ù9ÖÁ¡ ce0<=Æ0ö,ÊPWO§:‚æç ¶é…uZÕÁ8jÁ\òX,fÆ šÕ¼fŵ¹&oŽDœ�6gŽÖÙwFlž]¹çôùùÏt 4‹±LhµúдHô¢ý“GC#ÒÜ›t¥)}éefº°ž•5­Ýjž�ú±¥þÉ©S:ëU[{Ÿ®^¬‘ÑîTךX·ŽHÿ®uÍë›øZÍlVŒ›áÜ9ÿ4ÙvVò�FhgNÚ}tþX å(g;¥Ûæv€¼ GC:ÒJ2÷¹÷‰i)¯ûºÿ^eÀß FQ“z0¦Ö#ªgýqròþø§;p‚ó0ÁÔõ,¬vf’ýØ'öˆmlT Êf6HÉ“q�mÝû/¤K±x‰›P¸4³›„©º«Ó¼¬ã<îû< ú¾Â 6b·Ãb%†(;¦:; J»i½×{»Ø»,� K‹?»›¿]¸Á]¨8ûÛ=¾ë=]¼í¥ÿs@ã;>ôó"¢R¼&0Óñ`ÀÖ¬ $¨Ë¶‡;…ˆ«:ó<“Á,ô@0ŒÄ \Âó5\ÃPhCÿ7<„!<ösA”Ò¦ü‰$'˜»=åË=£ãAüë;BÅB¶!�Dc „Ã=¢9?d>ºr<'ìœèÛ'§�B’�º‘‘º+´º,ÜÂ.\6ÅCtŠ1,C»9C'+¾åXC6tÃ6dD9d»o#„p«Ã´¸CBÈö²=™+ÀGÜ»@ôÁAä?92Ä—AD(Á‰ELA4À?<*Iì‹ß�Âõk LMN¼¾ìÃÀíó„!ÅR<…SŒ´\%°bűpE5„ÅXtÆ“™E׫Å[„«”ÒE^ 1_¤¿g ÆûË¿#Ä“AÆ~QÆHaF#”G$„Fwûªi €j¬ÄÄÆÇ±šÿ戜RØHŽìÄ ÔÂÍã‰s’#ÇR<ÇËJG`XGìwôx YdÇ]£E·³E¸3™¸ÒG—ÓCùãC`<À…à=ßS.À³ƒä„”›hF üG|k²ˆœHÏá§K¼H’ÉH¶áÈŽôF,Ì<�Ì@‘ì<’Ü6“C0DENSG4¤ÉYxɘœÉ–\Ž9ÄÉÔÉ|¬'ìÉ^¼;¢[>aH£4F¤Ä¢!lŠDTHÃcĵ|D¡„%˜Ò ޏ2 š¸:ÌÌL�"�!ñ?S �Ã2ùD Ö8KÄ�Á©í±"†I‹~i=§x§S"@Å1ÜÌMó˘P¬ÃnšŒÚ«ÿŒˆb`¶¨¼'2i:± ¶æØÆ�Á©Ã"¹˜äêDŠíªWzXÊ� ‰LÉÊôIϹÌÌÄÌÍì�ÎìšÏL‰ÐÃÑT›Ò<ŒÓC„ŒÖT×\ØäÙl Ú¬Û<™ÜÔÍÞIßœ(÷N¦N�0ÎÅCNSi:æü çÌèÄ é„GêäëTìL«_ÐÎ1âN¯ðNÉ Oîò,Ïó,Œô´‚õ$ƒöÁ÷Ô—ø<€ùÁú\MtjÍ*zͪˆÍk,Œÿ P“PÜÜMŒéM|”+–ZPâNŒ!N…DXJNå¬Ð²¸Ð µ› …ÅýГ Ñ�"Q÷0Q^@QÿÍPѳ̔R6e{Q§ˆÑ­Qb»QñÈÑýH§`Jœ¸Ï“ÉOdØOMèÏS8Ò~Ó#%5&å'=™mRPàœÒ­Òí¾…9Î,�P]ãÒ¨ðRtŠÎm›Îê< 1ÓºÚNeS�pÓAƒSm’Ó:Ó)@²Ó>Û�¥ØUÑìÒ¼AÓÄ Ô<@½ A5B5TDUÔ¡cT%}ÔHÅK(#¥)-NMEN£ ÙÕ]0P… Qý$R=4SõPTeUQ¹`UîtÕŽ€Õk“Õ´ Ug°ÕôÁUCÐUoíÕåøÕ]Ö›Öbµ‰/mÖdRþ,ÒÙ¤M$M˜F5 `eK`�a^~ýV„bÄ�âú™`Ì#6+–ÜdÔâ îbXü⊠ãÏãÐ-cJ=c‚IãõÍT.:×}a7öV8î�9¦ã”ªá)Âã¬Ðã™Ýßzòã äwÙ¤©`Òc>æqÃAÔå£Xg~fAa嚔lj+èÛIèÓ[è ihcNfˆ–hŠvæhNßËèרèPêè­º¾iÏi^2J g†mŠq&1¤)gU[ésVçdyéyŠi^˜iš›þœ[�F žîi:h j5%j±Ù€—Ü+®ÜÈÿ¹NÂRS§~ê¨Fc]Ÿ¸ÒP*ÇlÎjª» Zàê ñj/ê*î±ÞÚÂ(ë“Á´N5µ®uÞvŽ4w¦+x晹˜º®!êÀÙëžökÿ1ÐY‡ìVM1ÂvGÃ>ìÄÑÅ6ÑÆ¦èÇ>åȮ攢l+²lmÖlÎÏYd†ÐíÎ-í“6ëdHmO[íÖ5·VÅ£ší9¨mš~êUÈíla�Q)ßnIjç€âvE~’Ã.…ä.ÓåæÎæ®hȸè2ÉS±�ìéVœx³êþ>à#H쳉Íî J8¥ Q6 ¤Vòî í’.Rñ0m“A픞50 –¦©Lpí¿|kÙ–iÚ†o-’oú6 û¾üþiÈÐoþv¾ÿ^Ã’/p“Ñ/5£L‘oèað‰™ צí!¶ ½ 7F“ÉðšØp#­ÜO˜ÿ_ÝU"q¯0qÎ ïïÓ~|áLˆñ§qÜcï{RSßñ§îq¢È”ûîå4å[à¦5íï#WÃ$Ï„%Ū'w�Õ†ž)—ê}²rGÀréÖòQ¤ð*òÀ/¾`ÃîÞ¨3QLóÆds^pó–h½8Ÿ�-Cš:<ß§Wï=g˯òó?tBrCŸ 5Õïþ¦‹F÷„ãæJ&GóÏ�1ºtLÇ*§©,O êõrôèCËnÓ¢±‘–(ð®Iñ¶uòÆ•Vk¶F”õöö6Ña'ö@7ö?Fôámö‹xöhçÈiW'7ÑkWëlÇ—ciºn¯ŠoÏÿËX$¹æèf²×ÃZ)5�;r¯’ÿ‰«ÕºuVqîvá_Xvà>@§hAÇ�}çŠ~çNfø€/l¦Šô¬™t ªôÉÀö…߀†�n�ŽðAU§‰‡Oˆ¶øßÀø Òx âxõøÞà, ù”y}›…’—óÏÞT6^•×Y–— bïñcç÷dgˆ±·5›·�Ïyä–tå¦t„·t…z¡¯‡ÿtoÇO¤/GŠ¿A¦/ §EeÛx‰êø–ûxÁzmÒz½ê�®g÷¯{,e{/£²Çw—×÷Ü(ô>>tšOô··ÕQ�ŽÍ˜ÃÂ)ýZí–r©‹8–X&§~‰«aÈ}ÝßÿtäXš*Ñ)É"�ß ·{<Û5†1Bˆ€YçßqévGš$䨞¶ì1ÛžçH3¥Ö…&Óͨ¡›¹™ºöò/±+èÍOÀÓGýÔg…ÕǘÖG§×WëØ싨ý2¹ý”ÒýÝeî*(ë଄ Q1lHè!Ä\'NªhñÆŒ7Ê‚æñãÀ�®F+ùë$J1*c±Ìäò%¥˜2_¾ )0ΜÀvòŠP:‡å`ô¨Me—–¾jªë)T”R§¢”dÖ¬Z±èêõk×?bÇz)kÖÚ´¼Ö²m»Ö*\I[çÒ­k÷.Þ¼wYñí«ð/à£G‘.<ò°+ŸŠAÿUjì˜*¤È’%ëÅÚ°!àÌ5q.éÙØ°Ð¢“ܵ1óe†#N”hñ"QŽ?‚´yØ3U•bXÆ¢éRæLßIsêä¹ÓgP¡D— 6št饦¯ F¥jýܼ`·KÖlÙ´jÝ’�{µ2úôê×g àþ}ß¾ËóЯ�xäbŸPöó_äÿÿd¢÷�¶q ‚ q¦‰ :(šh–H8ai‘q!†Þ‰µœ#zøZE´y$›,Ë9èàm%ݲ"‹ºñ–‰-1Ú’ p1ù–É9ê¸cŽ÷%öSPbè˜c©¡ ’IB'uOñ×ßþUu^zZxá‰gyìyù%˜•Yÿ_óÕGŸ�ù�òä~Qúàd^I ‚ &´à‰ BÚ„t��jø‡vâ$"BC¢‰y¦h ‹-®Ô’Œ3ÖHÉ�Œæ}rža×ozØ£ƒ¬­£§GšúêÖêúëˆÁü©Ì´×Ý®ÍPåþô¼SÙ/á@÷<þ^_ÿfñ½.�<ü¢¤<ÞQ­y–‹Ø‰°æ ­ÉcÕûÜõÀæ ±m„l êXr2ß°Ž|qCßÜÔw»µg: Ïä÷*ÖÏw÷Ë éçž).Çó‰Á‡Â7 ‹…sªÜ,ðô¼èMhz‚z`F@'A Ä‚&Àà÷4˜6ŠÏC„ºÒG¤Ú!©„z;á“Xµ;^ipsŠ!Ñ#€5Êä/�x„¦0!GÏL((9ä�n|¡Gu©xˆø£'©+òhŽžñHÙƒêÆ?D’ŒW–ÈIRÒ"Ò)Œ"yÃIRr’šr(C¹‰Q’ò�¦|DÒR™» •®”ŽtJ“CFªDÿ�¾Ð�)r©Ë"ð²—KPt“G_Lf~i<&2ÕÈÆ˜¸Ž…4¤1ê”;îg˜Ä P ÷GDÒƒtÛ3?ƒHEÒR Žt $»ÂÉNZ²)˜L¤&Y²NJ’oYšReÒXéÊV²)²œe¬‰K]æ²—¾|@*L1豘+L&D#J—5  � yc¡)M:P Ö„S6 ·Ín~³u;‚¦1Æ™Èrž³1é4À<'ÙÎW¼³ñŒELQÏ<ÝŸõÑç>ûùŠÎR *!hA Z„Š%t¡ ½fdŒ)Ñ©B”¢MFŸ‰ :JÈŽNóh-ŠM?R� !äI·zHh(r‘ÿkä"™H¥“2­È% “Éxæt§'êé™B!ØÁõ•ý$j9m9P‚†¡±ŽUS*Ö¨>”ª–=¦U™yQg¦U­Ñìê4¿úѱj³¬Þ<+8Ó*N¶’ó­*ii%^šÓ™Öô¦}u�=y”ÊÁÖ±ŽÝŽPëÚ§Þò¨Hõmc! P§NR½,tñ—YJ43£žÝhGG;™�m¤f�Zu„R•ºU¡æŒ+:çªÎºÚ•¶z…'_ÙÛI¿:°õá­`‘à¶ ‘%îbu©_åU²Pune£«`ÃM·ºZåª%¼ªC°¤dåæw’ÑÕ¶•¥èu©zaºŒTD…)ÌÿM+Hb»Ò·Aö¥~C¡ßí¬æ! M¬-õˆTS 8PÿýOsŸ»à!ï«Á›µ.„%ŒÇ°82Üe�•æâÝÓþeÃkíðpa+ÛŸ¢Ä¯91aRÜD.·ØšòQŒg –âÆÃͱŽ�‹\{xAN0‘ó|+#c•³âÕ(h9*Z&[LQÞÊ”3cå’�×Ãr…]Gìe‹€b.™qËS¡¿jþ ›Ýl^8ûbÇ=Ò�ýsg=³Z_|žEV;›äÐNX»’yòäÜ#eÓ*:œWn­yµb.wù®_ó¥‰]æ3ß'ÍÈ¥q�EmM[šzÎ>^îkU}`!·ºÛʬ¨fûŠl79^7ÐÙ%4i¿d¯DfÜžM)kWšåÇ6Ä—ÊȤ+Ri’©xħŒµŽrë2Ä8Û·Ð^�´™lË,yáÔJµ�·�goSí0°°á�,+.ÉÃàÁ‡#KžL¹²å˘3k&háB†˜¨¡"Œ‹j2{6éÒ‘*ŸD¹’¥Ë—’6�Z5Õ·®C †*U!U«²jåºÕ+XmÅ–ý(7íZµÙ?Àÿ=Ú½®]¼w÷òíË4°{È›6.¿¾ýûøóGFéyaÇÂuÚP«qäH"‘dJÔ¦Òm¸Å¤ÛL¼õæ[<ñ\Dà •QF!…`{  S�tXQWÝW`…·ÝÝ}^vãÅ%—yt¡—žz;°G¢{Ëfß|è§ä’L6É_Bþ…`iªÆÚ�J%Û‚´9x—`f˜Ä˜dVÂ…ä¸!PTø¡lj˜%‰&6‡ÂsW±èb ÖŘ݌5Ú^Žåñè£@î€À¢Œ|MF*餔öägÿ‰Ö¡›VHFrqÀ&ƒ f˜<‘Yf…hª©©€Å�ÿ8r#ybŠUå)Ýž}†õçv�~7èx…š÷Þc0Úh`Ê. i¥ÐF+­f—F ‡°xå§#ŠÊ¥A¥žú¥˜ª&af«ã­9Z¶oƨ¶Ú‰gtzºØ+v¿–,[8»#�Ç>Ö,î üì´'œpµ e:%qÚz ª·Ì®—â’«ªwŒ.\ên«9Âës'Ò@UwÌ+Œ¾¶¨\6B1,\ÅÖð`Ö³Â@--à]Ë&Äon;±‚“Šñ©“Ù2Ç¿2»ª•\ëɤÕÊEMmÆË×ɸ�{5ßüVwކl²Íú·Ðt×Í$ÑcÛæÈJwÿË´Å)=�jLå&!vÕG]½7�ZÏoÊ`�!6Ù~Ê|v`i÷‹³\mÉóÜ…ýl÷è¤o†·”z#Ý©­ù½eÓ(‰+û Ôn{ábçèêÃUfÔ¸_\{­2ØbÃaüñ÷ üò�7%¤ÐGh¢Í—ˆ¬èa_úöÜvºÑë.ž´Ä®�ûì§Ú~{¹¹ëò«âg=žÉÖwíuäÅo|òË+_ýóуÞô€T½·iìžK÷=ø©N#ä›Åô¥O}ÀÝÔÜ÷>ÞqÊwóÛZý„‡¿©éo0ó@ÿü×<p€ê)àõ@—=.ð†Û3Èv耤@€ÿ‡(¶>ñˆdùˆ{6ÀÄ&~F![ˆ¢1HXñЍAÍ'ÀÅså:J£÷ÄÅ2N`…pÏÖÈÆ ¸ñ�fä"â"€F!)F1‡¹cb`÷ ém8 ¤ ©U�þ ‡øa‡(Ä"шI<›ÈÄ'¢@ŠSÄౘE5l±‹¬ú¢UÄ8FÅñŒ+T#×øF8ÆqŽud�Y�G=òq$~œÏ wÉËËè�‡>ìÉ"éÈGFr’”´$&£HÅMZ±“ž4b½X0’R dŒ#U¹ÊVºñ”°\¡õXË;ÞR¹lL/×ÉÎÂüò�ÁÔÐ0‰8µGBR;J %+ùÿÄen¡™Î„æ''@Mk’2›fÜf`VÉJo‚óB9Še_fi™�%°�åå;©È0ò£C´g"Ù�}n@™Ëè&*MPòF'-%uN©PÀ0t‡y¨o"*NY’³2µaF‡:È�ƈéGEJR¹˜¥˜T)'³8ЕY¨š£¼æžÞÀÕ7pQ7Ê3ÖBqj�ê„§ýçW)™ *‹¨p]§!9*Ìá®BPêHƒÄìt'CPͤúœéhžÒªgºÐ5±é¢®zu`5€XmJÖ¬ಘ gZ}ºV6¶Õ­‹Š«h9×£ÎS¯|½g[þÊKR‘Š{éa©rU�ÿ,v«]ý*Mª³±³™…èxjú—Y²52  íh—»ÀÒ&²®zedjGêW¹ö‰¯Å`líyJjÚV«¦Ôf*Çz\Ëwše^`( Ôä2÷½ÜsnG£;Ä醇µ1�t¨hÓl÷‘Ý ¥o냘¦ã¥lyrÞðÁÑ�„'\0¡Ê ´ðÍðèä ]úîu"}]­uy¢_«ð·¿0øï@§)`�xåÅz0ð�ÅÛ?nzÖ0 †0„'LafYØ0ÉE€†‡,4Ë3©ôµouÑ’¡_àÄýUqKÍèÝœÀØ+2.0‚kLÞ›¸:~0�%\á·¶ÃDN3ÂJ%�6»Yÿ pf€œM@ç:Û™ÎHEª öÌgÕ¨¦€4iH³§öE€&9‚0ˆF׬fiˆ´¤% Åxy27¥^`�tQ5{:�n~sœç|çR—šÏ}ö³-èAk Ð< ¢Ç£hF;úÑß‘ô¤{ª‘Xz�ñX:eóãO[�¡n3œµ g˜úÙuFõžU½jVWÀÕ¯v‘¡g —Zƒ Ñ�Àu®u�Jû:1—ÆŒ°7=ŸNûݤK¶–ÝlhC¤ÖÎ÷µ] ë–½…Ûoñ6¸Å½r—›×•F7°7³nÀ Þ¤¼éMj{—ßúfõž¤Ü‡ÏdFcÁ¢¿}k‚üP¯ÿ97 Ò}wGüå N6Å�mñ‹4ãß8uDêñ€|Ì#8Á¡pr¥\¿®lf\ó¦woâˆsÍmÎHœZç-è˜H¹ýs�|äC':¹uΤ»ØNOûöJu8Càíp¯9Æ­Žu­Û“ëÛ ù×]ªš áï€'û-ÍÎp´«ýðuc{Ûáw‹ÏçuçØÖgB«²è}ï}·à+\éê6<âG¯0ÅG�ño—ûÍ­}[�Ûý‘x·<Ð1ï  Øþö›ÿ»àùHxÍ0�ôÀ�–é—�zà¯Tb¾[¿ñ×1öI¹ü×Ku{Üç~÷ _ùÂ}/úà{RÃw;ÿê�×ä qùàm¾äïNy9EöÓ¯}õƒ�û!`_å,¯h÷¿ÏJ±ÑÍÝqdzX„U€Î$6YæÝQî1KdÍrN ¨G¿×Ø=ÿ×fØxMø�. 6r0‚$¸€¹7�w¤Ê"��q�.8Z(HHJ h€"H‚#h‚›‡‚xtfŒÂ‚€ñ‚DHT18ƒ5(F7X€9¢ƒ;( ¸^?…X„VÈ=G¸�IFK(m6ЄNȃ€çƒ‰¡Ux…hh7Y€[¨](m`¨ƒbøwdHKùq†i˜‡@sS$Ї3ÈAoá…^‡%…'ècfF…û§‡Œ˜0|ÿ臈G!ˆp8N(}˜‰$`@îu‡‹Øˆ -�H(‰”ˆj„8‚šØ‡œˆfŠ˜ˆ¡‹A3Š¥ˆ§Èg©ˆ‰«ØŠne†Ÿ(‹À¨$´‰¦x‹_h‰N¸Š›8C®xxŒÐhÀ’ÆxŒpq‰ÊÈ‹Aå‹°�à-³”(3b&h4#3"긎Ü(dáøŽï5Ž@RŽrŽèXëÈŽÈ�ü¨aò¨ôÈöx�‘�êHý˜�C–(³dŽ+D�Ia�‚ �©f ©Gî1�IÑŽÙ‘v‘w”‘¹é‘&¹\3KuøGÌÈ('ù’q•’)…wÄ’ó‹0ÿ™“Û#“!I“‹1%©“BÉK<©+ ”-©\C¹”�T”‰q”�”L9•Ýã”,•Œ!•T¹•\Ù•^ù•`–b9–dY–fy–h™–j¹–lÙ–nù–p—r9—tY—vy—x™—z¹—|Ù—~ù—€˜‚9˜„Y˜†y˜ˆ™˜Š¹˜ŒÙ˜Žù˜�™’9™”Y™–y™˜™™š¹™œÙ™žù™ š¢9š¤Yš¦yšÌU* Ò ‚šL©šNS®¹”°Ù%²9›BY›s›¸™“º8¼Ù›/ù›¬œÂi’ÄY*Ç “¥‚Hˆ¤œËy’Íéœ�ÑÙ�Ôé–”�Öy�ÁØ`Ù¹�Ôÿ !«é�¡žÔ)žÎIž bžÞ·šŸò !Ù9htJ²Ó`î|ð)ŸñIŸÔiŸ+„Ÿâ¢ŸûIzýéŸêœÚ?z*z ˆ— óy¢q º< &*¡jG¡ñI~Bp¡zŸq”Ÿçå¡Ê þ¢äG¢¢a¢f„¢À¥¢‡¢ ¢0úh=et�H˜µ6Út8ª£; = =? ¤BzYDZ¤/w¤/𤰤 Ф×ñ¤+¥R q«)¢Hš¤Xª¥`Á¥^ú¥ïFlÚ¦bZ¥I*‘>ÊE@êhªj qmê¦oŠWVzrʤtê¤=4¤xš§i¶š5°¨ÑÿÅ" A-#‘hnàæ–º°¥’œÚ©¥bH†Ô`�ê©­‰¨ú¡¨ŒªWŽ ©#©B©�f©n€©šê £Ê©Ÿ ª? ª·Ú�¦j¨Z�Ê"¬Ê1®ê°²J«š±©½ê ºº«çu« à«¿Á:¬ÒQ¬fp¬:‘¬Ëª™Ú¬¶ú¬µ­¼:ªÖz­šáX\µ¨ÂªªÄZ.WP¯ö“ «á*ãšÎ:ª’!/0°K­ëÊ®˜á®o¯Úš…c¯÷šùJ©ûÚ¯˜ñ¯�°›²á!p·&å²îÄ Þ”‚´I»´a;¶”Q¶:ËHi«¶>¶uPµÙ·r»OtË(q·yÛµ^Ë·Oôœ¥â´~ ¸QûQƒ‹¶k˶ˆÛŠ ·sK´–b·Þ¹+ãµ<@¹Ÿa¹—ë·1rWRúbs�»º{h‚FhäÀ¼Ä)<#P¼Æ9y�¼Ê[jyDÔ†F9’�1ª²+´kE¶+¸«»¹Ë»â»+ÿ¼Áë= B¼Æ[¼ù¦¼ËkqÏ»BÑ;ž_@½Õ{½.�½?±½Üë½¾¾ý#¾ÀK¾(a¾ç›¾ê›5×¾ýó¾ë¿�Z½@¿öø»»Ñ»ü«<7À!ÀÆKÀê{Àª½ã!½ Ì© Áu»^Á½Ý[Áß»BˆÃ2œÁ§À^s¡¼¾ö†ÀË£Àˆ4½ <¿‹V»)¬½+ÌÂú«h$Ã3ÌP\ƒÃÖVÀlqB gª¡<äÃ=Ä&,Ä @ÄŒt¡,<ÝaÁýÃÄ1LÃukÃ)#ŬFÅ5×lYl”o!i?\ pÂCŒ½Eüe|Æâ¿^ ÆˆÀÆŽÿ»Á7,9œ¼ØVjtœZ=x|zÜÅ|ìÇa Èc,ƒ,hbȈ¬È±šQìÈS\À‘|gí=pÉ�ÉàÅ} ÆbMØ,RƇ ÒC"MÒŒ­ÔŽ­�ט{­•-ÓŒDÓXmÓZ 6ž½< ýÕ¢Ö¤-¦]!ˆ]ŠÍÚsÐØLýØN Õ”M×0mÙ0DÍÖ¼ °Ù|&¢½­<¿ÿ}" Ugië¨ÅÍÇ�ÜHÝÚlýÚ±-Ù³íÒÒ=Õ—-D×ݼÍÖlTÌÝõ¸BKëdáMgi‹>àå}ç�Ú°Úé½Ü®ÝܰýÜ“�§µ}×Pßyvßr–ßä×ÝÐß%öß&à.àn.DªmÔÊÍÜníÜ‘ ÝßÔmÝr†ÝÎ~|îáúâ">â%'>)žÖ+Þà-þà/áj:áó]á5nßžãxµã4ëß%Þh;â$ΧMÔ®àkÝÖbñÖ²-¶ ëäÕMßQ~áS^Àú-�ü}åžå¾å\äC^ä‹Íàëíàí ã­w­-êÞLÿ>d—K´åë5Rðè�Þlƒmg�hØV8wp€°é€°ŽqëAEŒDgÍöb€ÀÂV Ô¦°ùG�7!in&ì�oÆ®*ÈÎéž· n¢>ØÒ®Ô®»Ö~ØîXÚ~Ü^Þi³î5µ®«w9‡~îüºîQÑîRðîÃ.ﮆéšnïËŽïÍ®ïÏÎïrfê¨N36ÂêÖæêFë6ñíÿîh8îoñ¹^ªïFñïÆìÞî?²?hŸì÷.ù¾ï£Ýïÿž»ß5Ãò¬æò}ó! ó4…6ïF8oî:l<�ÊŽôÂïCOEò‚Àì9áìêíLŸòhõÙÞòÛþòÝ^!XÏð⮫u9‘“«?ö/ö¿Þîð^uÅÞñÇþñ›>ºH?òðj;pòÓ.÷gA÷ŽuE�v¡H• ¯kÆ{"\Äóç“([²„ “ëi7U«Ö¹³'O A‡=ª2éÿRMõ<Õ:µ*¬YµÎ9íìW± È9‹VmZ¶#ÜÂ}\Ýúu†{µðû70`Â…̼ûù¹’'W¦|ÙAæÍÝ:ÏhÒ¥+ æºÚÿ�Ö^ƒ (¡ˆªÁ(�RŠ)§†ó­ªà®ޏ®^:¹±Êj®Žç kk¤·@oDô0ñÄC\l1’H²Â $bD¢%Ül°qÃ:"„b ÊÔ‹ŒÄº´óqö({áH$ãC!<& SÒ(-�R¿ fšIJ,-h ¬ÀV#ë0?HaL2cû) 4ÓôcM%Ú¤R%ÜÄ"dNB†°J€Z‹-7ú âO&ÍRJ•»âPDÏÿ*Fɬ,D #½îDSL`E…ZéEgd©Æ7Ô‘Gʆ”T.!},R$“Œ¯É&ŸŒrJý¬”iP-Yâ0/�SL2Ç4³€4ÕdÓMýà\JN:íO==¡O7þ "P&p-0D5kÑFÇ|”ºSË¥‹R-½SMiàTF—²ÑG¨G͵(UõVmõH%aeRV°¤ÒV ´Õõ«.Uû2Ì`…5³X4×ô£M%ÞL)Îè¬óN(£M#:j­ÅVá íö Eb4G)ƒT_š-BWu1ý¡ÝwcŒ—�yë��T L­Y"~×cïß.<@àðð”zV ¶ÿe•v½Àã9sØa)ÃbŒ5€c��…ö§=§õPAÝö‚•YþÖåpSWÄ£û†èfu#NÁ°ž=] TzEúÞRóõû¡¤#[5)ÊMpÚé&§–ÚàZ¯–{á㚯?{bŠÉF¶4e`vNµCf[Ú’áÎöó”¹]¹å^ŽY‚™pK'Fx?•7Ôæì_õ„¿k¯!'¯ÜòË�Ë\sª­¶ë”´½ôÓc[õŒ“ÝxÙŽ›9ÏÙGæóíkãÎrîºy÷]\™É•þhâ¥Èx)LZ‡›>$ð,Ίa w"éEnßÌõ°—½¯à7Ü›š÷fbÿ†0 #ÌÃ3>_…©|@9ŸÅÖTœ—´îu{–ì жÚY+jà!–Z¢2»5çe/[•yþG³†h€)` ×§Áöa�vj`Ah¢RÏG¼€1 .…ƒR #B’0|&Ü×È·Bb¥Î…~€adØ>ؽOd$£Ÿµx¨²ˆ8"£Š¸�#ê+‰oYâ@šhÇ'"P�faàUظ@Px䢿x€2ŽOe<#Í0Â$”0t'tc ¿Çº°ŽwL›ãÇÇjép‡=$” uij2‡dL"Íu³&5R �<àR¢8Å!T‘ W@õÂÅNÿ^ï“  £(¡TF8„Sœ¦<¥ ¾VþjX‚`g;ðNxΑŽ‚äÙØWËÂëãŸþÈ• rCÂ$¦1­£�/$T¡™IfÄŽ×)FÒ™“¬C%wdELjR_Ú‰BG=ŠM zò‹¡ô&8ÅNr¢R•¢K§ ÍÔNwÂó�òœåg;}â°Ÿ»d/úKB² } BšP†2I™c`¦DðLJRÑ’-Zd4j.Žz´£ ýŽH1HRQšô¤)5':=öÆØÀ”�2�ékjO×ᑆkÛ§üÜ–KþÓ§ø;TP‡8T¢ÆE]Ô¢ {XÔ1,b©ÊY8ðXDVÿê[£,KÌ.g9àŠ@t2ðYuÝl‘ ØÎ^ ¯ÏX�J¨D%P &ç,íÄÓ¼æõ+0 “J•c_^dœeÃÅeŒ{\$ž-`îLX’ÜDR�Bs €Û�hdH à.‚~HÁa áR Ó@�ôÙ Ü,°,aÝpXÄD¤Éi¬YËéN–u%´¬0KÍ’…³ž­¥D‹.u•V/§Õâ R{½Õ²6 ®­clÅ2[vÒ(¸ý€nõÃÛ¸úöEÁýÉp'PÜã7¹XnseòÜèF–ºÖÅ®@´ë#î‚À»ÏµÏ°K^0™÷HèUïzÒ^ÂÂ×°†ÿ™/c©âXÈJ–²ç<@ÿà# ˜-è í�+•"ç…Áz‘̃+aÖR˜žn†¡áŸpØÃ¥qr~Kâ˜Å)^q‹[àÜ•@w)Ò�ñY®û«ìfd»Ý­M {l¦#ˆOåÈy?[d#3É…U2“µ‰¡Ô·÷ÍbåÌXË#à²�½œ.K…/cÎK™=£ZýHxÂj†íõdkÚÚpø�s¯oâ;Û2ÏÄ�ŸnÖçw2÷Ï/tŒ§[]C×x 7VOŽwìèÐ Ë?†¥Ç`éô¢+Ó ÙtŸ”Ìûä¡É¡~²}£ ýF´²—MµfWÝê½Ö`–5ÿ­ñbë"àº4ºV³ ŒM¹_×!Øúö¯Šý’:‹%Ùù.³ïúlåFÛÅ€ñ eŒm³ÚÜÜ–Œ·­’x‹;Ò“r¥‡|iu¯í~¯’ã=oQ“ZÊûÝ·1«vno�Ýr�.ðr 63åÐÜZ^cÜ×v†…gbr·”ëíÆéªçfƒœÅ"Ÿ6É«mòkÓÑ6V4Ž� ‡ÛLP"·¹Ñ�éÀª+DîuC¼þéзޣ¾w¾�Xôÿ "qPzïEà t™RïÎŒ{´cðÐçÖI¡Lt­ÝŒ}A!v3œ g±˜ìȱ²ÑþqtAûÒ4Ì­ÿ]è”k›å‘AзaþèØ@é(wÍÏ}ótS*Ó‚‹Ó o /^èø6u•ùMÉS^ÀKǼº2ÃùÄxÞ´ACûÝ/ú„“þ%«™ꛢz޵¹ëoþúëqë~÷S½±³Úã¸ó8jQ;?ë½”4 4”«•s>� 4‚â{¹D> À/¿ƒ>À#*êK뻾“È>2€2ü:}£2T0U#¿¦Ë,û·Ïr„/ Y €%Bù«úûÓ#d½ýs½ûº¯%lBÚ.Û‹Bg˽�Û½‘+¹<¹,¤À-äB/l‰˜Û;å¯2 >r´@sÔtì&<‰4vÌwü‚£ÑD¨I›�– ŒÁ]k ñ ¤Ê(ÊϨšÒ ËŠ?hÊ?p &¨! ÛªÊy%9,…Z®ì¯ô“ § ¡.²”¡°’zZ£Ä‹C�)ø 2¸½Ë1?K˜8‰ÀH §|Ê!ø�ýÑ›ŒzˆãZÂÜÉ6i y&«”.éj „q-\§ßj§4‰ iQ(@Ã�Ú ›´I§ÉIý0L%èI–øÉ œ“¡T€¢ �£TÉ“XJ#ØK¨ ©d’x³J«ÄÊøÐÊ„âÊHž•Ëÿ°œ�a9Ë™HK*[ËhËvzËß�˹�ºtÍ<ÈË>�;¬Š¿| Á4.Â\ÑDLWT̪Ä�•xLþˆÌpšLvªÌh‰ÌÔL¬âÌÎD„ÏÌ�ÒMÒ N£JJ¢4JÏ@Ê»|M!`J§œM#¨Íð¸MÜ´-ÝÜ ÞüßN•Γ"N31N™@ÎÅZÎ+pK¸„ιœÎ¤4 ëÄN¿ÌîtˆÁ,LÃÏ5$OÛ2O•@OÔPO8`OApÏÙ�Ï„ÊÌU¤š¬Ïû\ �4Ìý¼ÐþEÛŽ�ÖãŠ]ü˜Ý•¨Ý9º]ÌÊ]ÝåÝ}Ù •O™Þ¾M‰â5%y2Až]Þ(Õ)U\{åKé¥^¥¥§›Ê5¬Ëe×Ì…©«EÓ¬íЭQ}N°%ÖôµXŒåËÕuÖÖ…_ãZ „ÙÇ5Oûu!ü¥«Ô]+à_Gõ_HàSñMßôÌìñ[ ¸a‹A`¢PàNe` }ÞÅ5Z¡ à}E<°À`¨U² ¦Õn§&�VÓnXóe ô�XÿêLÑe=ÛfÌ÷ýØã’a[¡áã8T%^“Þáý¥˜»â¼u]}!b®4âš%à¿5à9bâpbÂíYÃm`ç}`è•àÆ½ã¼KA,þ -Î^.Þ^î^Íý ÎaÏUN36áÑ [5žR6V]7f]«‚á c+±c°ÀcEÆaüåcºõáËüßq%‘è�%l ©]^Ö‘2’Ú ÁUy½åyªâk¾f’ ׂn(¾ºgq–aaä–`äg¦  �u^ghg›àfxÁ”ÈHgIazÔ[±&Øg•šæÕ g;–舎ų‡ðÍHèÔü „a8þ 'ršYMÿŠ®h\1ЪŽ2š)æCMfÃ]æif¯<ç߈fo~¢(ºflî+ÙænÞ«”"€‚qfârfb“NçuVçv&�wæfyzžÜ0¸g ÎçäÚç&èçÃYŠh�è(èY;h®LèXhÏhh s-ˆ6%‰Ž�Š.ë¸hÑè(àÁŽŽÎ�öJeÖ]f#ghÆ�ÖYi–æƒlÖ˜†�”κ9”š¾iÎiÞéŸèiŸv皀ç¡.ê!°çBÂg¥fj§n�¨ç©h«ˆ@h…J†¶‡F�°F£±³¶h¸Ähµfk}ñèAiŸÕÑaâ°»–æÿ§¦æ>ˆ·¾þëÀ¦i©6³Q s¶kt^lÆþé ŽçÇS ɦì!²ì|ÆlsÒì¢,l3¡êªVƒvÑÞjÒîjÓþê‡6%Æ–Ü&ëÖ^M´~�›‘ms¡mµíÔ|ïàÐíBâm¸Di™†«(n—ž âpãæläž²”Xn­¨ žîiè~l¡žîyÖ¸´î—Án}æçí~¢Íçï¦êÏí¬m(m+9íÓ §öæo¬ˆoù~m©ïõkë¹|ëNY^¿ ÿ"?i¼Vé2ðÒHT®€çâþ%ïŽ�ä~p�fî\un wì;€l 'j ·F¿¼¤¾lO%îî㎠ÿð>q¬^­æê"ðê4[o4Šñ§ñ¢œïžÀñ3‹Áoóœÿñ ™!× Ï•ä,#$� [)Gt”ÑDÁ31›þ‚𨊪hï ¿K·,®g4ù˘\±'8õý‹²Æ³a¥û€ò^ÞaÑ5a&:—q;?k§otyu ±˜(€D`wpa·?bÿ cGöPv=`vµtöЀvÕvÿG�t6šôk�pßv?þ‰n×”oÏvP×]Q?ê¼)õä:õ'Hõ¯P÷klõW‡wŸ•w&¡÷!²÷÷Æw¶ÚwBö÷«.—€·Ã”öáY^„Wx†Oô0Š·7hz§�v‰§øUlp¾x$Èøáàvªðv,wqŸìQ/ùr?ùsGÞt¯hV?á—OqóŽy3™wšg›‡Æy™Òy"æyÐæó5 v¡× ¢�£ŸšÝÆ­ª0tjÏ ¥·§úˆ�úÄŸz‹¿Fl':mÏú�/€Žo‘�·ü�§Û‘'÷£2÷”GwUGûu?_9]{6WñÔ”ùðˆ{¹gl©ûèÌw¼÷M½×—ÿŸê¿Ït3)zÃ=zç Ä÷m0ZüÐhü¦‡zi—ú§«Ê×·Ë× ­'®êšðz‘w±}²/}³?}ŠN{vgý6�÷·ŸyÙŸ{Û/Ñœ�N~ß}IñM‹1ýpšÏÈþˆ9çX±¢B„PJiå!¢ˆ;&RŒcñâ�Œýpì˜ä#È "G(i2Ê” V¢i©À L˜blФIà&Α#}ðìIç'Ð B‡âĹò(ƒ#J—lje!T(_¦R]cõ*H�L– áõ+X¯KÓ�•`ölÄ´ˆH°uáV§H#rç.]jà.Þ2z÷RèëàÀ Vaø°‚ÄŠÃÿ0nŒoãÆu•jÔ¨6"aš1pîÜá3hÍ“.mú4êÔ§ w4—kÉ"²³ÐHÐ`B… B”HqâEŒ•‡tô˜5 Ü °—8Ú͢^fÖ´Qôfòž>�þJôzòÉGœŒº�*U7ê×O²•kØø!Æ–=köòÚ¶oáÎ¥;ùñ]{ñåW_ªvbŠ%cÀ`â 7~™ifh¡]h ‡rÈG®é´œlEЖ…m”T IñPiý\pqLXGí%Çlι$ÝtÕY\ÚñÄ]wÞ]páMFÞSæ¡7Õzì÷žIò…E_öÝw[$¸åÿBrýÉ%žƒêE`�"h˜‚ 2è „Wá`¢a˜azzø' ‚ ÖÚk°•xbЏ±¸Û‹½!¤‘ÖŸ•vÀ¦™îÈ£I>B$u5å†Pr&˜z*’tÔ±*«L&w¬±BiØzk•ê�°+¯X–”RJñqù±Åâæ˜É‹šFð,´lR(„–i¦t2hgex.à§jàR;nj ú!"I†ÎVÛ@*ŽÚ"o1Fi¤¢‰f)ŸØbº)§Í±ô£t¡Ò4j¥žjjª¬¶J¤N±ÊJ­·âš+¯½Â¶lÂ*EVÅ ¦~dÂ…q³�A-›ÔZ;˜¾,hÿ·UjáhŠK.Τ™‹®H$®‹b»Š&o£ò>Joöj†o†-óË©§ÑÅ$° |p ×á*\Ã:«yÛš«ïêëk|Ç{lÈÊ.[2^'?+­Ê+·ü²d“M8sž†+xÎ…W»2ÏÊ©k"»¹»(.˜ÒI+Í4h-·°yºýF ª�¿1úH›zPZ×Aë9uí5±7¥TbO@¶Ù  �q¬_q¼”Û¼0<ña†Éò#a<ÔR‚8_·Ý)HïWÕÿ¹ò-·ü÷Ý·Ü™g|*]³áåwˆ}â>3´ãBëy¼”#=>æŸiÎyÏýúËÿÀsRËú¨F÷†Ò™u?QëÈຆÁNv¡ÝBl‡;³ínY½óÊï”<âÏx$@”·,æ)Åy‚€Þɤ—êYÏCØÓž¾ºç=}��3•Ÿùrh ôŠ+‡jÜmV44FMn^ó»\ýîׂÎAí_Ÿ s#@Ì€ªÒZ8¯ v˜]bj'¶ V¬‚Àº`2x„ rðü`òD²<¡4ïyw±[TÈÂ\Oo0Ì” ¹÷½ÞPi:<äj×C“ü�}A|U9ú%Q_›[bþ<çDÿ©:¢#�HLg+"°uØy�üFˆQbd´Wx+ß‘ÿxnk£=B‹„G0! ¡¥Ç¾T��.ôãYÈ |…´"£)(k¥oqˆ šß'9IÑ^õ»”%ñ§8Mò`S‹bB¦Ê®$uX4e“P+U>0Œ#Å(x1 ΃µÔà-ÛøÆ]Êq„t,¡ €ÇaR ˜}´V21µÌf†/C8”f4y8"kñqC„_ÑäG/JbN‰LäÑç èÉ‚²¢$å;xJ¦Ò�V€`­ðY¥Ü™1%hT#98Ð8V`ލã ï½é³…çCæ'JCBŠÏ�µÙø°‡½;pµ«CÊJl#�&0x0‚Ñ Òê¡ñ!{Ëÿ eé0=Ðujb¸ë] ¦:¸Žî«+é`!ØÁÎ%Vü:Š½Û±¡±Žd“3 P¶²`e€"ž1p¶³#ølG4 ÚÑV¶²r�í>;°V®½*lc¶jue]õê².+Ö9�•uf=kÒº‚µfueoå«\cEW=دbÐ«Öøú¿2°},aåbØ"6±X¬ØûØÈJ¶¥¥ìe3+�Ív–³ª íhE{^ œ@©ý,kiàZȶ¿¥mm s[®R÷(»í-~{VáWin ¤t“ «å6¯ÐUX„sû×Àb……ÕaWâÝ±âeÿd…P^óž7½±ÓìdÚë^Ðr$¾ò=o}sßÕ¶öµþý±à ø«X¬`´ªµCB&Ìqá*áPX&Î}î¨öŠ\ W—ÃØýðBŒYï‚Wb'F1y%;_CÆu‘ñÞ[cÏ7ÇxÙq~÷ ä=—ïɵ-ò‘pàÞ.ù! vrq­å¸òs®uµ²s/̪ ë(Öí°‡µ bÌ%ÛeS¼â5ƒU½s`o{åìk ÎÃA­ØT›gó¹Öãò³VÍe'™Ðnnp›Ì!\/º¯�VseI¯ŠÒ*Ùðu; f1�¸Ì· uš“Cj¤˜Õž¥ñªéÿŒãWÛ7Öøí1m­n@áz«Ƙê¢Z; Þö.¦CÙ�h(CxËÀŠ�”-†£0»ÎFÉe1ÍE%]€ÍŠ KŠS|ÙO¶Å`ÝíR†b$à(Üñ�YF`-±üæwÝ&gwR®r.°¼å—¼$œño�¨6¿¹½ï�ocþ *_yËYþó”Ë¡èFÇ#ÀAu×£ŒiL á¢.u<^V¿ú•tYQ.'â��8\žóœ?�½ì¸R4n¤ŽÓJ<ª­ùÍmžóz“œµ'¿û°‡Þ„ ³ü囋¹Ýf>¸Ç}îØ9Ïתw¾sAïF?ºÝ’°¥¯¤ény:ò¤>uÿ»UýêVϺw¶nº®{ì:{KÊnv¡ýj×ÛÍãö·� îrŸ{Ýi€÷Ý£ÆçCg¼ß[ø“ žð8Ÿ;âåûŸ3Þñ�—ÒÃp¼2Ýò˜g‚æ£Nu°zþó^c¸èFúˆ›~$¨GƒêÉ~v±f\(�}TfÿvÛ£Àð¹ç=þI³| =øÃ‡Vñ}ý^ò¡Üïñ�ó=^ô�ÅôQXž \_ö]Áö!E÷Áè Eø�ÊøIX%Çù¥ß¬Ÿm´ß¼Ž´ÝdÐ^íÙžýÕ]þÅàþ¥ðùÝÿ=K¶`á!ßÎ)ßâ!àÐ=ôEžô)ÝÀUžõaÞVàQ\ÿ` ÅšJ~Ý†ê‰ ºÙëõüA…üßíåÜýÅ`þ=�ž¡Þ�áò¶!Ã}¡Úž—HÀ~í×E‘FåTŠÞé�š”Aâ b îV|°šÞuÅRŒÂ�#ra «]Á@ \"&�í@ Ï„Lq Çl"y—pÝ!ª›ša®bº¡’À¡ÞÜÖ¡k¡"`ä!ŸìáÐõá ¢ bXâÐ!¢Ý(âQ0¢å9"@¢×H¢�Qâ¨X"&^¢&Š ‚u¢Û|âp„¢(¦):…)¦.¦"Ÿ­â´¢¾"¾á ÒýÕ¢-–£.f/þÿœ/²!0£X¢�"Ž$",¢H4â#:c¬@c|IcnPc5^£Äd£Ýx"7j„7Šb86Å8®@9š#ïÙ¢°#0œ”¤IJ—íp€J®ä2Ñ#ÒTJĤLÎdL–¾ù¡>"A`|�ü$PV .!ãJ(cÓ1£$¥RŒBŽÖe™¤I:d&º�íHäÉPde´ÌEŽ¢Ø@IKZ•GÆ HŠ$IB¥ ¤Ø¬$K’KÒ LÒ$\Úd1á$âNZ^Oº P%Ÿ å@&cA.£#*åRŽŠ?.$X™¥H¥5R%6ö–6zÌ„´ H~#8v%y|%4…¥XÚâ|æ°ÿaÜ …b¢¥Ä¨¥JJ¦N.¾$ŸÀe\Þä/âÁ]6ÝÓy…Oî¥e%å˜ %azÁ¦S&¦Y2¦h±T%dNä6eÚ¢efdA¨f¦l&gÞH‚fhòÀh^@iòUJ¢&v²&Ô#hÀ&MÊeõÐ¥]z Þfäæ^ò&ùfrç`gq£�A b*'s~€s’UdËdêKe~£uZv®æÍl§ºu'hŠæÍ‘¦Yšæ­ &œ'ù†z~{Τ{&|ê¤|&!òà¦^ê&~�~ÂÂÁp§ah| hrZžíè�&P‚K„²HæŽ$©’.ÿS‘j'…®ÛX²cYB%‡ÚЇj愎h”¨Læc]ª¨ÃðdXØ'_fˆ_¤NÔè�þ'X°�B%ÚDÞŠUBKð鑚�’.)“ÊPG>i…Ú"Y*ÉxÂUyª%–¢g圣6*—Ö¤šÌfmŽI^zŒnîf_öæ_%�º…p&›~…›Zžbš‰È©Ûx(‚9Hœ(žÚ"’î©ô©Ÿ‚% ž\”¾â”ž$y¦¥y²¥­†w~f£:ê£zi|†)^Žé‹Þg¦æç¦þf§ºÀ§fn㩾©Iš*ªzŒªö«ÆÉ«Öa¬î)­vÏŸÞ*Ÿå*,zG¡ С®e­:©°|ãóèÓ«_Ïžýãl¤%O®xñòîÍ =—<™²`釧¹¤ÚO¬¥áZM°ÅÆ“O@ e_fØýÜSQWrÉ)לs_…%݇P—–u×õ¦�\Üy÷]yŒÇbíÅ(ãŒ4ÖXØ{ñIF™e…_HÛIZý§Î8H&9àjÑt`‚¨ÈF›mµ[„K™$q^ˆœrËmˆÅs‚�ˆ�ˆÝ‰ÜIðâ‹ÁiãœtÖi'b8FÓŽõY™Ù��9¤hþý—¤’x`PJÉ 1·åveojI!:ødª)†`ž#昂u¢™!Ѝ¦‰Úµù&‹q²zç«°Æÿ:gžê|ƒäDô=#韜Š¢�üZ¤¡‡Ž³¤¢O&èhm V ( dt„Wa œ¥ÃA¥é¦_‚ù)™¢jG*š§ºÅ&w«–תº²¶ë½×P6ã„®”5²«�½ê¬9¡ 4¯‘Å›èe‹6º ³ª�²Ë.ye@µ”fÙ”pNm›)§ÞŠ î'ª˜ÁYäZ·¦v+¤¬rºæ$'¼0Ç,ó@ò6Tï½åKѾõ+h°CVZÁÇ"œ,lË.é0ÄIL±[•^Œ±ÆøðaõÕud­õ·¡‚¬�È$›j]›ã©¼2Ë0ºìêÌl· kÍÙȧ³¾=öÌ™¿ƒ ±‡ÿ=TÂÊ.ì7QEY;áÔ_�µÖYsÍVÈ*†M‰d÷evÊh§MÐËnwîùŒpË­3†÷ùükÞ Ì7¢ªåöð뻀!ûìIìgQPä®{Ôgœ¸â|0Þ¸Ç]Cî`€¹¡üòv4ï|å|]¾Bæë¶üùõØ£ºŽ£#ÇW€â têB“F´íÁþðì´ Ž>f™é¾»Å½ïA5ðÁ ïxXÆß…ü_Ëcžóš=¦H�zjcWöÈ@ÃloOݳÊ÷¶¾ŸŒHªZ±‡õÅŽ}`¨]ëê¶ùåŽw½»ð„W‡ý…+."ûß ¨¼�;e»7·¶úð‡ ™—ÿ¤2€"1H¼ –ÈD‰I ;õ3R€Ö1·ÛÜf‚Ðø”ZRÁÅHxñ‹¹£s³¡#A-oùòôæD¯à�p,R ˜ÌI/4¡á÷ÈÇö±Bå0â“&6±�Pì�‘pÀÈFVъΚ ÓÂÅT|Œb #›cF4E|k$_6Úh8ÆÑd½¡ã_úÈÊV¶í�Å!¢ €Ä<(Ñ�€ e"1¶ÈF2ò‘VÄâ$#PÉKz1“š¼LϘ–4žÎ¡À¼HiÊ7Êñ(ª„+·ÉÍvÁr*³¤%!«�Ë\"²7Qü�/©3HFò{Ã,¦1‘™‹M2§“Íü¤#ÿJjVóšcÈf7JÐ9}S–‚¬å- ©Kt*R�ëæ%)¦-vqžÈ´'ðg~šü”fCüiJ€ ´ (M©zÈY*´�¸l¨[ÒYšuâ@¢AfE)yÑKÒS£õè~¢9Í6V³&Å¡IBªÒ¦:51Ä!Î7¦:ÈZæaI2EŠldÓK_âô�\¦ZõSer’™Õç3£™�£&•.2|ª\ç:˜¨Beªß¨j-±zN·lu']ud;!©Ó ¡iQ}H¬b�ŠV¡‹­Ñ‹^Þ:—¸Òõ²˜ˆ]Ñ�W½"‘¯NÄÎ_ÁXvæË�…mÎa¤ØÅšõž�UëG!{Éÿæ…²$±lfwûÔÍv¶ˆVýì€HÙŽâw´´¡�MéÙ©88÷¹¤\­kZ›ØO-Ó“ÙÙç*c[PŽ;ÝÕ-oÇ‹RßR¸Á]RÁŒ{Ü¿&·'ËEfsŸëÜ花ԵîY± J¦FÖ¶"kSxÿGÞÔ¼yE¯UÕ[,ö¹ï�o&çK_ûR¿­Õ/lù«]mrÀ*°mÅkàsØÐ†Š¯ÁbcF"œá´—ŒÃãY.É8Î1uÀã›ñ΄Ë†Ld’Âñ,Øq€’—ì¿¿h®0xDÉx¢,,[™ (V±6X| ×øË`6â�sŒã÷˜Ç?²Hˆ\d£VÿɽY2“íRÇ+ÛùÎ ÉòŠ[lÌ0ûÆc&³™Ïœfµ ™Í#0òáì9+¹Éƒx2ž'mg=o™Ï—ü³¦Å< 2—y‚gF³ÕÌD'Úͦd4RíHKšÒ°6°¥¹ìåMk:Ð:u¨ �ݸ˜º~GUõQXíêX»Ä³Æôm}ëN{zÐ>µ¡×Œh`¿Ù,Ivt±�ÍmÞ&»Ë}f¶Ÿq�cV˜ûÜ&„ÂÉâ"=k§Ûqv´ _Ýíz;õÛµ· ÝÙ)?øûßçF· ±Ó¦v÷.øåæmï†ËßáÖ·ù ¦<à¬H7Á¹cpŒ!ÜÑ 7ÃNò”~Û(ÿO¹¸©Áò–S\9÷7Æ3>ðTrürõOÂo.òÿÑ»ä@gåÉSŽò|¹å.‡d¿c>s�Ûœ.ŽÎAÎs•�<èXoåЉnô#�å/ÏJÌýÐôš»%ä*Ëy_võ…û<ëp禖1¬X yÚ¹Áß§¨F¢sÑÅE=È‹ÆÓ]=Æýð®œ;k©kwOçxŸJwßSÅ#þò“Vüt�œ»?^q‘7áäãÒ&ËcþôVÖ¼M¨Ëú>xþ2z“ä­ã÷Êõ¸¿²–ÀûÞ·žº¤$eì74ûÇQ®·Ï½ò ¼ûÞóþ÷­ ~C­ƒÐËoôþ²=m—ÏýÌ:Ÿ÷Ö?ÿô¥ïDê[_wØ’öýÛýöÓõû ¿5ÆO~¯Pÿ¨Å‹ˆ%kz÷û_¥ð'ôWøƒ¢76à5bÉ÷ €ß'€¿W^Q€Õ”nµG¶} ¸�Û€â�H�¦d�Ç7È~˜‚¬ä�ó‚<(?('¸]*xƒMå:¸ƒ%Ãë¿„B8ý‡ƒFXP;ȃbヨBø„×ÂG8…—•„:؃mÑ„@…A8Tø…Oõ"X?(Ox@�†jØM/"Cu"g¨Ci¸†tÈJmø?o¨qh6†W‡~Dwˆ}ÑåÔû Ø� ��JÍÔp=Ù(=×—í ™½Ù|ÝÙ~ýÙQ Ñ¢-¶†MÒâ¶Ø8QÃJýÚmZ‘�W16QÙµíN¸ý5}Ó]-ØRüÛaÜí,n˜ÿ\ÁÇýØÊÛßÐÜRñÜ´=Õ˜ IÓ�ÕíÙ× Ú:=éÌÓ…]Ú%íݳLÃàÞn:Þ%ÍÜáÜ5ÝêmÛì�×2½×ÔÝ×û×PÜÛçLß=ÚÜMúýÌY<¿áíÖÞà$-àä@àa`à-mEíýÞ»ßÚnߎßÂÍlßÍáþ�ܱÜSeÞå€ÞQÝ >ÂjÌÈlÌÙÖ Ø^íÛ/.Ö‘�á2&Æ}ãžãäÍã>.Õ'~)îàËÛkxGQb>æ ex[KÍÚ]ÜNÐjÈ=¥ô0çtî}çwîN‘-üÐç~ŽšÜÚ¦HPèHÐ%ñÿ\Ir°èŒN5|Ù�þ…`ŽGcNæåiæ…æikn[m>KoÞ¿ï%çt>çvŽçyI{.~þç½è1èÞ`è‡n!‰ÎEŒÞèóè‘N…“•.æeþ}gž†iÑ³Êæ§êæ&êÉEê¥~ê¨zÞÔ|Þêüè*èƒNëˆÏŠžëràèp é é—CeÁ úà^ì©xìѬsãg¡þÁ££¥nê61í]í%}í­®íÀíÜêí¶î¸.îäN–æŽîf£îÁÞîîÎ ðn’ ï`ý?îTïavï�´0ò$/îrpê§ìN]"¿£ÛŽ>Lè†ÿþíûî¹^ñ­eïëéæ_ž8ñ¼X/C¯3öÞì¾$ò$?ò&�ò‰¬òÂò¯îò°>1?ë†Îã·ž &�ó¼~îøëPø {øšøÚ°øj(=Ž�_ñ’o‡Æ>‘–mOoOÆïÕùŸ_òv/ú¤_ ¦oÑ÷Uoõó­¯õ…Þ%†ÿ¿èˆ_ñZ†û8XßõíûŸ½ïî¿ßG/2¥9üCQüqü8Ð%Ê?÷tú5!ÐÏŒ–#X�ÜÁT Ç,dÈÁáÇó$Ú£XÑ›7$‘,˜Ðc*9!r#YRÛIl)¬dÙÒåK˜1eΤYÓæMœ9oêãÙ³bETA… ÑaÉ’Ù”.]ÐÔ©N¨QL¥ºÂêU"Yµ~ãÚ•(ªmaÅJ$;¯ÚY´�Ô®ÐÖ­[q9¤W×î¼yÿìåÒ¯œ0�ÃÄ‹÷Îða´Í-w�œG† �FœøÓÞE�ç~Lèw$Rn'µ¥ÄÕôiÔ©UŸîéÓòׯ“As[ÊÔiÿÓÕ¹YR­zÕªÖ­]¹~;¶¬Y´gײ}û6.ÆvïæÅË·ï_À‚ F|V1cÇ�#�™LyžåË52æ RäQТIë¦_ß>TÞSíç�Àÿÿ|° Dk÷QpÁVtP ñ‘p¶Ú”º�¦üà�?߬ªçC3ËKlçDS<±sæE‰‘qFjj´1sìʱüàG ƒü1"‹äãH$ïQrÉ‹šôF8®zT°È"¥� ,±(.¬%—DA0Ç‘rSÊ4S4ÓÜrÒæ»ðM8sË/€ ÷û@,ÐÀ³ÀÓÁ#œ´ ³‰¦ ëÿ¤Ã@±9HPqÒvXlÀE_œ‘FkÌQG®x”RHR? ’H$“ìò'/‚ò›1OÍÁÊ,µÜrÕ{¾ SL)Í<3M4×lS¥C‹5ö¦9½Ó¿<õܳ›”Ð!ÔBB|(¬ðØÝxÓ°NFý0Òæ(UÑRL3ÝTÆN=ý4—³T!eMõH\[}ÊXO¥5Ë5qÕ5Ì1}-Ø`·¶4nvx¥dë\�b*¶øYhû”¶Gj[±[mks8Ñ:Ÿ1ùdrS–Ô\Ñ5,SM×m—šwá UÞQéÒÞ{ómõÕ~©üË€WØÏ^ FXa‡}øéc#Þpb‹/~ÿ6Z^9¦öãA‘*tdoq=e•#e¹å_†y]bf®9^ræÕùGê¶û^>|vh)eÚÖâ¶l׬4Ø”¥›njÆã”º¿e«®c¬ÿÜZÐl ݶá Åû™²Í>»Ò´ß�Ù¶Ý~n¹ç¶ûîžWÕ—ïý¾à[�|ׂ•FXq7¾¾Ç÷+±DÉ‹¡\ãÂìØZkC^ lªð|ìÐ!UL±I-µôt@Â?ù·ùÍÙõ× ðb}öõn’öm¯uÍö•õ±o}îs•ùjç¯ÛmKõËÕî–4_í/ ý+ÎÂøÃỔ€X0 8x5æY®�Ä7Ç­ÎQðsÄ`7轂0„€ ßê\裹}…*\¡ì~öÅ)Áp~3,c B¸Þå� ëáÿ€xG�0jˆE<âž*7­ËA¯‰Š 'Ø¥ RÑ-dÄ-•En‘‹#ôb Ϥ:dR“c$# ÷eÉ -†€ ï×<2éoŽLóßâðøÊ›è‘€|”œ¬°\ær9jqàµ9`SÃ$æœìEDNQ‘`$¤8ØAHJ2y“y¤N§ÉMÿ¦�Œ^0G7½©(Ç8R5û›`CÃ=¤S�ë`g;!•xÆS‡išŒìyOoz–ût‰,kE˪ْy¹Ôå.{9H|S˜Ä¦1‰wÈ%%r™ÍlÎ3!¹ iJŽšP²&̰™INª0ŸÝg8É1Îw•Óœa@§:ÓÙNw6'žò\e=ïiÏ‘šƒŸÃ+:|úSuU¨0e'áÐB:¨D‘`ª[fFD•SÌxÆ�Ó…ª[åêKÚ’… U¨&%ÛN ´¦•p3…çqæU¸*ÀnÁ$ì*m/ž'# (ü:UÀ²"ƒeCapXoÒ@±TáêOBP·Ä3ÿ9gùhìzY(ˆA³›kPÉ ©]6¢IÐ m^$†S±4ÄN×ÓŸú´³ê`$[ópT‰$µAKmj[ž*¸¶ªãÁê°´ÊÕ­z5?/ kgÙfV˜¥U­»²­[ãÕ¹³®w J^³W“õõ¯�,a ‹Øn®–±[u,9 ÛÉN¶²˜µëf9ëÜu�v—£--^Nû£Ôsµ­u-Ô`ÛÙÖ–­¸�‡n[ÁÛH8µ]P•*UcÕâ¶é¸ÈU.o˜;¬Ù>w]g•.,ÖÊVë^7»Ø.ð ½Â“¯ñ+(È[Þ– ‡u@b;•Æúô±¹Œ,<'[�ùÒ×¾šÿ q~›ZþBô�AíBT«Xøajg5 S½ê×µ¯&³�ÌŒæ0`xÍÆm³ÿ›;L•·©Ü"6ZóÏ=õÏÌæ.*¼+ð>C¼6&oµ�mms›Èð5ò¤±Yéq/œçVKº‡ðßX†÷¡æ�qä\çÚ«÷³Á|²Ðú†”�šdæ•\ÍùdsmÜÜ�ƒO…%K!ê:žó¶�Cë[—$cÀiA×XâÊV(‹)îâîÂØçaŸ¶`<¾côšcN�~t8 uäʱˆ¡e›¦sär˜Ëœæ5‡ÓÍu¾óæôÜç÷έ²4ôÝ’¨è5:ú¬�t�3�àµIú¸¿Ju¢^=.Yߺֻ>—¯“<ÐÑ´_Çn€²›=HÍN; ÙÎñZæí×îæÜÙÿ+d÷Žü-¡Í»Þ�Çw'_-¿i¥¬nO³Ôî5áßdøÃ‹ƒçŠ·m˜�%È?XòÍ1úE�¾ÒÌ{³éKéü’?¯”ª‹¤/ýé9’zoC[ãÒÅëcïçÚ[;Ö#4 ƒÝ‹;ßÛ6àë6· ¾�2¾ãÛ¥¾{²åÃÀ[·˜k·™{7ë»ì;¼íë¹îºÆ{<¢#?Ê3?Ëüñ +²ެh?ûz¿lˆ?Ñ£?®Û"¯C°@×Ã.²S(†&Ú³8µÃ8ýÛ8€;ÀD“»ü »àƒ4 \Æ€ÀA¾L›Bæóçë´O µ,ëÀÔ(5œË¾¬·Tµ¿|‹ÿòó†ó3§ÃqA“‚A"�ÁÍr=Ü郿лÁu)=ÓÓAÔãAÕ»=ÿ+»!”€"¼8FÈ8%,@&ô¦9)T>*œ +$,œøDP\‹-ìBèûBê C1< 2Ì>íK<Å{Ä#Áû>,¿™\ Ѓ)ùÃÁA ¡‡Ü¿Öë? „=EÂFçË[c“<ƒÛ–઒à�|ž´­wb«Ðš™ÓÄŒÜ"·ÒHò²*[­hÊzĉ{œ·|”‘}”Àä+ÇåÈ€ÈæŸ-:H �µXHÉiȇ,€ˆ¤ÈŠ<ˆ‹ DADÊÀâHWë­˜�I’�™DIEPI®`IjpIÒ‚É4‹Œ™¬É,ÃI’ÐI~àÉGðI™Ê]J˜!JI:Ê-º1¥<,¦tʧ´‰¨Œ­©$†ª\Ž ÄÄ<Ž€®| ¯ !°L±T ²¬³|È´TËt°HµÀH¸,¹Ü7ÿº´ËeÄK2(É“LÉy[I�´Á„ÂT:Ã4IļɭÊÉ�ìI¶úÉ™ ÊvÊ·4ÊãøÍ©ÚLèÌøLÐt3|<},Í޼ʶ-­¤ŽÖt‹×ŸØD‘Ùl„Ú´˜Û„HìÐÍÝdËøÜËÌLò N~kιK,ÉãÔËäìËåüK LÁŒNä¤I,³É•PLn`LDŽ̷°-ïìð¬¿-J:òdóDOõ¬‰Ðl¯²¢Jøl„ÓÄÊÔ,‹Õ¼Ï¶ÈÏði�e€±< †d«²EvŒÜíQ²XÍØËIžäÕªFV‹AÅ C{»oª“—ø±@!¾%Ê9(eSF¶!B!JÕ!²*Ó1ï að%cŸª:\Tc­«±¥I:8L9ž%:æX;†~ÜcÑëcùcƒ d\äV)äC6äD^䃸äFÈä!ˆäI–äJ*kÆæMþÆNÞ�Oö�PN¾E!S>åë"J]eVNW~e6XÄ8«ZZF[vV\>]F^>•8Þ¢9>\fá(æÉâãæðã"@ Af+ÿB¾®h–æñPd;`dÖ] HmÞænV‡oVÍ€ çCcƒqæ�rF€s~�tNŸu.eT& wžÒx–çñ çzÂ{NØ|ÞgŽíç–€¦¾•$Rù]„îŠÐ:�çdè·ph½ŸˆF…‰ž©ŠŽ«‹¦ƒiÞèjîhG–H.»mæfŲd±Æd“¦”Ö±•.S–å°ešUç™F6R¡TžÎéy~e{îµYnŠ2&ª[>‹5ö«]^)YIê-Zê`NFzj˜yNé¨ d&eöfgvhŽæ¯æhþýa²i³>ë‘.é�vëp†k’òd— ëm°ksÅëuؽžRž>ëÿ økc”Ÿc®åŽ‹Ã®†Ä…Å6§Æ¦Y¥’B=CF ìL±ìËÎìÍ6“Îþì& mDÚÃÒhÒ“þ=mêiJNko^ëknë¼xëŠkTÚ¶m ÅmSÖm!ákzömà.,áìÍ êãÆ�ä^îæŒç6WY�lƒ.›ÉÞ%¨Ì˦‡ÌžIºj¡xµxÚj¸Ê’ðž×ñÖhE&œ‚ëyXͼ&ßžZÂ1o¶ní¼¬·Ó1EA¸•˜üI Xþÿ~eßf#ï�áÎS·:äægÄÎeÅèŸ� ¾}ðþ¾ÛÈn‹ _Ž wÉ /"è*È-ú ‡'¶q+ÿÇhwWäÙHñª¬Ï`¢Ô©½9ÒMyNÿFks;Ðqû^–—ˆé×r%Ýí›êí³>rF_�$ŸÑ%�©¡~rŽr£žr†¨òSAôÎrfÊ ë†ì–01˜‘$2gªx:óãHs¯Îè6s‚(M9&:?X;G�¶ÌsÁÜó”îó6ô‰ô»NC?KN·'EßæF?òGWÏHg§‡ræ–ræM§’d÷€BÝòµèrçûr sAu¢(ó<`õ²põ¯ÖhY/Zoë9ŸÒ:Ÿ·;g=Ÿª/,?vAw —J§?v‡ÜöeŸäf7ògÿÌh_‡i¯ôj¿ôÿk§ršµr!Çò¯¢í õu»(u;;õ1?wU7óuAs,q†ðów�÷Öž÷›ª÷غ÷uÉwãé~—ºÿ÷–ø=x‚7øÿ^ô„GrÇçâÖgÃvrå¦ö/ÌL¯øM¿rßõtoW p'-q?rs tW÷ Ky5_ùX 8ßÇZŸ€[¯×\‡]Ÿ›ßw6Èù˜kžg Ÿúcz"'ú¢¿Š…Ê…©º%ÊRHü!’oÀ¦¾m²ªˆ|É狱ŠB»óÇ–k• Ž*l9ä2IG\ÔäÍ �Hºt‹“)ÒŠ«#8‚Mæé¿5ãWͲUVöÂ*ݧÈÿvºóµ8 ž­•ºIôšÉnò�»Ï bÔC+i~)àižžIã©©|†‰Â'ªÃÄÄ/…Åmzµ9�|É�|Ê÷,Ëg9ÑÒüÕç| ñ|S}lýÐ%ý„0ýKE}“Q}h9á`6 *jèpĈáP¤˜çb®Œó6êhà#H"–)™îdÄq*±lùî幘Рa©‰å£È‘ Ïð4gnÐ-jô(R¢R–2]èô)Ϩg|R5Gã*Ö¤Z·ríêõ+ذ[±‘-1bË–ÔÖÆl{®\›6"|ÊF^¬öòã÷ïˆÀ‚ÿVg˜¹pŠ'ÿV¤˜–¥·È’gBˆï2�̦LµëÜ8F¢µ¬fº-å!ªS±öÜ.R¤ÆŸÑîf{æ@‚ë>uøðì:Æ/æÉ˜k㼎€@†Ôɦd™“éR®|üòjš6qæ\ÕgP¡b“2mjªÔ©U­b½:þ=üøò¿–5 üq£µÔÜÆ„[JnMtd^èÅ×^ƒ(¸ `ƒvXb‹É6~’M†›@—á“›¹Úh¤±dZ5ÙA£Ú¬¥âlÒöŒmÝ`(PAtÙå[CÀ'qÆ!§sÜy@’I(A¤Ò8ø]—�\B¹SO?5Ô|îuzR­gŽ•TÎ÷%˜az…ÿ™eꈟ~ü½€&ôT�"¸ ƒ Ž@؆©ƒØbÂUT¡…ÞPffšq戣•všL3¡¨"‹±ÉöbŒ3êfco8êèç=jÄ‘GAv§tÒQ—¤u05Ú¤9=ÉÆwRåe|]Ò©`x@Ý:H—]Šù+°¿–iæ}�¥ÉŸbá&�y]eë­vÞùàž*6! ša¡ÚY¢¢-Zb£'®Öšg-NZÛm• T#oNá¨È¦*ùk@C/4»—½ÛÑNq¾4pœ: õF¤—n:꿳ŽÁ^Oýÿ*ÂS޽|ÃÌÆ¼ÜéŽwÖÅ~¼¶ Ï&ÆCÉäÄÜñåoÕ \ôA8êYêp×ûÖg´7.ïõ,R•+Ÿ¥Œö&õqÎsüæ!¿Ñ™Îõªq?& vP’�ÿh7§[Ýn€¹; ¿T²ø‡ËÇèæÀ»�'yL�+èI:àH°tÀ‚ßx'< OËUjF’>Å©xÂIH’'¡4ÕžhŒcå(}¨k:ƒÍ‰Šƒ½(~.zÑÅ È >C*‡¿€¡¤8iRª&ÊPF.mΫÈùsš#� �&Ns &j.ÀšëÀ¦6ÓÂMÛx³#àÌŒ>Ù SšÚt�_içßøùN€Ò³]1»g>ý²©~ß*¨@ÏAPÕ4\£QhFÚ‘‡B4¢ÿ}+FWŽÚÆ£ éHýRR0œ”)mÀJY —ê¦ã,'^ΙN�2¶±Ó¬&Æ"Ômš¦›1ùf·’ºÔÄÖ4�Nõ TSÆUª–¯žW½LH“ÊU¯Ž¬PäÏX‡PV„2­¹P+ ØêЈ¶®pÍè[éÚ »¯yÃ^ûú×À²”°†UÈf% Xt:¶ºÖE O}:Y¡V–¨—5jfµ ]ÄJ·³èülWB«§Ñγ´V%>R+^6¬Ö«®½$lÇ:Û‰fBüe„nQÁ[ß¾¸.qb\’š¥*å�`ûR!v¦œµéu3lÝìFöšÙ¤l5,{Ìn©ó�îÿtÕ9õ†½¨êåN߬Ža«Reí}ÕÛýò׿ü ð„à(ox£tM°¬×û5¥R‹°s)<^ —þ²N9ü6É~˜»!öîˆÁ[b:h–¼)F/WX¬øzX=®�ù‰cy†uÇeý¯�CdÙ9PE¶(‚?Z\¼2˜¯nÀ“å©U˜©‹Å2¤£©å³lw\"&q8OlfóªX>jv1@…ëfÔÒ8Îý´/@å©cý޹DzÁó„øüÖ!Gx®G4·f|Ü¿ôµ¯R+°� 5~¡˜Ó‘>v'Íå Z̘6q�§ìèó®Ø�RMµu©W�WÇúºµ.ò‘{] `ç¶ØÇnoÿ•›å1uùy%ööÑ¿'î5ŸûÍ¿›óð&¼ßy÷ôÞùœ¡£µè�]T/OÃïñ‰gÅâÏñ�_ä0£ ×ãPùËžÞdç|A<÷*{Vô¤¿¾W �íë)"åø¾%%Ó$ŸÔ‡NÉúÓß·´�G’Ùx?ü)-Žp¿HüªGQH§o�ýëè¿`¿G¡H à-¥l`$Àï96 sQ†²(KL B�^`æÉ”Lm Ù¥�~ ]8€Žà–è ` Š…öqŸaxøÅMFØß9�˜ßB¤ŸúY_X¸ü½ŸüÑmÈ rà>éÿ‡ÿIþÌ`ªÿƆA" l( á5 B˜`)Ë~ VàZ`jà p ½m¡†àŠà–´] ¶!W¬ 6tD|_9„_d`n”¿Ü fÀúíÅ{ð`þ ¶ÕßÞŸj䟴áÅþYCÿñ×ÿÅ„G�‚à-Ia¾ÕZ¡3< 1ˆ¦ANà‚¡Ø‰á®Gš!¦áê Æ¢QÀ¡®Ú¡7àá@è¡sð!þ!š… Æ—á3aG¡¡#"!$*!R¢`T£5b"2'v¢ï%žšá(@)BAj öZ(¶" ®Ê¢;-¶à¾ ðÄà!2ÿaÖà*Dú!,ÒÇõ c!á=a"á"J@#>"+iPëLb%†�5Zc8f£~l£šü+|ã†ã8–ã®R¤ãS¤¡²ã?¾cÆ£:¸`Â`.È Ú ?ö!0b@ $!¦š!æ""�"*•5¤3>äÖHä4RdEæÀEjbrâFþžGrá(†ä)Šá–”$+ž$J¾"‚°ä;º$Lâ¢. /¾Š/æ`X¶ßN"—)M{ãA&cB.ãB6"7ìeDìƒ_âLZ`œj4¥S^e)VžFv#ÔU¥‚d)Š$9måQt‰:¦dU´£X¶äöÅ¡<Ú"=Mâÿš¤¥]ôcNvÅ^¦&7 ã@z˜1"# (#3¦f_þ%ãf~a:æV^lq$G†b(ò&f¥9’ädZ‰ ¢¤²�i®äQ¨æ^²f6ô$iÑ%P†YlÞålò%Døå>fKæì¦aö¦×ý&p&žp‚ã|'½¡¢dE—,'J:'tÆ¢tz&u‚æuŠfZ2çíü£Ûx'7œÝ^í•xÎ%lÊf^îm®§mnÏ{æ&ŠÈgŽ£oŽÕ}âg~~ ´ØÒ�%û¨rêÍ®h�j& ¾ätš¥$2¨>Š„ƒš�•l‘i„z'…V(\åè‹dy"¤P*$Qˆ^ªç:°§{²|’¨ÒgyØgŠ²ÂŠ²¨�¸hzÀ( &'‚˜`�fQšÞ( è-Êdh棫©3 i‘鑪f’V(“þ$Îiè”2"‡Z)–ÞfˆºElq))f}¢h˜Šé˜¦A‹fI¬\æ?(�¶)(µ%œ~Å„„*©–ª©¦à¨žªª®*«^Yª¶*¬Æª¬"ѫΪ­Þ*®~I­æ*¯öª¯"Å®þª°ë¬+±+²–ª±&+³6ë;.«³F«´’´N«µ^k¤U+¶n+·6–¶v+¸†+!ù,3*~üÿ`ˆ®`¹ƒÇ5Z¸0—Co¡ID±ŽÅ ÙhdÇñŒÇ* ŠÄ¶®¤É“%©©\Ù­e·yó@ÉœI©f»›àr†Û¹ò�ÏR@ƒRBtHš45fXÊ”›Ó§„¢J=GµªUª ²jåÀ5)ǯììˆ;¦¬Ù¤^Á²sÀ¶­Ç·g˜2]A7€]xóÚÝ ¯ß¿€ L¸°áÈ+^ìWdAt(×)dØÈa.ˆÞ$B£ÈbŒÒ²{ ²ÊÈ�‘#¯déæLš6qêä©Ò绫ç†=ŠV-;ÀƒkN7n­[»nT;–¬Ù²h—ƒmën\¹è®ØË¸»÷ïàËÿïî¸`äÉ -cÖÌÙ3hѤCžN�rµJ—/c¾U“ÒÍv9�³S8=ù„›nDñ&ÚWÁ GÜpÆ]…\V\q° G͉õtÑùF[Ö]'—vÜ�gâ‰(¦¨by�¡„^CE4QEe$]|¦ÍGŸIöQƒŸkûõ÷_€xÛU…Ô…¿5HÃÃ!å”ÇMX!“Ú±áѱáá‡!b—]]w©hæ™h¦ù‹çQVYŒ™ÍØY�¡Ýø‘|#íÈ£}?ê÷š�² H5¶HQJö¦–“OB9å”D*é„ \)ÝWY¢é¦]~I]˜Ø‘X¦š¤–j*clºè¦z2nFãg6zÿÙÑ�9æ©ç:=ö¹±8�µˆä¡»-y)GŒB©Í£RJ:©•ÊÉ V¦›jÚ©Z:êˆdöuê·à†›Wª'½øæe­¶G'|´î¨Î»Ä+ïJ˜é*øê« À*¬UI*xl“ *ËìÎFJéµk±5ÖW«)Äÿài[Âׯ%ŠëñÇg’k’¹¬ÆéꜰÖ)-ŽîÂ+o¼ôBd/(øb¡/‘ƒ:,¢KË “3›°Gm¬hm=±Ä7MqÆsÌ1ÈTW=žÈ%‘ '{¯¾g祵¬ÎË0«Tok~Ö|ó¯FÊóѾ%ë¨Ð ݳtI‹õ4ÓN7ÿ µÄRolõà„+†µd«n-§{±~Å2}ïŽMvÌÞ̬v¯8÷«3ÀÄ&÷¢@ÏýèÐv�·Ãz/]mß~ÿ½ià|.ûì�®5º&«›2»`ƒ$6ÙPny¾˜³쑜¿­(Xr?x0év3œ·{¯Îzõ®ÃÞ1íÜn{â¸s�²×+· ¹Ë/ �öL—ûh‘Ç»]ìò?,:¤uGß!GÓc?ñõªËžö¼Õ½n|Ìc"‡ƒšà�¬†'ˆ(¢dâ‚t‡7qxðƒÒ¡ñÓ’ª¥Bƒ W˜ƒº70‰á܃ÊPnrÄ›à¬eÉIÑ%šs�ïj§/×ÉNw¾s˜“œ'eꉟeÒ�úܧ(ýùO6Ôšs,(+êC†6t`�(-56ÑŠúÔ€ªP#¹q‚U§G?šEbh@Ç$©K‚‚Ï“¦T üd©VûùÒ8^3,ÚÔ`lºP‡²Ã›û©Z)Ô¡UFR“ºÔ¥:õ©áˆj#5IU äSŸ[ÚêV»šÊ¯Rkc%+Ç|ƒV‰­õ±@mkÞ ×£>0©¨«GïúT½Z‘¯}ý«3+X–v † «¦kÓŪ¥±Õ‚¬li'ÙÉÿ¾5®så¨fw‹¼æ•ž{%a_;iÕ”’¶´ýŒ€r—+Ð1¬Í«`È*ŽiG;®“îl·kµÚR·—¥+oëê[ÏN°”Ã-#J�»!äús¹Ì…)Ç¢]ÀP׺×]AvWËÝþ‚Ì»·µ¬ 0;^òâÕ¼Do_Õ{Õã"¾ÊmîsËZ†â÷ºûE¬7ü±lx8 1øûßñ¸ÀÓ­îj³ûÚ4ÌvJ‰��yg×ÞiշĹÇï\ÿà8Á{}pªûÝ ßvÃþ7ˆã{â(ÿ'\ÅG}qg\ãéæ8'«šp�ë“á®&9ÔL¾ì”ûœ{=>4晢=ØCëÒ –Îto:íçP¿rЙ5tfýêu@z”Îô¥;½iQû†§þ¨ª? ëGeÒ£Óu¯Ëòéb�ûlÉ>%³O íEv—¸Þõ¯WLî€,Ý¥dw)áÝ3zß;ZÚ~¿Ï4ð�§èà�Pø#Þ"‰W¼F˜þÇÛ1ò §¨�XùËg”|g|çßöл>—£G`fO{¢_>óIa<ç=âÍl…ÈÞÔ}½ð©ûоöV¿=êÙ®û¾ËÒ÷Ö>Y‡O}qÿø³ïq�•¥,Üo¾ùà‡>ÿ\¤oÓê›ÿT×Ǿö=Ì}(%4¡©ÛÅÿò3ôüøWSú�¿þl´ÿAïçCñ'LGa • h}±wˆ Å'&!â!âMbâ4S³€ÈDhhˆ¸�$(H!(#X‚.X@3�jQ�²4@�ô‚8(;6˜1!5”ƒ@¨ƒăÖáƒÚ„Hh5;(1Ôe„°“„Pø1KX-M8?…Xø-S¸)UX-6˜…`X*[¨)]HO†hx&c8e(QG˜†pˆ"k؆<õ†qx‡x˜‡z¸‡|؇~ø‡€ˆ‚8ˆ„Xˆ†xˆˆ˜ˆŠ¸ˆŒØˆŽÿøˆ�‰’8‰”X‰–x‰˜˜‰š¸‰œØ‰žø‰ Š¢8ФXЦxЍ˜Šª¸Š¬ØŠ®øŠ°‹²8‹´X‹¶x‹¸˜‹º¸‹9X|¼…¾ø‹rŒ~Q[‡tkÛ�ŒÊX|'ŒäFŒyaŒP„ŒÊ˜ŒÌxrÎØlЈÒ¨@ÔX�רsÙÈlÛÝø߸Œ±×ŒãXkåxŽ‘ŽÉMìØŽŸöŽ’uŒ[V�ó(Jõh�ˆVŽ‘¡�?y�Д-â�XV|”5�P 9‘‰�¢¤�üÅ�pæ�o‘ 4‘Y‘!��²�©cITçWF’)’#y‘%™‘'ye”õ�.ÿÂ’ãà’Ñ“$I&Y“þu“™“,É“>)“@I“BùSÅ×DIT–$˜$ WœQ,i GrDDsˆQ|娔è{P•ï2•Uy•T‘•ž³•\É^ 1`yb{dé1O¹~h™––´–醕R4q)—Cô• –wéDyÉ€£w–h L€9m‚Ù9„—sùui‹É˜� .{©}}©’‰Il™ƒy…™™›Y�‰@Ÿ šfÉ—}Yš`tšn©$pÉ•¬™˜vùš±ù-Nb‘AY=L¸ApœÁ¥#Gm‘™Œñš À�Ûœh2œ ¶’,yœ�„õœÑœ8ÿôœ‡ùy…{‡D�Ôi�&‚�é �qÅ�Vä�}ž€ ž<@žðx‰Q|驞ÕÈžM„@Äi”ñiÈimTeŸø©Ÿü‰”õŸšŒý' ÑI Ùi F%ŸDŸ ž ÊÐù�•:¡ýׂî ŸŠ Ý© B¢vãœ"Zžå%J”'  )*8+:ºÆÉ'$¤šAMK¶jΔ‚o‘_+з’”O-×[Å(ÿ( CZ¤«¡IH*Jº¤Lr`"P*¥SŠŒÐ¦nj¥-·UWµ¥ìÙ¥o•+G¦cº¤ðæ8Ö‘¦ë·¦lê¦m §'§)E§Öi§Dÿ…§ø¦Ð°§LÚLNꀪ}SºT„Ú¦=r¥ˆªOŠœŒ9Žê�JM]Ò§³P*¨'¡©›Ú#¥ô©ÎäMAš£ú.¥Ú§êF©j¦~ʪùåª&«„*«lD«Íd«+úÅy§FŠ�„ªÑ¡ª£ñ§Ãz+Àc¬nЬ2¤¬ZàM­ù™ÎŠÇZTõHÇÆ2Юî*&ØSê[ÛêQ›ÊÞCà*®¾œåzç*\}¥®°†îú®Ø¯óŠWõêN÷š¯0±¯²4®�ù¯&°ø1\û]r°í ¯Ø·°OÕ°íô°ö1«ZuUü*j±%�±S5°´®+ ÿ{|"; $Û@&»¥ôH*;±ý›.»0Û;³›5{³´—³;±³8г+ñ³´|D±BÙc‘söApÃuu¯”-†P¶f¯O±#�–Q2˜qp·qµN"„&ECW•-ÊÖ˜\û.^»`ÛWb›Gdk¶e‹¶N¡¶k[m 'o·p;·êT·q·5“·²·yÙ·ê𷔃aktcû!†{¸Ø—¶ô±¸ŒÛ¸¹‘kTtBv{O~åF˜KšK–œë¹f“n¡[t¯t0¥kˆË ;Ҹȋ;� ¹’;”ë –‹/·Û¹Û”»ë"_뻂+ºy$¼¥[¼Çÿ›¼mÛº®Û¼Ï½X0½lQ½[ëa]‹½€«½T5¸@但 ¾ô!¾ã›n®{æ+»•K»Ä…·)¥·;Å·îë·%‘Ù;mßðÀüÿ¼Ì2¼ ‹¾…¼¸�ÜÁäðÁ ü¿VÀç@s+Ô¤üÃLªöx½ëÀÀñëÀüÀ|5pÃ8,t¢ÔýܸÜÁ Â! »“ ÀÐ+À5s”šÂ°ÂØØ¾Ùð¾/|ãÐÀ˜1Ã4\Ã8œÃT·ÃŒW|B<ÄDL"<»%\»XÀÄZðmÅâ(ÅT ß Zü 5Ü]|Ã:œFa,ÆLÆ@lÆgœÆjÿlÄ΋Äw Çr¬ÂKÁÂíèÂx¬KµÇ}üÇ5È.4ÈcüTelgŒмÆ$lÂ*„ óÄ“Å5iÉVl™¬Å›üÇžÜB \È¢|ȤœÈiŒÊIÜÆ ÉNLÇAÉ�jz¾åK{¼T“‰R!¨PÍÖ,ØœÍ#ØQJ”bYô$ÍÁ v“-n�ÎêŒÀ˜ÊËâÌZ ͦ™nÓÖ|ÍÙŒÍÛœÇÞàÍÎ$Î#FÎÞ`ÎFƒÎêœÎìÜc¡ü΋ôÌEÐõL÷\Íù¬ÏðÀÍáÏÈÐ$Ðð@Ð]4�Ð ía ½¾tLò|›ô\Ï� -ûÿܻӯÑZáÑ™Ò"M£ý! ­Ð›¨î¬Ò‹ÄÒ=ÏÓ6Ñ1=Ó5M ‡ÓY¡Ó<­Ô˜1ÒGQÒë<Ôí|DeÔT„ÔîDÐV4dÑýÔQÍFß\á|ãŒIñË9ÈÑ3 òB­»DíÕoµÒnÒÒÏËÆUAMN�Ñü,Õ @Õp=b!Ô#U‚]‚¦n¦‘SúÕáà×”ØH,Øf]3h�Ïj�nˆ­Øí×`4ׂY×Gsב×M µ™}Ô�Ô.½Ô0]Ñ…­ÑýÌÖÿìÖ½Ø!mÕåìÓ$ ÔA}’ÄZÍLÛ”±qyФL]ѾõÔ‘­¥cÚ¨ØÅ½œ¥ÿ£Õ°=ný÷Oá€(GÞ‰{+{\^DÝ�¦Ó}ÏÕmØ*qÝY‘ÝÀýÑÂÝÓÞ}ÎÈmÒú6ÞèmÞ‡ÞÆ«ÞZÌÞCæÞ¦ ß¹-ßxeÝ2!øýÖ§=ÐÄ]ÐÆ�Õÿ½Õošœ9ªŒÁ÷*ꘋé€bÔ¹£�‹”åKaÝê“g1 8žã”2È}œÇjÓU‘ãÔºw�¶ÇÀCpâCJ¾ä¢1ÁqâÛU|ÏJT#žŒ%îP.›�©âÓ¸�üèâ"Å2A Qãh#C9®ãÂã5ìãÝ äT!侪xE®ÅGžnI¾äJÞäbñä@ºaRãoUåÛpåzñçÿ#�\î�^^�`n®n2æTæ6­I¥”æ8¾ãaÜãàðãPMÂrNCšWç3|çÓ–çzÎçvàç±Ãa�Î×TÎ�Ðc4€‘åÂùš‹ŽŽ�®Œ�°‘.é”þéwæ1¤^šÎÜîélê53êŒfädƒär¢ç{.N¶Y¯n”E�³^4!’í¦¢è§±â Öâ´©’�N’nÁNmÄÆ>!ÉþæÂä8>ä]ÒhŠlêë1íÔ®ê¬nKܵí%Ñí²ž?F—¸^î]þcè.šEéëìì4^éGÆFóŽõn "o ²¡ì Žã‡EþžÆ^/Ò~2ÈÿQíÒrí4 îkåD¨ ë‘Lß~ßê #�©ëÏ�0 Oa¾íþî2Ó9^J¯!?ò%�ïËŽòUµò{§È/OÏ+> cí}ÓSQŽ@;o¾åó îÖ�ó¤‚ð©qH:9 �÷zŸô‘¤ ~ÿ÷ÇÔô/ì.‘ãdÊ ê势øU/òWÏ©p~9žò\ß%^ÿAñör2ód@ðØþð¯öéÍÌxåöÎR:AoðáB÷E_w¯÷{/’ðô÷€ÿëcîôgød𸋝øõ~ï�Ÿïq¾ïs®ylðïd£ù'Cí�Oö«þùBï_:?úl_ú�ôói�úh.‡ÿ4¥wÿú°ß|ŸE´ï÷�¯ñ5®ûKÊû½ÿûmÞéXò°Àü/£üœÁüžó $XÐàA„ .T˜ÍáùM\WÑb8Œ«mähÀãÇ4!Ež!Y2ÃI” U®LˆÎåK‹1eŽ£YÓ&Í9u†àÙ3ÓO š„mTÔ¨4¤IM,5Q”ÚSoQ»M…U•ÕU¬´nõÐÕk°aÛ�% #´ŒžR‹êíÜÛª°°Ì¥ËÆî]¼vÉíåKÀïߤm¡ T˜ÌaÄwÙ-¶Ó˜Æã‘%³¤\Ù2å‡%R”™Q#Ç�AŠ YÒ$Ê“—U·|éRæëu7e�Ó¹³'ÿO A‡ 5z4)R¦M­m;µ[\¬Y·jõú5,X²eϦ%õí¹¸tëæåηï_¿�£†VâÄv³klç1 É“WÏ_Ñþƒôïoírân¶p@u 4Ð@ÌcAŽ®»ncB OË`…ø ï ýöÃæCa“É»½z+jSü ©¶Ú*æÅ:b4 i4θhrÔñ¿YpEi| B"‡ÐâH$×SrI1š´¨(ÄÁ¨…Œ±º�LrIº^Ë(8§Øj«ª"Ã0Ó+Ò,ÉspS€ ãL辈òë°ƒþÐp¢ <ð@)Ì£J‰”� -Äÿ0>9 º³CÑ¢g*µÔÄFRTqÅ£z±˜+g¬1‡§ÒqÇ\QÈsŠ„PË#—”•�&Åx2ʩ܈Õ+³„UÖ.;ÃÌáÄŒŠL"Í M5IbóM8•V :ñ+èÑ<÷ °ÏmþTAwÒÐÃM”$”•OÚG#ýpRJ-­SMQ²So> uTRK=5Ç}ÌHV]5ò×Y•¬õÖr¤Ôµ^côUK`çòrX¦ÂlY•e–‡5Û|sÚi«µ³Ãl÷ä¶[o 4\ˆÇ�°\sÍ�ävÝ…·"yç5±ÞîíT_ù½�§£ XÕß vV-VØÉŠ lÿ8×¢½®×¹ ®‹‹Ã!ª1a)óÌ®ÒÙY‘Ý$YZ“ z-eM±ûîèÆBÜAÅ-tf2ÌÃfF§}tçu€ìùzëºE¢ëµÆ£C�çrÌ—xU™‹ôZêÅ®×)³ö{k‰»FXÉ`cú2ãb76;Y´=P;dhßn4n‚æîOÛ»ñÎ{oÕzHÀ'|ÝFßYñž×ôqa,zÔÊ1Ï<ÕÍ›îœÈÏA}«6=f¹Æ"üõZ¿ã¥4.ûìeÓnöŒgGÖ=Îj½õ½µxP€Á³[ÞÚ!%)�Æoæ!Wà&´žåEgú�‰L¬f5èÉKz›’Æ;<(ÿ˜Á\i_Ø;šö.§9ñ¸å-¥`!‘jµ%%¡d3¤ákʇµF ;aŒ 0…íuñ‹ÝühW?ÛÝ/nÛ߆ú÷§×ÈF€$ ˜ ¢��É{àb"¨!ÃQÐ5¼`92x©Ÿ9)|¡ÑCÉ­„&D!‹¬³ÂBè…±Z’ i8C’îa×Ù!(àøC ~Â!Û±f×±ÚÝŽm¹k"}žx (ÞdŠ$ )¬xÅ,^g‹C8Ô ˆ®“¨K‚aÄÓcRF3®hq´×?8žöpr4ʹ—Âë°°.l ×ãÇ?òj¥Ë¡ß yHXñŠìé Žÿ Ácö[þÚ­J®¦ePœ‰&7ÙÉO"0”oe)Oy†tÝŒ•|eÏè³Þ¤%-Ia£á¸ËôR{u”F[‚™Ç!ì1j}<ÉIÆeò-Ïì!"Fͱ ›�Ôf$•øÍp*[ý'&Ëi“MÆ�y»"ÖyŽvÒÌ”^Då…2Ä;–dÆ!üq%Ã0(ËžÉFŸháç-½AžÊñ6&”A ŠÇa걘|ŒaCªLó5}!*¼úUibÔšÍæ6“ØÍ%‚3¤'ãikJj L¢ôœUd)((ÊÂ4�BïŒg|pº�f£­Êüéo'Ô¡µ�¸|£.•Ú¦:õÿŽç&1Å`ÌÅ ³†ͪyØÃ¯‚5‘ÂòLFeG¿�áNk lž^óV—]Ñ(–Š‹y>³ PP›ãˆ0ð[0—_90 IòD·ÿhC¹Ëu6ªåZˆZí¥×™Gu­kµŒ´”¶qá.,–£ÁAírž*#¶ë]­|¤VµA{QÂ&øšc IG:<ƒƒà˜HÒ ­W™J"r,n-kR- |à­|ä9`iïà»U®U ­íÏkÿ”_ §çµ­Gp Ý )½eáo\0 ·¸g8îïö´\æºë¹–É€Ÿ2Ý·PBÇ;Æ.Fv» ólÁ/¬Æ;D¦œ7ÁÿrƒQ-&€¾öÍn†ƒÃßþ2uq¶q�là% Éí}p„%LáÖXø@V&Ö†+UÛÂÜö'¹}™ªH\ £XÅÅmqk´cå6wÆi®±�q|ŽóJùq‚ìª!YKG^äR”œ^&/ØÉ'�28§|_6/Ë¡Õò–åecjxùËa³ƒÙá±V§Ð� ¦BMD7?΀�s&èÌ7ÞnÄ·À.¿VÜç—üЂ¦Sž<ƒTgÑ<æI´Ž{ŽF?ºH‘6—xåQÚü^š Ö´{9 åù:¤¾ õ¨¿ZjSW ÕªF0¦Å\nW›ÖÌ 'š_ÒR[ßz¶o®Jÿ‡ ðáÛYØ%&vŠù%Md»¤§¸²”Åìû8ûÙÑVà´ SmJ\;Ûç(„¸�(oƒ;8â&÷s6��N§;ë®r»�Ø_T`*Þ–š÷о f{·ºÌ±©¿]pÝZÃ޳‡ç â:»Ã>q±GñˆS¼âÆí£qÏp4ÈEþcméäJ9’-MrVãûÉèž°º©ŒüÚ<`8×ùΟÑóßü¼qw9™_mfYg&OHï�Ò®ë‚7ýàOO¸Ô©®ç‡1âèÐúĹÞu7»?χØ9Bv�“~ä�/ùNÞž¶WÚ,ÏtáG0wJJÙîìf³4ËÿÛ÷�£Zð‚'|X3<}C¼¢›µþh¾¢x¾\Ûµ^ûµâ1i¸³<³ºá¾»¢ï ?®?—(?Cë8�K½g[½¸h¿çx¿Æˆ¿ùÃ0Ú»7ÛýÕÚ?¼»5ÿ*à‹·$Àz·Ú3>Ü·UZ+jrÀF€Àè›Àê«@…›:†«:00 ij)ïë<´¸<�%0?C1D¿DS¿ÝJ;“s¿ �?‡ŠÁÿp³?!¤A"¼½ü»ÁÝã?+ÛA}êÁJ&aúÁ/313À8¾Ã#:’©/EL‡$”­¤8è#9ƒC¸¨»>)Ì>*´B ÂBÔÂ-4“.,£/\ 1ÃL¿\?ÖcÁ°pA;€Áos»ÙƒÃ–›CŒ2 ‡¼ë¿zù¿ÞX?d!@<0Aü­0ãCL@Dœ–E¬¯FD € µÇ“Àé£ÀݲÄË .M ND üÄ0Å ŧ(Å0$Ã3CAAC×SÃ1`Ã?rÃúc=B|¹˜«»™»;]ÔÁ^äAì™`,…a4°bT€cÌ‹d4B0R�jiFF”‰–6ê§NYzºÿåøªŒšÅ¡�üHòE£ Ë‘i;~é$Xj´,ZAIŽ«hŽ®.x¨Ix¨—<@5a¢‹#èɰ€”¡tÈÈ/TsÉ!øˆXJ < ¡ƒ°�6˜ÊÚȉ\¸J¬ÌJ­Äʉô ë².²Ó޹²ïâ€õjå).øJ¾ùhÈf|�ˆ\‘®\¬±HŸ+ÀïÒHŒàÈžùH�Ì‘<‘z)Éh8É”$ •ü±–ä˜d™ôš´IœÔIâIŸ‹¦Ì€§$J£´1¤TJ¦„• ʨŒˆ©lƒªl€­\M­œË¯¬®°K²ü®³ƒ´4�µÕ‚Vâ¶ÝØ·Ôvº-FV‹Ç¬b½•àâ¢à-–“æò ÛJë¢:Ï4ªí]8ê$u\%œËî‚C±–Â\ŽÐE±¯²IP#iÐ\Åà¯x9RD<Ô0¤$’á ”(КÈ(j80Lü­0PÝö `ƒx�÷h°ƒôgÄX» áŽG�/sHÛ´m�öðfȰVPvQÎ/R®.Sþ-TFSUþWVî!WVcM‰å®œåZ®[^ŠÌÕe„âe¯òe`æRÐŽÿb•c6· HfšÛÇ6kfyæ�ˆæ%%\š fk.Æl~$ÙfGNpn/q&çq6ç1@ç#�/v¶Xwv xNÒùå ³g­,å)<åžLesYå¸me"á�vÄÞ�åî:h0Hèx æÙåàêåšüåéÉåa®è¹h:ÌèRæìèlúh~�æ“�æ’«j6°kV€”–S–ÆX†xéˆi™.gw¤›ÆMuÎi Øi÷èiyŽ ^3¡ÎJ¢®kØç ègXí]¨ hÈ­‚žHƒÖŽª¾"\Æj†Žª!phT€è¯&í°6æ®@æ³Þè]Ä5��N‘žÔ˜�k"Z‹ÿ“Ä»ÆÌ#ÉëŒU¾öë¿&šì…TÉè4–õéÕhl塯ç¢Öç£æç¤ö縅ÁqêÁ0L‘jîжê…Öj0àjxðj’hŠvm€í=@kކ�F¨íÛÎmûøb“¦k”ÖæÆàæ…`Yäþëå΋tŽ/–…îènÙyŽ”zŽ{ž‡|žìí®ìî¾ìðèñίò.è©NoÑVh°nè­~讎謞hºk!kdÂïÙfæµ¶í¶é·éi–ëß6±àfÑá.ð–F‡•äì4æ¦VçŽ �î·¡î±î¬ È‚¤ZËNSÌqsÁOEò6‘ÿ¹,Hô¦ 0ÀW)!ÌÒ&ÔVíøŽñù¶èׯh�^ÄÇ”Ïôˆ! Ï€ÿÞíqðZ¨ë"_鯀¯âNˆ%×’&?ŒÇ‹«ò熲O¾rzj ×J./F/7Ô8‰+ï1§4xÕo£Hób\ó¹hó_ƒsövoø®%Ö–ñ¹ ñ°q«ºo&%qùóÉtÜþñp!pà&p;pt¶…ô !à�Åœ(?L§rM·`’ÁruÐr¬ uAuD)õ 8u1G2�P ö¨îJ5?h7OZgñövñ÷†q†¾ó±Îó²Þó †w£ ö@ôÜVöÞ~Š!Çfg‡öVòÿi_Ûj·vlgðâÚöÐø&wq¿Jr71ª]1tWw-œv‡UǵV—÷W§÷YÿÒ8‡�9ñÕ–ï§oû¦T‚/ ƒ§cOxCGtEx6yt‰�j/.kgÃVgs `�çøý9P)Aµ×Äð`²‘/®’ß[TgwU/U¦˜Ë�o8«÷7‰6íšß÷›·óœÇóúÖóØæóžßï<-v„Gv…g$†gv"7ú¨�ö¤—Œ¥7�¦zu–ún�ª×«O¬Í€äú%ùR7y$Aù±÷à0û`œ÷ZVû{wûOm›¯ó~Ÿû¯û€¿û�o³‚ßûƒ' ¡'éC_öÿDp•>òg?zÃ?–Mü’Xüœ†zLJ–|鮌æÊ“ï €ÊÿÊ7½$áÃvî— tGlt—�o¨LÙÊYnL-ù ­Iú{ØFË�£„è�a´”µÈú²¤Z/Øþˆuâ(hЄԾkHè!Ä0'V©h‘ÆŒ�6rÌå±HX"ý�dÅ* Ê4lV²ky楛˜ƒÐ¬ió&Í:wþèé3Рæ†¥aôè ¤JwîÄéô)Ô¨R`«jÖ¬ p]è•Ú¼°bK‘Åb¶Z-jW²e#á-ܘnšÞ´c÷nР~à×/ÇŽ‹, Ë$bVjÕÿfÊäî1äp zõfY, Ì”(µëÜ8F¢å)íU¬XªWOhíÚ ìØ{<8ل׆ï Fœ(qñâŒ7 ²[a’~L¦TÉÒ%L™S§Ûdª“hÑ£F•.µNý;x§V¯fźµëW°¨ç‘-e Ú:‹Û®„7&]›wñæÍ0{]_ @\qƒyd˜H‰™\c�Ev[e—…• ›yöYh£•–Çië­Æšk­Å&Ûlµtn 9Ä!¾ýœÂaD q!�TÒI)±Õ;/�!×LáIe]Ø ¥ÝvÜ B¤�M~7^Uÿ�G@zê¡ÖÞ{ñÍGŸ}oÉ•_MDB‰ÿÍþEàqÇ!x˜‚ :æ ;’M¡7˜iÆ™g �Fši ­7χª…Øœîüg"(æ¶"o.†cŒ2Òø‘�°(ÇœŽÏõ�A:é‘¡z÷)©NŽ)%F\`«u®‡åYi©Å#�]Jð¥N8‰ e™H\𕦠b‹5§œ -Ī�âÙ™žöiej�:A¡‡š¨¨Š»±è(¤2’3i.jÞ¸\Ž(íÝ�Ò•z“¨ñð.½Oò:Û”­JxeY±Ê7+­ìØŠë¼ðZwêlfl°këf¡ÉR¶ì¾Z˜g†¢mØ!j�rpm¶%n a·,¶èb¸’W#rçbªÿ®¦>Yo˜ò†J3ÎPYõß@ªªª¯«ìõû�,ð[>1i0Sï¥ð¯�T3u°-Ãòb�jq¬ƒ§H ³Þya´oXÚŸ_ØYÄá¸í6¢ÜR£Ûq½ù–²ph6ìrºÎ±Á£ÌîÒlóÍ9nÓÎ<¯ã3W@�5ô{F —Ò£Vwð½OûÊÑÔÕT]Ö BÊõƒsR´ÅÏb¸çÙh{èÚí´ýv8q“ü!4‚(D^ªoÄ Üñˆ@0)�f œ�£AÈ™e‚µJZöˆAîi0aß“š�7¾ŠÎ|$,�²ÀV±±aŒu-< c8?dÑ.@“ó¸¨üáð!;ä!Œ~D!‘ˆ„‹gÀÁ-1WM\`”ÅVI�zÕÎõ°hA-`W]ÔÁFs� "4cÄL¸Fg©Ð�o,M_(C:ÒîÿŽyÄãõ÷GöP�G d!?XÄáÅŒSžªW#ùÈz- ™ ÈÊÊ!M¯„$ç¸f{ˆE68 ›Þ¼Ë ÂÉDðd£œÐˆ4˱1]óšçòÃ{RƒyÒS öL>Õ¡Ïqð³Ji•Hþš�‚£Ž^3?:ŽB±°sÕLÓŸ€ÖÎv* ¢] [ Ÿøô¡£µèEUÃzÒÓGHç2SÊLgžs/é¤fÛ™MmӛߴK8W€Rê”3-Mç:q7ÑwÆ%$�§=¥€ÏtèS eá?YÐ4E�n‰Ç†:ÔsÁЍ¾&zM�V£+ÑèFëàÑ�’Õ¬lÿ8*LÊ©�ª´®Nræ3±Íi.ä¡2%‹6écÓn‚SœÊRO*Í 6d¨$IQÓפ.µ©Om]T-3UVµ uÄ*q´* ®:´j`m•XÏAV¸­]kGWëV¸ÊÕxtµ+n¿ƒ×–ä¥}�)6KSÁ¶°:=lx«Wt.vZ�m'QÍ"Ï£R6Ÿûä'TsPXüÑÞýîUo“U­’ö¡Çù“/��ZÙŠô¬0J«ZaË^Œô¨µ%Xnó{W–.×¥|¥†_ƒ[ŠÀ¶e°0îm¥¢\tô¶¹b't O镺÷´®S±‹YíJ•»;ü.x?+ÞÐ’·u]õ*ÿDדÞõ¶µ½‰ä|aÛ‡kÍÖ¾rů~s¬[þ2x6¾0pÏ1ÓÄÔ´¸85lÁš´à«Ó¹ïp¬r&Œ…é’´ºL½î8²»Ýî‚Øá�ÌxoYÞQ‚½¾d1HÝz´ÖÆ.¦í�ñƒ\ÓÙ)y-“«Tµö yKl8 ½”œæô]Kfn“,ÔG¹9æ�7­lY Ÿ-³ÞØìºìeƒ™Ä·Úžù<=¢¥7½«ÝæšÓ*ãkÙ¦'åd�cM“;+¶z–¨\F¶ú‚ ¡Ãihsö¨N†²r-ÙyFúÂWÎp–7¼åwùË sA�kQ[²Ô¾¸Ãÿ�ꀱy­¬&®«ç kY×™ÖÅþ¯WBÍçSò:ÐÝt°‡íÓw'zQÈ&‰²éÙl¥bø²•æ°f=¬CM[!ØÆ£¶Ó”ën{û‡á7}RýÚ6ªÕÞ|5SØ-òY—‡ß·–¸¨é½’^ÿ:Á^�¾kÍØ'3:ÙŽx7%�e-w˜Ë .ЃÚÀˆ6âÇ™8õ*nñ‹‹aÜ´’‹\VÝqt\Ý!9»ÝÝãuü8ÞÛž÷®Wnoà›Ð1ç÷Ìÿ퇀3;çΞt´>í…w9èAoÞóþpi$H'µÒ�Àô¦g<`P�‰!¯øsx° O0Öíªõ<§GÞ}^‹Ø}}oÿ`ç»T‡æºƒý]s€ß¼íÐ9´yžpŸ×î@Ï»Þ=�m}YžŠX¼à™îtÞ Š_üÔŸnÛ®;ò¸-'7¸±¸çñ†Ýbf@ nL¶¤å>y9^›9¦mp¿û=íiòïüÙŒƒ8[fâã�õ.{xÿ^kC§v‚¢þ;œHò¯W­j©Ý%�%� àîµÄ~Ø…‘˜CMø„�˜­4à_~!ßø óá‘óA HŸP;X_OàDö-Àöu÷}Šß”_`œ Qˆú±Ÿ¦¸üùX9ÈßéПýéþé_þñ_ÿ¥ÉÿàmÓ.á$ÿ ;, (F MÙJZ �aàòaYóåHx Š þ€ f_ ª fƒø%ß š_¡ Ô ´ß[¼ßÄŸAÌß5Õ(ÜŸDáÂV¡X!aÒ B¡öVa—\!æ˜ÄJCQôYÔô-�ŒaâÕz ®a vŠÁ¡Ò¡Ø!„žúabÈXì"/€/þ¢Çâ)a"à".`#þÀ#z“’,IñMbnU¢r!záóiârbzbõm^øD(:Ó¨à –â¶a ¾á ¦Z¬ßÞ`æ ñ yƒöÿ!þ! ê"/îâ/c £c16aáÑ #ZNå0E36£$Bc4ªá)^b&BÃ&VT'Ìz#8ÞÄ Ž#9¦¡)¢£*ž×:Æa;Ú`"áàê =²Ê=Ú".òc?þ£/£@d1ã~$#‘4¤’<$DÚ•4®EZ#j£rd ÞDÉmÝ@�ã6ؤhIŠÒ*žd+Âã+Êcƒ½¤eÄä.Í$lõ£?Ú$NþÑzœ7OÞEþ$PvÇÕ ¥ŽåQòÑ5Zd6bä6j$(:eÉ�¤ R¥¦J*b¥IRJÖ�;º",ºdöàþà‘åZ™eP¥Ç\ËZR][ÿÅ65 Cr’\Î¥3Ö¥]ê^R#&"%6†!7n$ÙEGÚÄSf÷f—!¦f%cnåJÆcKÎãdÖ£X^æ>–¥Yr¦µ Êg _˹%}�fPš¦u fRåj.SkB[êeRúåRÖæ76%nælÀ{¶'o‚˜o¦#pÒ`J¾ãpv嘢4�¥=V&>þ‘;º#Mö"Z>gˆD'[X¸\°Y'wÄevj'wvg}gB…çqŒ§d¤|"S’¡`âÙz¶'{¾çwÅgI–™VÖ'd¾Ÿ~îàq¤`€®ßj¦s~ˆg*"hšgÙ唃Òå8�æ\N(….�…ò†~Eal*ålfzŠè^�h‰ÚäaÂIb‚Ñ|²£cªäáç‹ògrîP�zÀ�6g�ê(tò¨t†&ƒZ�n'v2¤„>ã‘’J@!ù,4*züÿ¸§ AOšXȓǠ"J,@±â¢‹ i”Äqà@ Q‰ €·SœYªéÉÙê¹éâ+ȳ’üç­ôêªòv,ë e¿0ÇllÍ`‡}áÍžä¼3™=ÿì0¿*qÑ›ÇYÒÏI#Ó;­#»îòÿ ¯Ôµ yrÕ„^½XÖÁë¯×‘ŠíøãÌ‘m6Â<¿„íLÚÍ6Aok´Ü—{w�{¼c»{ö ¸¼ƒ™²¡+ÿš8×ü1>)ä¸ç®—ä{X¹(—‹‘9šÜº½‡Ä¨|Ž´Œvk\ºÞëÊ*r¼‚Ʋհc-û¾Šwm;¤º‡/þ]s”_ÄùšíÍ“ˆa´ïþjåÇ?‡e–¥¿.Or¢ÿþ«ôï½B ªí¬Æ „lž%¬f5B ½0¬ñYð‚ωßùŠ`¿±Ï}탟üæG¿SØ�'ø£Íþøç¿þP€$ ™ ( *ð5wy ~ˆ3AVƒ@ "_ÿ4ˆ¾ôy0; ¡XFHBú�…“Èß 9ÑBê †1¤MsÀ>j�vÑaQ"ØÃ ñŒhô9hÄê<â�pLbD(?ØñŽOD¡WXÅUÔ«€ ¤ C¢.zᆸˤ ÈÃ2F)��Dã;èF8¾QŽ«ÁÑñ˜>(N‚  å©XÅ?�MjÒ+bHD*RRÃrД"IKHN²�…±ä%“˜IølÒŽyäI(E9Å>šò”©ÔÊ*)ÒÊ/âÐ.“Š%qfYËj^P2·ÔL‡tù9æ,gšüe0W2LP& }Ä’N‰Êd’¨�b¹]^¢¥IQÓšøÔ6ÍWÿDmV’›–ü¦´Â¹Éë ®*å$Ä9¤Î#±³ç$Q•ô£yâ…ž¾±ç�òÉQÜís¤d.P�ôŽURBJœ†Òá¡ÝÎD): ‹¾2RÃÒ(:ÊS±}4¤¸dIKúÍ“Ú1¥¶Yi2z‘u²3¦‹™)Em MXÖSR÷ì©VöÓ~¦d›C}£@#aT ¡åd©Z\ SwÊ”A4­©¤ô‚ѸèŒ[Ík³ºÊFŽ4¬c-ëY©¢ÔT2uNE¦[£ WšRµ.uåÈ]Ÿ©×Ê‚i˜Í¬J`´_À~ í$û‰ø/¨M­‚0¢,‰‘(Uê¡Þ>ËÿÚ¶£›í¬8CË[O’6¦í_jU Ö&eX¯�Il{HÛGÝö¹øÌ-Å<ËÛÞŽö:J î*†‹ÚÕ^D?ÈMîr'Ø\U@÷¼´l HäHÝê‚ַص�v¹›ï.¼´ƒÍjÆ+Áò¢÷¿hT¯Ø»[÷Š…¿�/wí‹_ßLi¿ ’­La ˜À›4ð8ÙEª(x¸ >n~_aáHØ-µ­°ŠÃwá$¶WÃx≒”ÔGâ–ŸíÞ”ø3¬œÎuÅ@ö¨z1ÌÉêÔHN²’êUãî÷»4ÕñŽ_Óã«6.ÈXöé�]\`Þ9ÉH^²®š\ß'ß7Ê#Þq•3úã,»yÿf-áCIAç:ôË`3¡Èâ§yJk¶k›ßLè½nYÎ쬳�ï|0‡Ù6L®¢�É‚ã¿lÊT´$[èNƒ)Î¢IÁèF;ZÏHâ³™ã*å)kzÓƒö´¬7U…ZÛº^õ�’Ö³ú’HArxfMìjÚúÖ¸&Ô9•D"_oØWbÔ°‹Mí4»ÖÉVv2™½g/ÚjvÛªMnZfIP}'E¼]pÏÎ7åŽw$\¯t«›Ýq7÷)ï~ ‘Þº²÷;ñ]}o ÞþNø5Õ[ïŪ»W«ù­ðŠ�àÚNåÃ+BpÙNáyî0Žn‡ß›»$ÿò8šA.ò–k¹�ƒˆ¹ÌÞlî’q‚W–ËwN0õÊ|æ&§ÁUîg–óüèÎðÏcNógçæÌù´‘Nu°aiè=ÄR¥8]õ®ãnRPG Ö#Äu¯›=l`oäÇŽœ²Ÿýícœl'U)¸Û=wß‹ÙÝ÷¾¼ËŒï€œßøÂƒmð_3¼âãŽøX/þñšj¼ã!Oy/Iþʕϼå/ï\Í{þó ½èGOúÒ›þô¨O½êWÏúÖ»þõ°�½ìgOûÚÛþö¸Ï½îwÏûÞûþ÷À¾ð‡OüâÿøÈO¾ò—Ïüæ;ÿùÐ�¾ô§Oýê[ÿúØÏ¾ö·Ïýî{ÿûà¿ÿøÇO~7 Ø ÁUf3+ଖ?ËçGÿp%ÇöoôýoŽ?úéŸDûïÿæ§^ò·›Uêå~¸bÆM˜D¼‚€ Xa ¨K Bxd%t èrÄ+�¨Wȳ�(h(!ˆ�#h[%XB'ø)ˆ&+ø-è‚c‚è�¨‚$‚7hMm0„Dø‚ôƒN1ƒ'Rƒx„E„E˜ƒ0¸ƒ(؃4øƒ,è„‘4€Ø!žäIIJ=°`-Ã6ãÆS"`þ‡i@¨…Á…%ä…_ˆBaJcbeht{‘†jØ@l8enpH?r8‡+Q‡„p‡6v z¨|ÿ؇ ñ‡;ˆÏ1€FSˆ†ˆˆŠèdZÃ(€ñˆ�(‰mH‰{±�—Xž¤$šH†�h†Ÿ8$�(¢˜…¤ø¦H1˜¸ªˆdbÈŠŒ¨sŽ‹±(³hƒµØq‹áÂ葊IUN›Xf­ØˆyŠ}(G’xŒoXʈÌØŽf *�¾¸(ÔˆÖ(©°Žì(G2ŠÚ8ÉXB§hèŽã8LѨ(ÅqŽw‘ŽìØŽIôŽ´�w1�ôS�÷xjϨ�åØ�ÀX�CÒ Y‘¹Žîˆ|°‘i�|��ä�‹ ±�yÖ�½ˆ‡Ó‘á¡^”Ð’.Y‘y‘‰É‘ë‡YÿY é"Ë8’àÈ�hå�(ù‹SW*’á’/ “­p‘©0“WQ“y“�SB9c?è�JR \Ù•çtNãU^�"`¬P–f¹�:V!°–lY/r$•T9$V)-X™•—€jGò•É–(&)di–e¹�/öUÕÁ–m©+oy“qÉs u™•xIz™J| “ò—€)˜]†b˜ké–I—ÚX•"q•éc—w i7™ZQ™—©^€˜%4˜œY¨Y/$"šÇHš¨`šš�š‘Éš­a$–�2�–¤[T>™•¸ 8^±˜°Ñ˜�©•ª™q“éš~©^ܤœEF˜…q›ºÿB+Ñ9šrYštyšªBDÑp¬Y%[·� Ô�Óµ™Ð!¨¹HBžG!sµÈ›¾™Þ3ážMÒgFQñ)ÈCŸáB›÷i›v©ŸGŸVàŸ¤ éù›ëùí¹š©„ qµ �Ò ºä�ÀÄœö8¡1±ŸÐÙŸ1÷ŸçÙ›*  Š�Z!¢4E¢�b¢ÉYŸËéWߘ•JŠ¡”›¬Ð˜ž4 Z ºrX•–•¤@ G(úY*šŸ-Z¡/z¡1JŠXŠž‘ð¤7š£HB¥P¦ R¦ßâ ˜¡øÉ¢�ࢋá Jˆ°a–ce£tJh"R †z¨Rù—G¨KÕÿ‚š+]‰§¬4âÆ§¯á§¨2¨dP¨‡j¨‰ ›¬°¨–Ô¨vù¨w©/1©`ÊE–*mgxƒ}Z–Š#¨Vx" ª£Ú@²IÜ„ªY©ª£‘G’Ê•”ÊL±j†E9‚µÊ ·:¹úžÚ«ˆz“Š’áR-á("�*7QÔªÊúª•*—ê†Ñ:­Õ* ×Jž¿*Áê&Ýú)ßšáŠ'ÉZ ËZD‘®Z¸®›Š«ª¢«h(¯ó õj4ÞêhສâÚ¯ÿ°²Š©ü¡©Ž©žtã©Ã1ñÊ+ÛÊ“˜"$™d"â›°a]Ù•ðTfä„S±�ÿ‰°î³�!‹.#k(PÉK1(û“`¶²îá²/[ 1K3„5k«5j°›D:»³=‹&?´÷š)‹dFHû²K;MK«Cb³;« U²W{"Y[ªÜz²Òµ–ðµ6¶0KC2Kq4{¶PÛ±J7kÛ¶"뙼· )´uK´*›,;Vž”´¥�\b€ n7~O+­QK­ªR¸%´¶ok"Š;·&1´—�¯‰¹5¹Ik¹˜;yà7%…Cˆ#F#§&�¦Y™P,«”­€º®û²«Á²Êã¹—PÊ»¼«Á�XÒ‚´+ÓšÇK½ãŒUÑGÆË¸\Û[™´çÿ´½á¨Ë˼bá¼Æ½C2€Ó‹Õë¾× E4VEâK·Ý›šUA¹áëÇ‹¼Ö …`@ü%† ¾üÁ¾«ï;Fƒ½T¡½ü˽ÖYªõû&þËkÌEì ­ë+½ c ¿(4¿-tÁŒ€ºÁ™L* ¨ÿ»Á¬ÔÁqñÁ½è×¾ÖÀòk}d6±�‹¿TQÁPðÂRÃü$lÀDˆÀßDÂÖ.ºæÃUÄ��Äì½×Yr©„ÄÈ«ÄÌÄìÄC¸�:l`ŽJ(ì?X¬Å[;ÁE ¢MƼ2ÌL4Ì6�°A„h<Â0¶ÆRÑÆý£Â,ÜÅyÿéÂ<¾I¬ÁK¬5M,kðøf|Æ%”ÆîEÈQaÈ«€ÈC܆EýÛb<Ãd\ó†Ã!`–•�sqÉmÈQ,ÅÈÛ®ž Ê÷+ÊMâ kK¾å[Í[†l‘¹ÿÅÊáÊ•Ë!Ë´ ƒœªllÅ)ÜÈö+Ç?aľ¼³À\¾ÃÜŠÅ,»z¥�”-i€~X�a3ŒP»¶ËDfk6b“Sö1˜PÅ3FôÅ+5’œ¬ Dñ7ùÆá ÓÊ”ûœ;¡j¨³z^ä\æL è,‹ê 6ììÎPÏê%Ï5BϽÃ÷|:úüÀ’Æ]þl ]±/A b@ÐgÐÿ�Ð ¬ÐIËÐDñЕÑÐ5Ñ{Pщ]3-¶ÛÝ@ m "­3ÕQÒìrÒ?Af©µÒ-ͯ/¥1=2}M ½ =žÌ*<íÓÏ%`(ÔID"•ÌUÃÈÑDÈD}ÔÔOÝ!RýT V�ZX­¥ Ó2Mimªc= eM(çšÖ*ÆÖ%äÖ d¡ú4×HýÎ#t×µ6Ï$QÏ$í^øÜ×��ýFG£Õ=…MÓ ŠØ7}v©ÓýÐj}[�M?’í>”=r–�~Im×U„×�=Ò ±×!Ú)=\¥ý§½7�ÌÕ« Ö‡�‰-žŒ}ÖŽ-� á’8¼ºÿ¦’9ìÌMcµ¶}¤1c¥× mÒ/�}4ÚËÝÜëòÜ8ªÚ^=ÓÒÝÚI�¶ƒ{ÇÿЇZÛ¶u”-ÙÝPÔ•ß�§ÄÞ�sÛ–AÞeÞU„Þ•‹“�G|ÝÞñÞÉ}Õ†òÏ‚íÒ©ÝÕ߯ÚqÅ߀êßæJÑ�½Ý^BÞÝ>ÊàŽãàªKå½³çí*é�ŠP„áÇ­á‹Àá-ÔÏÎÒ!ŽÚ„}߆­ß£€âR«âHúVRà/.Ü-ãΕ ^bã/'i G;²=^'?^ž$äùLäF~Z6G nÚƒ ÝNnâ4%å·lÊ_ZåŒuå.®WéHà”`à(ÿ„à4Þ Q3I�–SHT9#á-DáßdPm~`. îç«ÀHjQçÌ}çõMâí¦çÅç^z§+^-ÞÓË,Œj¸åô3ãaPã�N3�é®ãÎãîã…éA®éCÎéîé î¢.ß)4âÑ]¥Q¸Õéç¬èñê^Ù 4€&•IÍŽfÐëñÝ©åêg£°)ȼ²�"õÙýÝ]É‘ñjP’ ™ðM…1ÄQÑTxÊ�^� ôZ–èÒ“¾s¿ÿ¾W©²5€ã�Vg\Y`™î1EÝà(ß~“ᾎã.âå¾èçŽêÎî!Œ~ï^Bñ^Ü‹õÿ¾‘ñúPù¾ïžíï~ÝøÍ¦‹Pð¬pðÞH9 ¯á Ϭ/o&0ñtVñ?“íooŒâÔ¿~!Ÿ #�Ú%ë‡Zè.)¯)íÞòN¤¢Õ~ 3Ï5ÏN7Ïï;s1ÿªï°¯ �º ô �ôè·ôŒÐôâJñ•õ,>õUß„Wßñè'`0ù”O_â>-äæ.ö(¯ënö+Ó‘éD óóÎö\É‘ôeó´¡ïrO9t�Xÿ$^ñš`–BÏôDû€?‚o„oøx‚øE!QŒ¿ñ7ùÁM”_ùÜuù:“ù�°ù90öeŸ)Sò Ú¿ý<ÿŒB//ü)Nï©¿‘«ÏNôåú9_ôÈÎówo¶�û|?ô ÏûM«²µýÛüNO PbÄ XPÊAC `ÈÀCˆ%N¤XÑâEŒ4nÜÓÑã#�! Œ$™ÃäÉT)#­41À¥ËI1EÍìT3ÌÍ“& ”’ÐÐ(ŒA…JlØðÓQ¤Œ”.�ÙtÒË—&¤N…êòÒU¬¥´òášÓd°a½æÈ”i%Ë©yò`�)jÑ":qé¼R×Ê]¼ªôîÝÈʯ&MK¥UËvæ[(‰¡, ÐËcÈH‘¬´%Ô¦¤4k(�1Až>ZÚôéˆ9zìR$É‘cS¦:{ùeÿÓ¶5;Ý 36tB ¨…C,ÊPòQÁJ�Ƭ:ÉsªU ‹ÒZŠ+Ÿ±aÅz-{6ÒT…¯¶}+w.ÁºWðŽb¿—¯F¿¬ /u:bÅŒC~|üSòÁªZnÎ:ûl'ž­¡át"Õ4:eB ] ¶Ø¼š­6e¢É&œrB°'àD­¸üp@KZtñ9$¢ƒjºê®ËN»>Æê®6ÂîƒK.ºìº‹½QÜÓ«¯¿*³¬>[¬ ýøS19Û`Z®@Ï>KPÁâLôò´ °B 14@6•Xêp’Ü@ ƒ “Fô)¸/…BqJÁXt±Ee|‰Æ­ºò ǹ3‹G©Ä»ÿ„¼ã R½!Û3Iù”ŒÉñ[ÄIýÄ௿ã¬r€±HË-t¨NV/ sÌ -|ÄL4iS3EÑ�78uúí§Vƒ¢dXbñdj¹=ù„NªæµNМÕñP´]+S·=¯€ôÖ“Ô=Jç[ª>šÌJ1f›ÍXËÖlÊÔ·”BÕ‚5ÅøâƒußSd¥UÃ4¿[³ÍÝnê59KŒEM$¶ØP“ÓsÏ>™•Û¡=IZC½OQFÍ{ÔÛ"'…/Iú0]TSNÑU7%vÄÕ)xQM�^{Ä7_Vø…Õ_ kåpf‚y- Î_é|ˆá.|xؘ'~qÙQpÿÖÆAqœÖã±-Hô„´‚H#U ×RrÍM¬Ó—S‰yÔRKéìTÆäÅ9g‹Â “µŽPñûï}eUkð<01üpÞxÛdqÆ›P7Ýz�|r¼ðÚàrÌùÞED:÷sÌQÔüiJ0ýôÛj+Ö[/ëõLšÅê*Pj·=½ôä�cwÊzLöÙ ~xÜëzëøEÊÖÜwMš{ÉèÛfÞ»•œý*ë¯W}&2º÷~n�|ò ï¼õVM󿇕\ÂÕ:ñÄÃ`¼qwc‚¼¦É)¯Ü Ð/×<þ0xîsýßHw:Ô-g{¢h�ë`»‹ÍÎv·+žîxǼßE+Ã#^ñ�÷ÿåñ�yÎs ô!=ßQ/Ù› §Óï}|âKù*b¾óñ-}~ÛûÚ÷>Ãp~‹sÜrî׉üInüëßÿâ'ÀÎõodÍH€Ôm¯�¬{ gt½ Ö®xW°à0˜Á/�ƒ„ã“g¤åùŽ„0! {§Bbo9×[™êbØ=ð‰�††°!Ep¸’«9>$\uª@5Ç‘ZIb%{°D):1q•”"=rEP`’¥Xà7¡ÈªŒò@c,#eP •0‚b•ÅD-m9ͽ²9u|Ùô¨—ÇKÓå)þ:9ƒkK O;H4K„Ù\B»Ý Ì6–•»xoqÞI´wϹU<¼è›ßûö·+�W<ׯ ¯Ë�ð•ߺᇸī–ì˜\œÙ_\´×ÔñP|<'!¿ÂÈCî™t )ïŸÂ—‚vQ¸ÜI0¯º×]óvÃ[‹:#½}^ï1=!C':rÿ݆Z'}nn Á-¼=_G}á˜:±CblS“PÙaœ9×7áõ™�]ì'!»Ùß^ò´Ÿ\1l�Û•w¹+†î(†ÈÌñ.½«NÞ}çùßëÿ‰o+}èE?z¿ÏøÖÍÜé3,5'_ù‡_>â™w^S¢Ùy‚tFã‘àx‹ª-�k'øxa9uTÚÄHQŠå_ ú˙ ó§ì>æ¼�;ÏŸï/6áë7Ã3:Ä ¸É{ äcå;¸ÕÙ"ç4†› ‡‹>�À< £8ëkìk �ؾïƒðƒ‚ñ»‹òS»ÓR¿þa¿íq?'�?â�?ú›¿ûÃ?íÙ»ýã½þó¿ºÂÁû "Ù7;K¦â³µÉkŠ …|<ÝsÀøaL#¬¨:” Š€h:œë0‚0%Ð�æ ‘ »%"–Ó#œwÑ ÛqAËQAÿOxÃ3„»¶à:dû°%™A¬A?´?ýkþ›œ‘ÙŸÿ»‚Aj'!Ü‹…*Â[CÂTK¾uûÃ@d!Zœ($´)”>«#´+ÌBÃÙÂ,)/Ü8¥‹‰0ì “ Ãý1Ã×kŸ4,…5t¿6T¿7ô„8D=Õ¡CN°C+ÀÃÂÓCœÁ?üCƒ2(¿<±ùAŸ£D BIÂ;K¼#Œ‰$œ9JÄÁÖ¹ÄMÈÄËš*”/+¤8PÄQ¤›Rä¾Sœ„T$=ñ[Æ»pEFˆ¦XœEô«E)ºÅ\̃âE_FIˆÁ¢àÃ*(F?<ÆaJÆzz5ñqF"¼€Dª‡pÄjœ„kœDÿ?¬ÄPàFo¬*päÄ*Ä–¶hŽr<Ç‚HÇ�sŠv\Åw„”Ê‘GzŒ‰ê°ÇÓÂÇþÑÇW$œ~¬CZ¼ÃZÊÃ=äCƒ¬A„4…,1†œ“–$ˆ”ȉ,@¤«È‹d¶?œ¹TTLT àÙÄ œ>qÉ™ É E®àBR¢/\Ž•Ö,ÃaÙÇz¬_TÁ ÀÉylŸ�ìÅžüÅŸ Æ $Æ¡´¿¢”‹£ìÁ¤Ž¥|HÂsJ È(„Ä÷,lôC«tÂÄ�B­Ô «Gy¡°¬Š’,ËQDÉu\KV|É·ÌÉÁ‰KP˜K7„CÕÔÅ9äÉ{ôÉAÊa¬¿À �ÁŒ‹Â,ÄÊyÆÿvbÊÅ´!ôÙ¡­T25 #TŒb:�b2éD#—I©fóð¯ì£áÁœ¾oÛ1˜ Ï™à ó “ø Îol“¹)ÅøÁ`4 Ÿ¤9­@Z¢Ã4HP…HÐÿ –ãLŸä,´IŠ¥æLŒçüŒèœNí$ 5�ëŒD.¢–ï€(î” ïôðìLlO¯0ÏOAÏØROQ`ÏL[÷ô øôHù4ËúÌ·Á‹ÈÓÈOðÙÏrêOÿ N*ÐeÌ HпYÐQrÐ�PƘPS Î µÎåÀNu¦�‹QÈš-O±9OKO]íÁã‰QV˜Ñÿ騉ù$ˆ ¾}SÆàOð R!"…#ÅÍQ!%�¤U(TC}P(pÒ‚€R)�R𪠠ììPªÈR:ØÒ®dÑò< às+³2]ÏáiÏyOíŒÏ±Ó8::Mýü <�=Å‹¦üÓÒTêTG2ÔCmÒ?‚Î?’Î(­PG� HµI½RŘRèÎïÌÔQ%UBèT“øÔ– ÕW2Œ3}”4=UMU]UM ûÔQü„Õ•ÕÍÓý�È[ÅU¡ÐUïàÕêðÕBETE%F5ÖcÅÐ別eý±ítVhQiíÒåÔPÓ�Öný´oU ÿT¥ÔËhÓN`UsÅQC¸ÏÒ¨S³¤Ïv¥Õw…×á“×yåAÕLíU|Õ×`•Ða¥P>û×d­��•Òq5¿ƒåRÛðR†S—|Ø6  ט¸ä ‘ù¹+8þ8™5W�åX(8WVq«YíŒ%BÙ”UYŒ°–…ŠÁ $|]…Ór«}-€~ÅØ•ŠØø™T,5X�ÖGמýROuØl…XQUZÊÛTá1U‹ WŒUU]ÙØr½Z�Ùq+Ém©>õÚ<[‹Û]­Š²Ÿ³MÛ–ZÛ¶}ÛúˆÛ0ÚÙ íY­øÙ„ Ú…­Ö†-Ú¿=Úˆ\j%Ã¥6Å7m\¬­“ÿÉ ÞQ¨\ËEWÌ¥Íõ>êܹ9[7r+7’7"ÖFM›T¹MºmÖ>ZÝ»EؼM\ÅåÛkõÛvÒÖ>»ÝÜ•ÚÝí£ÞÅV�Sà^É%^Ë=ÞÓ¡R¡åÝ"³Å×çm©èÝ’éµÙÍ¿íÉ^ÞØÞJµ[-Å[½ZØ%Z’!ô½ÀÁ�X§­XÝ¥ZÞe\øíX9ýXã�\úu+ûõZü…$õþ½æí çý èý éý êõW•ñLQPà›`à‚íÞgý^ %´¶ ßÀÖó\yRßUÓö­Ñv܆\9a&Òâ-a°Ýˆ[œr\9Ñ�Î0à„ ÿhŒF½À+á´`kTi;œ± ¯�!1Û—€;�Ê*�H°Kˆ¥? $<;:ÐÃ:6™ ƒr¶o#Ö}lÀP¨�¦uZ’9Ð)K^á ðâ7ccÃ)ã÷EãOà 5f~cDŒ0Z9^:^\;Î <Öc—àã5òc#œ<¬d?$äBv,Sœ/ÜPäabäOqäØäGæcIJŽ”’‘FMžf†€/>…0eLe&åg¶‚S…TÖ‹ `ec�céãݸc@ZÆB]ìcÉ @æåôe<fuæ\Yäì‹È@æ»ÔÉeŽdP˜d%Îdj>^NöO†mææ3~“ÿ4~Œ5VeÓØ±Vž™W†U<‰YÞ\¨°eÂåz£AŸB†ÊCÖ¼~.æö”c–ÎG.èfv”R†f…^è.ÖˆkÎæ�#ã1c�ðfõ‚‹&çÓÐèsvåt†åu–åvÎc‘Þãx¾åyþã[Ûe”îeði°k}¾Âaæ@™æ�Ž&H¾émIèXãijnè‡ã å¡eŠÎip¶hT^DU@ ¦vÛª�Luþh“ézÍ«.é¬Îå(äê Jé¹ k±V®`Fä¶8ëÎhdšNæ¶>hg†ki–ë¦klþä»Þæ¼îæ½þæpçÀ^ê_ž3l¨FìÀc3½ÿržJÂLFK¡ìΰl°~gi+ë§£›Ó"Vbek›mœfŒ%"¥6mMFm ¶¡¶¢£S¿gÀìÚ>…۶Ƨöhv6&�èí`þmá î¬nÆ.n¯®läVîúId„sîr‚né,?ðО䂸îoÑîiænÕön¼o½6Ì»ˆíó¦í|¶mÁÅm÷–jøùÞgú&ûîÆÌéö1n�@îVðo\Ë•æ&Y'!pS8pŸn'�fßnŸîäÔ†èÕ–è¢~í£NêÙÎèô^o‹lï]yïÎq«,Ãî$nâœ?tqçÉ¢§qŰq7ðÿwæßì^òÇ\'r gm wm ïk¤þk6vó¡Xi qòŽŽrŸr ñí±Ä,Ï-ÏïÁÙ/ïoê ¬0W È›â2'ð3/„4¯î5¯œ6sü�s»žs#o$'ï<7ï=Gï WïgoL8l)�ïBŸïCOôÉYt'Gô°V!IŸtæn9KO 3?óMß–N¯äìu•õ‹1‰p0ô_ðcI”ûmöá ”IÅ•éPVoN ž€ ÒŒ0ŽG ¤0æ)Ås=ü–«¬2Ý  ­D‹6Ò´á-RgÇ_h§iWKjïÔÓú¶lçsáàvõvl÷×÷ÿƒ ÷§1wB÷êP÷u§ª9âøoÄ yŸwì #{wW|P}÷ ~Ðøžx9Ÿö»ƒÇöÅèaøÅ¶’o×Ùp‡‚qŒrׄs¿’IÒø0öøS¼þm ‘ùz÷Š{Ç‹|�Ýôø²~÷Ó–ÇÜ€è”l æuÇkç�„7�?ä˜èyP08ú‰Œ8ênM¼Š@úC¥?5¦‡á-*&z·�’7Ù“oΔǬgù­Û®ò¯GÅ‚ûÕ³yHÀùm—Ún8µgû�x)€Œ¸�𹿄º÷û÷«¼Ÿ�ÁZÛXú{®ÝŸª'Ú«_y?|yMü�WÉÆ·öÇ'û›×öÿ…§ü†·ü‡÷ùˆwû͇{"zÏÿø«€�°{ÅÃûTþK8ý™eŒÔ—z“§z”·zã�}­—}ÆôˆÄ—6H>ž4åÇHxÉï}ˆ�Êçùà_ûŸz/è|9ÿ|æç�þ¥F (h0„ ’iè°Äˆ9&R¬8Q ÆŒ£6r„âñ#H�s\)i’#G*W²léò%̘2gÒ¬i“æžœ¬X�êyÊ ÁIBEM¸èèÈ�V–zi 驪¨RoÆ`u'«L™"q�T襰DE�*ælÄ¥°mê%'Ü=š49ªëhÁ°z/uêÛ cˆÀ‚ÄkxÀ^±c‹ÿ.¤ãø±Ã‡i $ ¹ô²”Cr†Âö³·n5�¢jú4êÔª]ÂÝéó'^¡“ÆEjQ)S§P¥F]­Òª¬Z»z :IïØ² Î†I»¶mÓ¸9çÚ½‹7ñ¥Œ&Lð0Pì‹+| 92™É”o[ÆœYsç� ¡‹&íû>þü¨[óôiX6mµHeP\æÖS�ðÖ›oÀ ·UW_§Yf¡Ñs¡E'uv†�v€qB %š^x‰�'ÊB¡˜çzéMV n˜‘¶Ž9r6Ÿ†õi¦�A ¹¯ý7yx n .xŸƒ; ¡qÈ¥sÎyFŸtrÑåáu‰…(ÿƈ$šX"vª8^‹/Ò£z4zäÞ{(å˜ã€ò(ZSö ù' ©é_lH²( mÕˆàn¼Ay•”r%¡•.w!DºÕe‡u©¹×˜ež‰fbŸV`y/Â9#{ Ñyã�äyÔž|ú(®¹¾Ô¯¯õ4�l²Y2l)Årì*ÉšdÒe%8UKÀI;m¬Õnœ)ÙúDe^—`‚‰B¥ÄgÒQ( rî ®õô»&¸û®^ÃZ‚�y#©·¢¼ò¶X,¿¥$ûï*œ-[Ò˜_A§! +, Ã+ð0Ä +LZ‚Ï2¨+ÆÀk¾žl°“ÈËﱄükp³Y¬ŠKÓº,ÿ€µ±b«mOÜ"æ-¸ ‰Û¹‹˜‹®º§°ûÈ»ð†¥¯‹�Ù;YŒù»o¿þpH<0°$1A 1Å;ɲÆeã求 ;²±È*‹õRÎ6ÚòËÒÆ|ç̦l;©Aa}î¸%•˺éö't»E›ïÓI;¶tZM; u¿SS ’Õ!¢ìžÖ[7 Óׇ]1´f›.$Ú¾ª-,±m›üö²)�²2Ýu[uwŽyï]\·ëøƒoTxÐC+¾øÑ�×k‘z1:�žz– <ðÕ±»Ç5öŸ¿z.‰=öéá™úk« Åv)%Ÿ w�´Gk»UÙÊoÊHº×Ìwï9#´ÿóôÁûL8Ðg<Å1n^Ž£ä"ò¼Ê(-Ò«ÚÀ¾g°ìQ{^ MJ'¾ ª†|>1ŸÈZ—>·­bsí›Ûûà7¿lÕ/~4;…Íü¦¿Pð‚þûÙ¹Š—¸¢�^JcÓè¼èM­&‘àÀ*¨Ä ~-ƒã MãÁ_ D6ßÂú,Ǭ¸iÆ},q™ÇVH?‹ˆqw)òÝþ€'¼QO€;4Ú%�¶¼Š4Oˆ«ràÔ^ÕE±-HJ´àL¸ÅAiŠ«¢P®˜Å©m±Nr_ �ÆޤŒ÷ãÝÍÐHC5þoxôÉy˜<Α"u´cdˆ0=¢ä{}ü#×h"HBÒ2þ?†T›"E¨Å’Èî‘üÍ´&9¿J®ÐŒ}Ãàx&¸N²ñ“ëz£»zxÀB•ЛŒåXùÈ•I–Úc"Äj)NßÜ‘“È¥%øµËƒq±•(d‰'â)OaÊ�˜ó3fþ’Ù¿5¶”ÐD^•÷ÊðÈš©ÄfÝ3:nFÅ›] $Ç)Qš¸¬œŒ°â· °FŽN*]’ç<}%F{ÊŸ™œa 1·LΟ�ÀŽ4Ýdž‚´!ê¡“6UÆÇ9T–�(P_RÑ^©ÎœèT'#yÙN_Få£ õ=YHÆb^òŒ(å$KuøR˜””2u MkzSœÚh�¤ã©7}ÚÄ Ò2 !ù, ‘ÿ[ä@° Áƒ*\Ȱ¡Ã‡#ØB¢Å‹3jÜȱ£Ç� !V I²¤I…#Oª\ɲ¥Ë—SœIÓ Ìš8sêÜÉ“ÃÍž@cJ´¨Q‡?�*e˜t©Ó§PM6�êt*Õ«X³.´ªu(×®`Ã.¥(¶(Ù²hÓª]˶­Û·pãÊ�K÷à‚»kòvØË·ïÞ€L¸ð`@ˆ�X̘ŽãÇ‚"KöÛ¡�åˆØÌÙŒçÏ…B‹Ž@ºtfΜѨ^í µë°cÏ™Mû®í´i“ÙÍ;…ïß‚ wíš‚ñã’+GÀ¼9†çÐ)7o®¼ºõëØ³kßν»÷ïàËÿO¾ºí¼k(S,8³áÄŠ/~ YrdÊ—1F½ù3hÑ¡•fÚ~ü­ÆqÄ&[nsÜvƒsðÖÛo¾ 7‚Ç!WÞ†vèᇠ†(¢yxé¥^_ìæÞ{ð"ß|ôÑaß}~ågÙiüùç€ ލ¨‚ *ø„âÆ „»QX¡…™¡q#Viå•Xfyåyyqáå—`z™â1ÒåN¦ðâü Ä›pRD‘�}laç�eêhF!râãŸ\!è ej(‘FiÀ¢̱ã�Fú(“d¤)Ã¥˜J9¥–œvêé§œr¹F˜¤r1f™g¦¹f›pÆ)g tÞÿ‰gŒzòI‘Ÿ€ 8(¡†J$ À;£�Jjì”ZŠé¥šfê³ÐF+-w¢–æ©1¦êäªüµúæ«°Ú(«�yêh«@…Ô n ¹î*h¯…fðÅ®+,±Ži²N.Ë,†S °ÓlðÁVVkí—N4ªPªú"«Þ‚ë¸e®ZŸë² ¨»WÀ[ÆÆÕk/ Ã2š¯¾�B�²Ë6{ÜÀ#lóÍ8§ðÂ\4ìÄÃÙF¼íÄÝVüêŲf¬ÚÆ·vÜ®»"“L�Éö¦¼èÊ,»ü\\wí¯ 2GsÎd—]öÎ û 4}ÚRÈ-jÞ*a±¸ǨñŽ<æª+Ôðþÿz2„,Cª5]{íoؘ­øâ6£m­Ú€AlašqSÜ*¸ãf¾…Òhü Þ¥�,²ßU3xËZÎõ×4´îz°ÇÎøì´?ëx©�“ôäNV^ôå¯j^7}wï™7è�òÝ+éš~úàªgÀºë­Ç.{íØgŸp‰£òܳÑï.åÞZÂ'm÷Òx޼è}#x2ÊνêÓSo=ìÚ÷i‚½Çô §LKH …ÀÀjà�lÓ &HA*0se‚�6ÈÁ4q�ƒÄZTšæw‚šðkóúBV8¸ÁM‡94Ø g˜€Öì8Ìáx8@† �\Âÿ†HÄ"Q‚œ`—€Áiðƒbð Ch€žÌ„'ôW gØB­½: £GÄÃ&øð‡1Z¢×8$&q‰M¤Ï?(ÅRÑŠöÂb Q8/.v:_£ Yž2žLeª€"ÉF#º‘‚雕E1”©’wt õÈG®��  %ï"@3ÒKàZ$#IÄ6Áq\Tœ‘ æÈÁ2µ™¤Ð&±½-~R”À &y yJ.¤R•`e+ùóJYÅrF´Ü -[”ËßìÒ„½ìã/…ÉÍnj'IÅ4æ«�™Le¶‘™AÌÜ3íCÆTršðƒ¥ÇD�†Ûô¦>õ™ÿ¤'øóŸ<¦*ÍyNÔ4óNë”L;óÎÝrLAˆ¨D¯YÂ{âsŸõf?ÿéÏ€Ž™ue:aBY.t ¥ÏCS$щ^Q�¥aFgÌ�rÔ£r"'A/ÀÓžÔN �ÌIçÏÄ@´¥A˜Ÿ–ÊÔ˜Î�¦P¥Mê=�®R™=õéH�YRhΆ1Duh‹ŽÚÒ¦�©MU>Õ¶Žqª­êGjάòô§[ê,¿º˜°ªt¬,EªYç…Ö¥:5ŸnMlm£‚ÆRá±�%`Ü,@ÙÊÚõÒ‚f7{Kxö³V­hç÷µÂJ€¨Míà’´‚Öºv°_p­kK[©ÿÞ¥±*€ld½7ÙÊRö²™Ý¬f;ûYÏŠv´'+maS«Z­ug¨­tEÉXÇê– ’õ–ok×à —¸Å=nhIë/Ó2µƒ{îþ¦ËÞAV·ðÍn«¶kàúH¸ÃmQq�+^ò.Ë´ÐM/w ÛÞ/ö¶ð�/oµ»Ý48øÁÞå¬~÷;O`)­O† Ìáþ½7Á*�/œèûà‹× ûUx?[a\˜©OŒ;LãÙ% Ä &UÜêÀã—ØÁ'Nñ-å@ä"·øÂ®�±w”\ã&“íÆ8Žr”{ìãy¿C.2‘�\Þ¥&y½³“ÇüdIùÌ ¦2�œ†çÿ>ZÞ²&“Ûe |Ùzãa2™÷<-(£Íj®›Ý¬…3ÅY\þ¯—[«çí4šÏ�þ”Ÿÿ,å@ú¾ø5tœÓ”A1õÎ× Ï£#Mê,MšÒ8¶ô� ­i-sÚ‰ž^ô F�Z—úÖ‹Cj¨H)J•‰ŠG¶°‡ìó’ I¸NötyÝk ý:„ÄŽöŒ�le[;±ÌnönžM,i›Úº¶¸£š$mó†ÛŒòö°�=îv»µÜæ&ºí=ØûÞ�t·¾g osÏÛõ¾·½ó½ï‚kÔAºöuŒ€Ml�ü…�87“¤kXüâÿ¸À .ñŽ’âH½8Æí†;œãÿOù�oSq‘»Ü⺦ŒÃ÷€r•ÛÜ oéË_s¿Ì¼æ7zír.Ñ�»¼ç}ù9Ä…ÎtA~1IIzÓ§Nõª[ýêXϺַÎõ®{ýë`»ØÇNö²›ýìhO»Ú×Îö¶»ýíp�»ÜçN÷ºÛýîxÏ»Þ÷Î÷¾ûýàOøÂþðˆO¼âÏøÆ;þñ��¼ä'OùÊ[þò˜Ï¼æ7ÏùÎ{þó ÷� AúÒÛ0ô^}éIzÔs]õ«o½ëµ{ÓÇpö[¯=ëo�û¬ë~²ï½Õ|áßükiƒò—_|ã«ùNZ>óyï|‰Ãú’¾ò›_}}_ß_É×~ÿšdÛÚî»ûûË ¿ôÇO~ó7y­Sš‚¦@ÿú·©øÏ? ÀþJ´b30îWcð7%DBN÷—ø·ýWÿZ(0Hc˜!ˆL ¨€ ØhxCX`x¨J¨ 耂€06!h`#hk„€ü!è+�-(€/(‚ø3ˆ�5¸$)Ø�؃>HCI4AAh‚C˜7¨‚WÀ‚.ˆ„ÓµVKxM¸HmbƒE˜ƒ¸ƒh…WˆOY¸…ŠÔ…DØ€F(† H†ŠE'ghDätvx‡^Ȇ`x„pU6$‡Kˆ†p‡x¸†¸‡nè!еVkÅ}}ÿø)h#sXDuHˆw�‡‡8…:X…²ˆŒHCŽøˆV²?4=EDäA¤'B‚RðŠ°˜‚pbˆP‹¡¦ÐE~+=k‚_ZPO¦=¶&ŠKf=¥8%§8D©¨ŠÀŠB‹±˜‚´h‹üc¹H~¼ø"¾Œ…%ŒbFŒBЦÈS¨ˆLÌØŒ:ÒŠÐøŠ²8�ˆp‹Éq�²•�ò±�zŒª3ŒàèhÆ8ŽPŽªtŽÎh ë(í(^µøŽÕXòèZôȾh9‘PP‘é�x¶�áØ�ÈHŽÊhŽÌxh‰B)y\ �Ð�­õ�‹‘)‘y‘ùø�™g™!Éÿ8˨Š"i$$)�I�Ñe�û£‹,9.ù’1Y‘‰’5)cÆxYMøTéVy•=© ”Â\Ù• y’bæ:Ú7 Ô@yp–hij¹–II‘KÙ” ù”a;4 •t¨HTùW‰•q6’LÒ•^ù• ™‘ –ÚW– „–i¹–j™/ “Kù'ú(— •v5•U¹—~�•±±•€É‚9˜¡f˜Ò‡˜B ˜gɘ�i�iK ’I“”YŒti—”ˆ—™¹—œ ž ˜¡¹a¤¹|¦‰šy š&à˜�ùš³9—°S——y—�—š¹™}é“ù™¿–­3–Ã‰šÆ‰œJÿ™>ÂœÍ •µ�·9�¹É—Zæ—ò™ )˜ÀÙ�‡‰˜Äž¬™œä) æyžÞ±Úc7 šªD•v¸—ð "‹ò !¡]ñ7–ktŽçØ„•z• úÙ$Z  ß¡j ‹„ w   ú™*¡º?ª}Š¡ª¨¡”Å¡pà¡ ¢ü7¢¡U¢&Ú(Êcʘú ¤ š‚Ê 4Z£Ös£Ò—£:ú@ ¤ Z‘"ºA$Z‹GФª¤*Š›Oj• ¥ 8¥¹Q¥:%™¡¥[Ú¥_ê¦A*¦CJ¦Ej¦gºIZKº–MÚ¦~ð¦±ÿQ&rJtj£vjxª£zÚ¡|¦P0¦bP¦ˆ0¨„š¦†º¦ì©¨Œ Ž*£TJ£uš!wjD[ A—ú£™*¤@¤V`¤ Š…z¨j™¨- ¥�#�:‘z¥“Z•Š¡³ ¦¶Š«`9”»ª½Jª,ê¢ ’ª€9£ ] ð­àšI0®äj‰Áº—ÍZ«~z«€š«B9­ÕQ­Lº¢Nz®‹ú¢¨J¬ª:§¬º?ஆA®åj‰Õ™®÷ª©œê©N9¨òЍôjªøúe2–/P±[¥ÔÓ:ÿú­â*°I`®+�Š©û¬í­ðJ­¢ê«&¬Ø:¬ôA±[±D’±4ÿ°± б ²š™…‹4²´Z²ë ­ïš²Ð°¿ú°özª#2;³5›±8«³KˆÕ鳊´Î:´'[´)»z³‘äT�f{¶9�¶jÛširh¥�–ä”—Ô©™†2( Àx‹·t˜ª!%)Z“©‘`;b‹Ldë#g‹¶j›¶­I)nKp‹LrÛžVY·‚r·yË{»«á·@y\�»�ƒ[¸ªt¸’¸f»¸Œû˜Žgo{–q;¹Õi¹W€¹y»¹й ò·¡ºà8º†aœmR¶¨K_�Ë$�‘Û¤r;»…b·™«¹”È·h๠xb¾KŒÀ[Â˲FÆÿ˺Èëº� »’+»tû¼—½¸«»¹Á»V�½¢8¸Ì5Ý‹ßkDáû’­«e¯›±Û¼é[Л¹íÛ·”ÄAüwbUÐÀU—ƒJ¿©e¿ªÙ&Æ ¾ÛuKý[dÄI¯“K•‡2¶«·Ó˹!»ñA ¨ˆàÀ,­ *Á¨EÁŒiÁª‰Á¾¥ÁLò�ŠéÁ²Âî2ÂÒ‹ŠÔ«)¬À³ÈÂ. Ágº½„q¿œqÁú›Á-B)<¼¼yùÃq&Âì[¹{¼Q’Ѻ°O ]NLÃkiÃŒ‰Ã•¥ÃrÅæËžo ÅZÆÅìÅîÆŸ;ÆLL™f\za¼ÌR\Dô导ÇÿŒ›s<#@¼+B|ÀÕ;z|½,,¿=øÇ¤ÈÜ;ȨQÈDtÈU¼Ãø‰š>ìÈ[Ä]LÄ&<É(…I쮢ÙÇÊ]6tË1„É6ƒË4c˹¼?°•9`N; Aqc®òš<¥¬F”—wx•¢%œÊA£.àÉ>š ’)È¢ÕÀœ(n¾ÌË·¬ËCÎ3Î]Á<.ìLÅü@Çl‰É¼”ËLkäÌmÍÁ1ÍTÍ5pÍ5¼Ù¼Íݼß\á|mêŒÎë,›ýãÐ -ìï›êÔ.ÜÀ¡ ó�$óóü^óo/ðqOðto÷wŸ÷Ò^Ô¾¸ñê%©®Jâ…¿˜õáž¶¾^T/°VòY¯î’Oòäî(ïa¿ùcÙ�ÿùlÄj_l¿�6÷Šú:¯ú ÿÈúBOeÄ’¶�ìέô­:ø¶ûÅ©šç~î�¦¶½ÿûäj ›1ÐÂùÄn“ÿA€Ö0Q°à„€ÇÏC?V$B¡XÀ¢ŒU4nDÔÑc�„!.,R¤ÎÉ:þ�aIÆb�D1½ÌÜP3œ9uîäÙÓçO A…% ÀQ¤I�bÚ´ÄS¨  ªÇ*J”9´n•Ó5Êך�% TéQ iÕRe{ Ï[¸qßJ-ˆÄî]¬'·–,bÄï_�/$L@ê»UþùиeË9‘%¡\¹²@@¥†\Øbĉ/fܨÑãG‘ —Īòñ˘‰fz {³ìÿmܹu›=«´©S¨Oéš`kUOÞ:[¹zkóènܽծmëVîõáwñæU®õ/`Á� /�T9:› ÅWuÒsÏ>ÙúsFºj´1Då =4ÑEïÑ!›´RÊäS2S&âT´ü°ŠP§´òÊR·t)Uis0Xx'TJzë¥á^|¿Ðw_YÍÜâ_€‘ëa`‚0øàÔîBcaÉü{é¥C"Þ¨ÞzÏ¢øâz…¸ÄË…À�CNbd’•0ùäQjhe8$£ãe#-t¸D1Ãìa‹öË/¬°xú¨†sE" ¹ýö‹àh¤÷d±¦›vúé¦ [ ÿÆÿ9âC6 €®»öúk°Ã{l²Ë&Ûâ‹ñÍw_}ûÍà€ó"¸àƒ NØ®©Æç°žøb´1¦Xã‹9þ*Ñ�E&yä“QNy–ræîdÖ‘æñlˆo�%â¹&Ÿ;:èú ºh(�NZi¨[Zê…1"Ûo�¶6ûvÜs×ýëÀíU›¶Ûîîž»‡ºíIa†#³úaÚ«À¸wÁ œbã@z‘̼m€�I�ìKˆí{.  ðû¸ñ#=Š ó{ ô;µ{ ‹Ó‚÷KˆÅ»ÙSÚã¢x›š'Ñ?(é¿ÿ‹Œ\ˆl2Њ„‰˜PÀÖjÀ�{@¤{š,K¾†«À­¸À—�¡Å€¾ ì@ݨ”ÄÿðQ‚Dˆ4¬<€,�t�ý�A8“‹4˜´ˆÜA„èÁDš D˜!\˜"ŒŒýCš@ß hB8xÂˆÂØ Bd3tš5z¯-”@åËÇCÈ{™1ÔÀ24CÜ@ô¾ ™7ŒÃ6ìºÏûºÐ »…9>ô? ÄD‰z;Mk®C<šDd©ø$œÓ=�ã=ž›D•> ¼#¼€8ÄQ´0.46/Ô 0´1T 2Œ>W|ÅŒEfº>Z[œCÐûŽð==ŒÁ)™Á<øC Fcd&dÔe”¿Ù£¿Ú³»Û‹Æ‡�Äjl ¿cÀãáãÆÿÖ—B E÷ÅŒšÀrÌ�s,€tüƒu”¾v$ XTCYdÃylœ,;º,k®B!²ñx¡=ìÇ><=a0²™�¤‚mº9�«�¬ÔÊŽGRìBSd>Tt>UTGVdG²,Š*$ƒ€šZ:ˆP–"­2hMõø ¶?|™Øì<òi* Y Ú¤2A¦ñ4ÿæZ,)P�jñ�Iˆ¶ÈM/ºç|–è?ŠÉ®BÁ‘X™&)šG”�¸yIŠçj¬HAŽ1(Oóä9SölO;” MÑ Ò,ÓôÔ|ÕôÖtÍÆ€Mª�͆�¡ÚÔ>îI!¨ GùƒÞԤ߉¦Î; Nã\–@Î"QΪæ|NÝ’Îz¡Në,¨û í½[Ty˜ ‰�Ú‰­Z¡¸ÚhÎí\­e’ɲ üÚ�[²ÍT¾åEHÛ®µ0¶½Â p[ÞL×-]×.mW™}WšeZ¼ÅeÛÛÿð£Õ}5Ì~ý×\mÒÂõ^=Ü;5X„Ý amÜǵÙ×À™kÙQËÍ^Ì Íí\Ï¥‹­MÑ…:ÒÅVӭв=ÛÕ�ÄÐu]ÍiÛ•mYÚ}Y„ˆÙ™„š=Nßàí[ÜË×Z Ü7\€M^XÄu^¤eÜ0›Þj‰Ü—¸^gÍ^ËÝ^ è^ïm€Ï­€öe¯ÑU8°%˜ó5Îô=´eßÖe¯×5:¦‘ÝR�[u�[vUUweUêõ�ß­W’ Éàáý›6Þ E^ìTÞ%ØÄ=ØŽ>é]ZÈe ä�àÊ à ¶`«½Ú Ö`ðÝn®¶˜ÞV{- Ö_÷µÿøÕ+�]®]¾]Î]Ö_1Èa�åP¿ `â\!6�%ÙÕ#N`£UâÅeâ0{E^ä†}Œ(.D¥âеâžÀ`ïÝàöbòá0c‘-cÂ8ã,[á¦qa¸•[º­a»½áý=�þÝÙÿíÙ$ûY>^9Úå­SBÖŸˆÞD^dEnä–xd÷ˆdIV VŠ>s=‰‚;˜{ƒIiºC9j®æC9”Ë¥’ä�Ž5zfg'QgEdçugœ�g/�gz&Y{¶ |î}ŽgµX¡ ¦a€¦Y�f ‚ŽŒñÚ …^è†~ê#¡h ±è>ÃhuÓè"áhñè�iÁé� “N”¶•&gs¾Rt†igôVˆ é‡±iœ&„zFˆ{¼|vÎ}ê?6§qWÝ•‚£&ƒ¤žƒ¥Ö�¦N视jø�êQ潄;`k:­�#ñê¯>'mÖ¥ÇY£ÉV¸³fé´fYå]^¶¾ �+b?€ë.Ùëé˜gºÖi»æi¼öi½ê´ê-þç™lÿ6%ì˜(hÐ “cNTÇNÈ>FØK·Ï¶H‘bÊÀìÀk¾ é+ñì„íîXi&í&1m#XçMmçˆyçv™ëº€»æ·¼¾×¦Ý–Š¿ÎÝÀìÂ>ì)n8n1In‚\î^kîynH†é6êÞæÎæïŠÐîn—oñF^fm|ï´€íô^ïXkï÷Žïiì€þíûîÑoþÿJo®—/føˆèˆ>l ‚ê^p «ðpõîÒÞ�ÓЙ.ïš>ï>ë¹Q�XŒ­È×|åç¾žï¢Æ_ûn¥6q AñŸê¤h;冿dd®�ñ÷° ÿ‡èXs6¿ñO™�áñì6OÝú�p!ï˜ï"?óö’›Nrr.&‡5'× (wN)j7jÇrÃÖòü.î.÷r¤óÿsƒ$ó9p")p4Os6oslyóQ‰ó°êñíFk<§ˆ!Omòöó#ôeVò+)t>8ôHô+XôÝ&êÞ¾òDî†ÚrJ¯tYqAJNg:…3s#™qQõps‡spLõNwðUíVOg=oë€} —B@OtOw['t iòÀxòD÷uùöÒ*÷mÝîaÏòbŸôcFödÿòÈó;(óO—ñP§qj¯öR¿öSÏv3PuåàîÿÿöÓ.³>ÿóÙHwuôÔÀu]çuyqúñ{/ñ}‡.÷÷ÝPö `ö�ßv/ø3¯Œ4_€„·vÎÆö×vg§ón‡pµ~épg‹k#�ëvÑxt_÷ŽowCwD�w¾fô‘wô’‡tüFùcWyÝÐ\ÍÕpª¸ÏÅyñ{®š¿�³È‚²�;¯íŠ0<ªI)8ª¬ƒš¦GˆAŠ)"”õž5bûÏûÛ„Â]4‚gβ…Š³W ®wl¯¿Z°?±'²?'³Os´W µ'À�T·GG¸/¹O3à ‰°{ŽÇ{AÒûîàûq]œ¿?¸ÀG1( |•ø‹Ã·°Äg�ÿÅOŠÆ—êÇ_�ÈŸü‘©üª¹|Ïü¤Øü±é|ký|’ }÷ýQ)ýº'˜»€¼g�½ÏŸ¾‡}îéüÅüØÛÿ܇9Ä&Å7¬`üß§äàþ�]œ…â›Ûýßÿˆfá`ð B2œã𡜈&Ò©hñáÃ"6rì8@"Y±Òãd�*Wzìxá%™˜2sЬYá&N :w&éésçN† ïýcôÊĤP–jjô�‘¨o¦R%jõNÒ¤2e>}º` @bÇ’-kö,Ú´jײmëö-\+æÒ%dw%NœW‰–ìk%ëD1‚ï)l8îY° ÿ&L(t!F‡å$µx1²Æ–AŽ$iåJ–š¼¼°5f˼7�êôù“5𨲭>Ešu)”¦‡žF5b¹â„àÂ8Mòä_Á"nîü9ôènéB¨n—Þ›>÷Þñ[’ø`† KXã<ãÆAGž3¹òï‡&ægn‰ä>ç‘%Q¦ }`4i0�–šj¬YàZOÊ6[QG†›n¼Eõ ˜qÉ)§˜tzø!ˆgQW�à´Ý^ÞýØ`�G^tæ¡7Ÿz: ET{ÄYô”|ô�vù‰´hþÈÑ|Iš@`^;™ñ$w .ˆFWÐX„URhapÄÉt˜"·ÿÜ@!šy&šo�A‰'öÄ�Šà æâ‹å t^ YИÐzX•#`;Õ£ õy¤�žñWâ‘)9“9éô¤Ü…'Ø”TVi–Niù—x˜Gˆ‰™a¥¹*««ÒEW›ªÁé�œbÐ9ž�`éiBcÝx Y úG{†j–(‘'1Úè£Kz¤ZNB¹×¥bdZåœ&”eW[r9*¥žšj­š{®‡¯Îk^³úU뭇Ũخ½ôk°ðÑÁ#f�"ûÙI½õÖèÍFºÚ¤Ó^Uíµ›NÔénŸZ*¸âŠI.ºk—º+°«WŠ´²8§C/î‘+A{öŠod:VÄÿ/Fƶô/GE°ÁϘp¥Ô^ÚpWÚ"ÄíSÞZXq˜s¸1ÓM‹¨îÇ7¹Û¼%×9¯®*7Æ2F.ï;h¿GÒŒ’ÍFàüèÁÑòléÏSb+ôADeô…Y}™´†;½7º`Ñ@ƒ] ÎÀ³;Yåâ}Q&lE}Uñø‘#0ù[ŠY@™?TH!yxžG8)ÛCW˜ñãUl°:â~ð:ìÁäHÕ–VZ‰�i€`ºSJië­k1<ñàÊTk‹‘±<óð<ô|H?}{‘/09|k¿±ß€28á©mÁ቗´¸¾ŽC.9ån]®Xæ lÞùç¡ß4zl¥Ÿ¾ÿmS©¯¾Aë`»�Ìî>µ»Ôí^’»ÇðÎw¿3CðG¼âaè4È#F˜×¼ß@/zÓ“^õØ—½í‘Ð\Ý Üà §“òùAq�j\IRg=ìUî}‰ßü>º�ˆî>¤sˆé®€ºÇý/€$€ì^G;‘Ø.� Jó@Fp‚Ã3^L.h+åi0Îë >ÂḚ̀}%<#šNø½ŠÏpDi� GõU¡Œ#l‹ o¨9‡pN‡ö«þР?!òïþc⎈D*Ñ€L¼qžÈ�( eŠôƒµ€E2h±=] ‚õ¬Æ0Š1„×3#Sù!5‚O…ä{£ù¬€>ŠÀÐÿ 2a óˆC>ÒÏs ä ‡¨:DºîˆI$ÀQ­HúGw”dˆù@1âTp+Z<ö°ÊÈ�2šÛ % U)α’�¡sãàx¾Î1†ë;åÙ’G�ìr}¬ïçÃüqC뉩Èc&s™€‘äBž¹�hN“šZ±àȃÍl"à›Ýã7í8Î�B§œ‚s% ã˜>wÖ1rˆ™'æâ—¹{úòPûd? ùOCô(NØ I> qjRg"¨F=*C¿åЇZ3¢ƒ™h63ºÍO~“¢ñä(VÝ7�¿¡ð£m\!,[¸N9ÒÑz'�§JWÚËîô¥Áÿ,ä!mŠÓè”#<½�OTÀ•&ü9É(�ŠT16t©Æ¹¦˜¬*ÕPRu›VÍ*dµ*®®Ñ«çk:c9ËX¤¬&� JÓš–²Õ®n�©0mºº¹Öu#wEB^÷𕾿à¯=¬`ë�Ô£-u"‡uª` ªÍÅF®±à¤hd“«�†ï²¯Ì¬XeÉNÏ.à¬`‘v³+ZÒÚç´sbjUËÚ×u—§±LPûj[Ü v·u[* â+_з¾yÍ«p'GÜâv±ªÈU.€ËÂ\�†U¤´l§-ßÉÑJ ÁήvÓÊ]—"á‡ßõgÜ:L¹æ”¼îéOÑËWõþ•½ƒý`ÿa'‚-ùη¾ô½¯Oó[Ñý׎á 0ŽüÕçªSºd%©Y×Â`7ÂØÝîZËkaðµ¦ÿï"ÛjÞ‹!½B]/s«[Â*5++f1 \übËx¿ ¨±oŒc  Ínn@ü˜Ä@>%v&¶ “Ç¿ñ™ø3 S èA Ð†v¢ÝÑHÙÂvNÄm ðh/Pzu`I]2­HªP¥3"ñ…,bã„ú7Ñôä'»ˆ�U³ú±k~ušÜüæ8ã“‘t6Ê£ñ\%=Û°Ït -hCÚ8‹V‰’ù9‡\+EÒv¦´,=LkúˆœžŠ§êR�ú4¥¶Ì©¹ÿ¨A«²ºÕÿ…5ºA$ë6ÃYζ~i�ï ˜<ïaϾöŸ…=lbÀØQa´i+¬lfOd)“®ô.ý¸LaÓ×Îö¶CÝí­|Û"áÎ`É]n ¸:Ý—κÐîZ ‘×ÔžzÛ»Ï7x9Ìõ�~÷û4Çþ…-ï‚;;Ж¶@¨Ýpk?ÜÓ§ÐÄeRñŠDó“VíøÇ£~¦��¼¥ï>y¼!=ï]×»×¾†9ÌIsà®õ®Ê þl„+¼ w8§!ÎÎo'=&K§CÓ3þôlJ½ïf¢:­­^rdÂ×;_9×[Îg°¿\ìü&»ÙL‡¤½ç?Oø´^mÿ^û r—#Ýë~÷¼�{ïjö;ê¡xwþÖ)?¼Šïu—3^‘Ù†<²s>ðëÝçlÏ|êª÷N{zÆÁ�-b²º“aôbtºéQ™úé#fõ$7¹l²®ë®ðú}¾¦ão`{Oãç�Þ½Öy~ðhc>èÁ>Ñãnô¹WÄd ¸?þIý›TóŸyÑ—>õ`[XŸàa_lhßÖq_×yß×ÕÞÝžÍý[î�L-ïYÞï¹_ð ¶ÍèÕß‹à_þyÛþõÿýßU   ¦E¶U]i Ê=ZµœJ÷]Nø…ßøuFù%[VÞú]¼_ÌÕ\aKŠ@{ØŸ‚Œ …˜‘€ žàÿ­ ªE Þ Ö^"Ì ˜Ô ‘5Ø : AàVÜ´Lž¦_ôÞåµ]ê!Na—%E†à6áFaª¡`þ¡Y\!ëÁ`Öy¡†€aŽ!ØåàH”_¢Ýþ`ûáûÉa Ð!oeÅŽÇ2!Œí!ê]ô"!ù", ‘ÿ™A° Áƒ*\Ȱ¡Ã‡#ÈD¢Å‹3jÜȱ£Ç� !V I²¤I…#Oª\ɲ¥Ë—SœIÓ Ìš8sêÜÉSÄÍž@cJ´¨Q‡?�*e˜t©Ó§PM6�êt*Õ«X³.´ªu(×®`Ã.¥(¶(Ù²hÓª]˶­Û·pãÊ�K÷ €»xóê½»"C€QĈq ð�ˆ-(6øñ”Ç� HžL¢²åÀ�»hÞÌ ³g C‹]¨´i2¨S÷Yý¦µ‹×°[Ȟͧ¶íÛµuèÞÝ¡·o¼ ‚ÿNüˆñã’+WÀ¼ùƒçÐ1HŸ¾·ºõëØ³kßν»÷ïàËÿï½ïßÀƒ N¼¸1cÈ‘'K¶|3ŠÍœ=w͆œÿ¦¦k®ÁöÚl´á¦àn¼ùÖpÂ7ÜqÈ)—\sÎA÷yvèᇠ†(âˆy™‡Yz†!6€b¸÷|SÈ7}$Øw~]è·_¢ €d¬ÖGkox ‚-(¸ ƒ:8øà]Á% á„aá…* á†$véå—`†¦‰è–"{-ºcŒ2.áæ›6j çœ<ŠöÁ�xúø�AX¤‘*¨‚qj( ˆ&z]”SþQ¥•W&šè”V*楘fªé¦� Š…©È¢‹f¬)£oÂißœtÖ žyêÿɧ�Dé‚ ƒâfè¡’²°h„>ºå½²P©¥œ&«ì²Ìjç©`f†Š&©¦¶™êq²ª�«¯Âú�žrÌê§­¸ªE )ضk¡Åþ*å”ÂnYì±”6kï½øfú,¨ë©8¼æ`Çp-¶«jË- Þ~«ç(dä–‹nºµ­G»ß;ì¼ôæ+òÈ$w¸o´ýª°À0<ØÁ:2 í¶Ü6 .ÄCH,ä<÷\n«».ÇÞy,o¯ô.PòÒL7mÝÉêù‹ØÊì2Ì:μ°ÍGŒÚÄ«õìs¹„Ý+xFkò±N·í6ÉPŸé/ÕX]0Öúi=š|÷ÿ͵�8ë¶Øü\ö®Dw—6tk#ûöã�'·´sS�Ç嘻lðµ1ë-Zß~{{³×}NLxádëj¶¤h÷ú1Ò!G.ûìcúu"ÊRÿk9æ—kŽ·gž‡:ßø×`Ÿn¸êˆŸÝ±ëGKš4íÔW/¢Øû•� Ü÷sîàK]Áøäšè§?¼c´ïþ•ìÝôׯà£8ã,ÿsÅ"à¿õ `Ó°'íqOÞÓQø8ò•Oa£IŸú†ç¾÷]i¨Ÿýpƒ¿ü ƒýûŸGHB{ЀÝãÙ÷>ŽÏ|0� úÖWÁöÁƒ¤ßýªäÁê†q½òÿJHÄ"jê„~9`õú†2T kxÃ>ÇIØ!…z ŠÐˆ` ãˆ�¸½N`…Mô— +°°(Öð�c¨¢ ƒE-‡‹V$–‡(Æ>ú‘€¶O y$è; :L„&ô› ©Ý@Ò’Žà¤(%©‡–ºô 0�ééà—%-E/Q”ä…˜S‘úô’(M)ØVÊ-—¾4¦0�é•júºI~ñ§P�ª^‚zR•ºˆ¥F…R“J8šf©©8}ªTÇúÓ(EI”|ªQ·z¥Zˆ©7ETOÉJ×�š58h’ öÊ×Ó�Ž­nUŽGyJغ–¡wM@^Ä×¾úUl<ˆ¬d›œÁv®‡Íl,»ØÔ4v¯�…¬d#KYX–§šM-8kˆÖº–OŸµAh{6ZÒÿvõJ§Å¬jwûGÖº¶µ°ýìlyØÛZ(·bå­rÃèÛß·±Ã�[á*Ï�v¹Øeî] \½ w¸Óý*B­‹Úìš—ˆÍ}­w¡ Þ­R·›äÕíyçÛG!Ö~=ÔØ/ãÊ,Ò÷¿±´o–ðëAý^“¿Np2Œ!çÏÀíD°‚'|I7ÇÁ8ƒð@¹Dá¿RˆXÜ&Š%bÿzøÄȱ“DLâmšÅ0†eˆ·Ùâa¾8Æ8þ㌇YãéÜ8Ç@㎧Ócéü8ÈH&á�¥Sd 9ÉP¶Þ’GÜ«;)ÊXà”›üä,{ùË`³˜ÇLæ2›ùÌhN³š×Ìæ6»ùÿÍp޳œçLç:ÛùÎxγž÷Ìç>ûùÏ€´ MèBúЈN´¢ÍèF;úÑ�Ž´¤'MéJ[úҘδ¦7ÍéN{úÓ µ¨GMêR›úÔ–€ªW½LT¯yÕ¬ž¥«‘ kU¯àÖ¸>ƒ®wÝLøú×ˬ‹°‡MlŒÔ:¸Îõ®uÝë_û:ØÅ޶´§M�c'ûÖËfv-�ýìYRûÛàž‹µ¯�í34ÛÙRH·ºÃÍîv«eÜÉ.÷¹­îu»ûÞøÆ ¼•½ìyûºÞéηÀ®”üà8ꂼkÙ0€K!'¸Ä'ž“ƒ#G ßdÃñ Püã g‰Å žðŒpãõÿîxÈWÎòŒpÛ#?AÂ…@óšßáæ8G¹ºUÞòžûÜ Ë|yÌg^sšã<çÞrxÇ 8kÞ�ÛCÇQÑ�~ô;è<ÝKÇ^Ó ;ˆ®{ý `»�¶@ö²¯‘?QìƒÖ¾öSeT;Ç^¦×½¾ÌeÆ]Ö[_ÚÜ»v±Û§ìf¥hÒÎö¶ËèíÙ¹{&÷>ˆºÏRñLÏ{Éßw°�ð[8{e¨ö»ý”¾ä±ÇxÇgrô�üä÷n£l±Jóƒç|á=ðy Á½Örß»é ˆzÕ“Œñ­OØëÂ{þð Àía�û¹ï{½÷½È€üÀÌ öÅ—ýñåƒxì ¾ôÏ�¾ÿôñEýÖ †h×>Ûk¯QÑã~–Œ�yÌ_@ÿúKàþ¼WõøíU~�‚®b|ë‡|òÖ�z '#Wö‡ЧûÇ,ýgÿÇ*ˆ$A�7€Ü—|Xˆ# hq H÷'ù(�¬|Ø*®"JhxX€Oâ�µ–p ‚7‚/P‚'˜‚™²L W}-('üa¦ƒ³g`4ØxAP…88…›¡ƒ;8‚>ø€(„—"„8B„CHXJXxLØ~w…RH…Sh…'ÀƒY(«Æ…—Âx WvX'Y§óF=”!z$)^ȆµUˆ<[!�ˆŠ(JeЈŽÿØjtè%vˆ#x†FÈ#{؇5ô‡ÌD‚8Kl¨…˜¤XŠk¤ˆ‹6|‰‘H"“ˆ•H.È™H8~èA€X,ƒH…£XФxЍ�…¬ØŠ"òŠ›‹³8µ(6·˜?¹Ø+»8…½è‹ØÃHcŒ®¸wwHvyÈ#ÑõŒ8�’b#¡Ø,Â"¾ø‹Ä‡�ª$ÛÈ�Çè�”Ž–H3ý1Ž›ˆ‹�È?½‚Ž¡¸ŽŠÑŽyp�0��óH� âu%˜pt³0ÑUS=Vˆ"�øA7i‰�.%$|¢1ŠÂ�â�÷‘T#‘ÃE‘d‘,€‘›¡‘Ù‘ï¹!ÿ¹:$Y’]÷�8‘Ü2‘YR‘ü“š!“ëH“D‹-’ò¨“;I&)˜·@)cX¥õ^Åôr62uB€”ìØŽÙ”8ù”Íã+Q9SY•WY¹•â%O^i`)–I–5y“}�“i¹–lÙ“÷ç–)9qi\Ë1—ÝT—˜q—T³‘JI>L N) "‰(€)Sé…)�!$Zš¢)Gö?pš¨9„€Ñ¬ –Jðš°i+1ƒ�Yé>1Å•pY™‰›I��Ÿ¹¢9šŒa‚š©ù…«ÉšIМΉ$- ›:B›ch›0…›º¹›ÖÑ›˜ñ– œ}0œ¡ÿIšõÈyšª‰¬ÙÎùœH"�úA�Hh�W€�×¥�{Á��á�0žâ©ðó3Ãrž?�žëÙžÍ �ðéòiôiŸå…Ÿz¡Ÿ€ÁŸþ)ž±õ3ÿI Êœª Fr: Zª˜Ï‘�šŠÊ ‰¡Ÿ¥¡âɡʩžÚž j "Z“µÙ>·i¢¹yŸ)zŒW‚eÃàY•Z.zžÊžúž¯Ñ7;º”†9†1å>¸9ò…ŸEzG0šKŠyMŠ+ÿù3QZ¦9j¥„r:§0´¥í³$ â¥É%¡a*c 0ez¦€—¦‚²¦åÒ¦SŠ °§bÿ3§t €¡a§c€§»¡§|4¤DºwFú)ƒA¦*¨eG¨æ"ž?s1š¨³±¨|s:Ž*§u SîC©ºa©˜Š}ú§¨.ºL£NJªcª)€ª7꞊Z¥­§¯«W0«¸aJ¶z«�«œŠ¤€ú©½Ú¿ÚX2:œ¥J¬Æ*¥8J¥.À¨=óªà¬ÐzÒ*_º“¦wqš!§ dš³žë¹Œ¢ñ3šƒ9žáœuRj*žšc�ÈÚxBŸÊ±‰3¤óJr›a¯áƒ¯.S¦üþê2ÛË#[¨ë2› ²¡°w°Éá°Îs«+s ÷Zšƒ±—ÿØ[0ËÛ!;ªÃy°í˜°Œ±°> S «›¢/‹ >†±‘6«�ü‘³³³={„…P°AK²Ck²-€² ²ñ£´-‹©M³3{R‹  V;XÛœ»µ"ÛµS²I0bK¶,Ë:Ôš¶õ*³[mÛžo qs›u˵¢)´¾H´f`´cSI«K+¡Ëuƒ»ž t¸YË#}#(ewµ—°t ²v ´Ç¡9sZмê’*G‰Ò�œ;KžÛr ºá#º«ë*¥(§+·©ë±Á«µ\{ »¤8»�Q»Åy»5˜»™´»½Ëš¡K�eº0ÃÅÿ˸Ç˳ɛ¥ËkÍ+§²«­´+«64½ˆ‚»øÙ¹#ç´à»à¼ŽË-ß¾�û¸w˼¸á¼y½Œ!½ò·òû_ÇÖÀµR%UR9hqö‹¿¹£¿Z‹„ýKv¨‹ª»¿6™U?¢)À·AÀlœ¹Ôë„æÀ0¼… Á$5ÁôÊ»÷«½¿Ë½šÁ¦±Á[ÐÁ{8Â%Œ¾¬¾Ï˾Ñë¾q¿ýU½ÙµL%X‚/G ×¶PqlŒ—ÅåörYürßxM4'°¡VG…TÄšùJ�¯é™ÛúFðÓ(êj+{X%Px‚¢†𺧪EÅU,W|žY¼ÅµÖÅäÿ–m`|mb|�dÌBfühÜRlµÆm¼Žo œq¼HBǯºF¶‚Çz(|\(~ŒñªY‚\Å…Œœ‡ü\¼w^ÌÈÜÆÜ6ÆeWÆrrÆE•U—L¬™Ì"›ü��\As<%ê*ÊFBÊl·ÇÉÑÇÏ1­ØÕÊVÌmoËN1ËsWËËörküȰˆy¼¬¾ì*{̦:ÌŠQÌýyÌôÉò0ZÀÌâÌkÍ Í@ÍËeÍ÷÷rÙ|mˆ kŠo¶ìláœË8bN’ÜË””„ÃV§ÂÎàÎà)ÇWòó\Ï’uÏ.4Êyü̦ͨ<Í|©=KƒLÈØ\CÚ¼ÜÿìuÞ¼kàL¬â¼Í@“ì*)Z£uÑ.Ón¬plBÂÑò ôlÏø úìüìÏ­\6òÒ]CVÐÕ^}Ы†ŒšñÅÜÖÐΖp3Ã" ôÓü]…HÔcÔšŒÔœ¬Ô«ÁÔÊáÑN Ò‘%ÒDÒ¥§©¼Ê™•Õƒ¼ÕäÕ_-Ë7ŠdÍÐÄ[h­-j>l=n][pM0rMÌtmÌv=Jžœ× Õ#ÝÌ%½Ï'ÝÏ)ýÏ+m^ˆíÊ1½ØŒm`­jéÙ¿¶Æ”ýЖ­k-Ñ@­Ùí…T�=ŸÝΡýΣ�×ÉÊŽÕ¯1ÕUýÚW}X/m#5ÐÝÞÿ àÞotÛ¸]j…é˜púºÞëéÛŸ…ðßi-܈±F?�Çø]ÑeÑ2¢®Ë�ÑÍ ž|bJÒ=§ÔíÖÝÚVÛªµÝöáÝßÞà=Þ·Ýq×,çMé�#ìÍÞîÝXñ-ßÁm*bßÄ�ßx¼ß[u*þ}ÔI]™©AàÊÊ©�Ï«MÕ ŽÝ žZŽÞÝ>á\]á~ÞŽ¾ÞÎW!ßóMâõýD'Žâ*ŽÜýýªÿ­ÑÛ:àLRàrzà .Ø(MØ*­Ê€üG¨‡ÅY|mdwp~ìMÄ-õ3tpçúc¶jù%ÇFÃns…¨Þë�;ÝK¥Qˆÿžè{h+�YŠÄMç¸ÂvwN,™?÷keçDÜ�‘•|RS ê¢.Yž¡…ñÓ„�ꪎ'“®¢®P—´æ†|m…øæqî9.eçx1&}NÀ^[° ›Iè=lè…�芞UŒ>“ŽnΑ¾v“Ž›—îk™ç›í.ÐécøéYbˆ‘幃ꪞê¬~ç®ê°nI²Ë´^[¶ç¸^çå2éy®¹˜ &¿ÁÁ>ZÃþšÅ.5…¦¡ìˆ¾èFÒè¤øè aï�"éwní‡éó¾í°Ñ³WàŽ!âÎä.5æ~îéNëí^Ik\ë[çPïpÿ ët�ï#Éçµæçÿ.Y¯ï/ð¯ðÂ;—ã‹/í‚"ñ”¤×îÙ~ÿ_x$5õñ!ï/#¿êwÒêÉñê õJ¨Çƒ-/ï/ë˜ë÷¾ë>¤ï{î%ý^R;Y=ÿó*ô‡Žð±[F�HÏí�¾ôÔ>ñN_ñØ~ñ”ñŒ±ñßZßåNÜçŽî_¯îaÏîcëï—IfO¬.ó2?¬øÎëzîë9ì#WˆwO�ÆÞžp¹÷ÊÞ÷Ÿõ÷�ÎLOñA`ñi/õ‹Oõ�oõ�ϑϓÏí•O%ò)¯æ��Ÿoª¡¯öøð-åèÿ"(§ÿö7/÷ªæ“øqp©Úž¯¿Ž±ŸÁkbû�…ûÏ®û3OøPíÿÈJOõSßíÅ"SpÈÁ) ò`Ø�ÁCˆ$NÔPÑÅEB5~àØ‘ÃG!Œ$ ÀäI”)U®dÙÒåK˜1Qž¡Y³ËMœ/tîLÑÓgÆ[¶\ z¡âQ 0”Âaê¡g¨t¤¢Ã* ¬2µ® ÐUÂWœ8OŒmP6ÉY´JÔ®µÐÖíĉh•Î…QÈ®B…6ôîå«Ï_Àyç±xq.S¨Pz�JGÁã‘%KRÙÁe¡C‰Và\¡° 3¡,Xš Þ„@BŒwÀÑ‹.4nìÈñ#ÿ‡� H–ÜÚÛ÷oà3kÒ {s'OŸ=UóZÔ(Ò¤K'Ž:õ UXY×Ú5ÀW Å»Œ=Q¶Ú´kÕº}ëZ.ݺwQ÷¥opàÁŸᾸñc&°² .s ³¢:óLƒØB3c42í4Ô–cí!×^ûl¶Œj³ $‘v[€;K4€áˆ+î8�’SNµæŠ‚.:˜â�º£ ;íNtÉ;ðÄ#Ï<ôÎRo=ö,Èð=ºì*µ)êë뾿#ŒAäëO ÿ �2Ë0‹ñ?sB MƒÒ 3„ #=üà¶ÜDÑG<óDi>ûLñ ñX|ÁÅ–ó9¤ö»ÿ‘:¯» «"•TO Á*nH³ŠçˆZk®;R¾bek�@ÿ¤˜âj¶yæ‰Ðyg›m^n9uÕuÐA!„Xâh!fT×Fùpúé#¢–š>ó°ÿzÓ”³¾ÃÚÛn“L;ÂF fš2Žál´3œ¨h£�v›>â–;¶Ø6¥;Kºlœ`o^a� ì°†8âpNÀb�¯Ó�§£Ž¾NOV*땯hÙe`®Lfœ{®Ùð�yö|¹Mƒ†oèЊv;ièÔÝûõ ž†Zꨩ.Ëj°Özk»þèk¬Äû‡²1>÷Sµ%bÛí·û’{î»í¾{i¦^ï_ÀY ÇñÄ3^<ÉÆM ò$%‡�r–qİۛìœF»Úõ¥jW;ÒîxGßqx,ÙÎ�±ã yXó–ÿ·çAàn.�ݨëMÈoÈÞö(E8Ã�/|+ã.b#k¡�=êcŸå܇9ÍáO„¢ŸýB—8ý©‡sñàèDÒ…€±3 �`»àNwZãšï&XAâ]ÐxÇÛ`™Gu�°„±9a M³ÂºOÝ‹aŠf˜± ÙÐ8Ä‘ÝÂC•µ�:ï â]4D&Òˆ;C¢jJŸ>DR’M|"ë5@�¹É µØÀÝu±k_›1HÆä™Ñm�¤‹�4Â6òM…Ø ^àäè#:~ÏŽw¼XÉwCÇ�¯/‘S ÊéÃA1~)"T"‰³û  ‘@aå\$9É&ÿ2Ï’ÔÂ$ì4ÉÉ�x’�êq`"AR†Í”c.«Ø*]ºŠÌ¯‚U¬ÃifY/š³´jl­Žµ¦G)ɶ¢ÉU)N*©]Q N½Ú€¯¹+æäRöWQ6{ÃC, »Ø ªo.#Œ¬G'KÀÊ h©ÚÃ,‰ d ñ„�µÒg-ZaÚ@¡IbhWц6°naµ5i­3ÍJ1^^l¶ê1BýëÖÛâV·ëê-îš×ž°”¯€Œ©L“«­å®3±¨üit‹K"dXÃÕ½æuaw×»ZVxÝíM÷¾{™ð†�¼ƒ1/z¡²—õ²§½ }ïÙâû+ˆÔ7‘÷�X~Q°ßµø÷¿¶õ ns[uñ¶®ÿþ-'ƒ;\#·w7…°N™+Æ û´Â�*†5œaKÒïñIE,6oÅÄ'NñóVLP×è‘�¢U¯VÙËU÷ÖøÆ»�Ž+úÚøÈjr\d#XÉÞô-^�›à½.øÂY“2©œ�œîs§Í}î–wH[¥|Ì”,ަXæ8œ™©iFÉvÄhul¸EJ‚‚8“Á9Jn3�ÁÔðk`—J�æ)‹¹ŽÇ4¦ˆLd¢&Bâ2C¤"Ø"Bù’AZ#…¤6‚“cë Œ ã¶B¹­…ê”~‰ëfwÜýîA+a„- w½µ-'y€WZàw¿ ðo€³›Ý™Ö4ÿ«]âjXì³.¸q ]£†×eñµ´Õ l¾»ØIÊ ¶•2f;[(ÐF�ÅÕ@mkïÛEÒö»ýèoÛZÜä67ŽÐ Nu œï†7tÖx‘zÛÙø†Ð¾ûÍo€\çG³ÁY‚pÍÅ:3 G�Ã�—ëÝíúh½¾�É1¾�7ÀØçòøÇC®±g� -&G9V¯}¼l#Ûåò¶OÀ=s4”Û ç.sº¤ó�ó¼ñžwÐ[poåÛèGOú¿ÏôU;ý$P‡™Ô…BuQ)åá—|,Ý&ÞƒÑzSX4ÏØAUve3û«g}ÚÏm‹·�Î{±VÜ™6÷ÙÔ½'P»ÞOÿìAù}2€üà}^TºþðCO|Ñ'tt¤7þñ™nºäS‚€&d_û\à~÷gdd!`>]xn¨[Óx·Ï‡^SGZì:5ÅÇàã%!ë[?ò²Lñ}Ôž‘ÿ¬)@ü=jSíÓ>(‰¿qË»rû½àù¿Ó¹â›9¨@ @lŒÆ�9i<X¼~ûÁeá“î©>뛼̾îó>è?ñK‚«ó*ÏÛ:Š»Ñc¿ÅBø«±ù«?û»×Ó?ÌÑ·è?Ôù¿ÃÀ$@1ÀLÀ[@ß;±ä$'ØB.lAî›@è°À tB ” ôA~A,ÁÿŒ<ëþôB.ø>#®%RŠÓªÁ΋ óp›Ì€ˆT�öóAŠ?‘™®»B"+#t$l %&|/'”($·�¤Â÷Ò»+ü®,Ì .ìB/,¾¿ú+1¬ÀK,C:8ÃÚðÀ9˜EZ„>-`C,Áèž|ºl:´CÜÂÃ<ÜC�:?ºùã ćĵ(D*ùÁ÷JD¥Bû‹¯G�H´€It�JD›KÌÄM„�_ôD´ÅÄB±vlÇRÜB:ü’T”©U”ƒV,CXìY¤ÅY "\ü]äÅ^T 9<À`|Á;ä«<„c¼&dôòD¡Äõ#DèJÿiDj„k¼¿ŽÉÆÇà?èð?@'ǶàDD�øCG+pÀulGvÌ9�“Çy¬Ç{ÔÀ|äˆ}äGÄÅ€$œ�$È_ÔJˆl‰ÜŠ$ô4·ÈȳÙÈŽ\½®„�¯œ�°4ƒ±Œ�²ü®³$Ç)dÉcKutË·¤Iv³ÉT´K tE9¡¨1ÐË~ÔœôKïÌVÌ$Ì¢1Ìÿ%ZÊHjJxʨœJ%¨JŒ¼ÊiÌÊj\Ä!ÌÌ×ÙL�èÌÏ MMº(GÓüDtlË�xK;`ÍusMU\ÅœÜ@¡MÛœ¾lÃeHVã–HQü¤Ãî!óxB8YÀ¬-Ð)  w¡N » .ð+Ð��z›±Ìˆ¿wSÌ‹@}�ø* Q~œEŸ`½MiÁ_C‰¿×À2xQI ܉ &¨Ñ_ôP¡ˆ¿§¡Åv¼#ðè“/Ù!R"Ò÷qEMš"³2+ð/xR( "ÞÜ ûìüTýä>þÌ¿½ùÏ PE^9Ðu·NiP�{P¾ŠPÿ ­ ¥7 ÍÑËÐè¤Eí˜Ñ-ÑÕ;ÑîKÑ­± À-ƒ…нˆe‚Ý› ­±�Å�¡å“ -RM=Ò2LRZR‹jÒ¯ˆ¦) Ž*½Ò,å‚-mÿt}Œ0Ó !S5Ó3eu 5²6uS ƒSò‹Ô÷¢S޼›;ÍÓÌØSÑ9ðÓTîÔÑ`ѽqQ½ µµÑÌSueGý MÝTÌARRRPU ÕRý�SÍÏ,]ÕVMŽWU€XSJP-‚[ÅÕ4ÕÕ5åÕ6}ÓˆÓ-ÀPwÓP8VH+e-fuVÿhåi] j�kETlUTmeTn=@o•Tp¥TqµTrÅTs=W"½Ò+UWÙa×%uWx�×Þ˜W,­×»éÏ.uÕ/…Õ0åWØñW[ Xn„5m)6•P„UX†-‡…Ø øPe­Øž0Ñ#AQ5PÑi%Ôj5Ôku€l%€muÔn�Ø…5Y>W;W è•pÙ—…YøO…P›½œõ �MU{ýY| Z}ÚYí×2X¤MZ¤XZÜiÚ ýÕ„ V9Ö†­ÓØ Z«ÝS¬M­U®õÚÅ`ž³)T)8ÔD�€Eu�F}Ôª½\´™Ô9¨Ôð¹Ô˜[ºR»½[ÉÛÿ×ÙÛ¾ �¿ÍÙHÙ¾,}å5DØ¡ ª€ã¢}£e\¤�ȵB)På‹ ð‹/´) d¤Ú׉¿ýô¥E±Xµ¨·Ñ…Ó�ÔUÝË®³Õ>IÊŒò=›Æ`Ö;2ÜÕÝÝí]¼5  8`^¤hÒ™â¥ÒãeÁä]Þh$ ç=èý7é�%—©ÞÆuÜ£È�øÛ^íÞ‹ø^° _¢ßuN´9ßô�ÅõÍÚ?m_z{ßшßù[ûY´m‚üŠý��þÑÿ½ŒN‰Ýå]»ý hb'Fà†¦&Þ– IA^ýTÞ7`Þשà!¸àÌàÒxn\ìu�vÿî5<ï52ð=ñµAòÝóQôýõ½ öU÷ Ô®Ô÷Êa�u€vÝ‘ýá-â!æÇ"v€#F‰$Þ'~b(Þ^à*¶âÆÞâ nÞ c1cÌ)cƒº›1˜4NŽ5º6Æ­7Ž�8î¼9ž€:.€;ÎcØã>ŽÖ?þÚ@ÛÔÕa¾ºßìCdE– ÿ�!^ÙÜM‰*ÕÔIžŒJnâKÆd)žbÞd˜¸bÎb ¾�)òbR.e2 ãÅÕ£ØXå ieŸxåz‹e¶™åZÖÊ[Îå]†a=–ág¥á°a�[ŽÛA.ä×MæHÒ_:æ_f&bg6bhV‰ÿ*%¸j–ŒkÆ€lÎä›õæ–gOgP&g åLj^tVçZµ^«Reè`åá a0áŽAá PafÆß…â†â‡fäˆv䉖fû´è%¦äkÞèmæf�~ *k²¦Ã¹0øЇôMŽ|óâX�_T¾ýÜÐ;åÐøRˆ|6Zë99#˜‘y¶k$hLa}�C=TºliP>Ü ÊŒ�ÒhG@¨ì£°=É·‰ý~$òÀò¨ 7múœ¼¥ªÒ* ë¦"ë²ö³.‹´Þ‚µ~Œ¶ö‰·®à¸žŒ¹6¼º~Øÿ»F‚¼Nˆ½þµ¾N’¿nÁ¦·ÍåPþ\ÄNì2XlТÜz{쿈ìÉfÇÊ„Ëf9dÓleålZôì±í±mÒJÕn`Ök³V ´¶1µþ!—©íž¸mçÍmÉØí ëíßn°ÒkÃåë"ñkìän�å.ìe<áÓÝèŽîydlǶÈæiÉ.ʶìŠÀ즀�Íæ€Î&oó>ôvƒÒ^ïxmo*xoˆïÈŒÙVûNA�ký~ߤÿÓàž‚áVƒâf�ã>½Hðo_‡né>¯‹èëÆìÖpíæp ðp8ï=ïY$ï(ñOqŸRwqÿ—qúfë?HAq××ñ9äYß¾ëò!w‹"ÿ À†ŽÁ®s%G›çNì'� )·ðëÆð춃íînôÐ6.Q/Ÿ0sšmWï2�לro׆oØ–oÙ^sÚnsŸxsQ�ó÷ÂçÐç 76­9 ¯ ÷så&ì@ð ˆðB�ò$™ò*'ƒ çî/p·` ­ˆçG(õ‚ò¾˜Ð¾ôÑžÏØtœíôÿô/‹øšñGõ&�¦/¹R,NÕÿ~õ-ˆõ÷©õ$èéÀ–›7ilzûï÷’Ýø;›'Øá2ШF^ÙîíÎó¶hvxvZŒöiG�j?ÿLÇvmçtíðô|íwR§qSï r�Ž6 tguÿmvwwÌ�wy zo{ÿŒzûïYîwŸðÆ x b‚Ÿƒ¯ìT¹ó° å,û8{Hû|_{·ù³·†{¹ÏpÓøy@°{Áû÷lK—øôþKÀ—<ÁooåÓxïà;ÎýªùÿQõÛ”püÇç‚Èÿz Ÿ|¨|—7{˜G{™ß|¯¿iÏÿ|[ }¾ø @g20}ƒ�ôÔ/úÕÿl¾sM�}V›}Ö®}Pßx°òbÝ¿c7Wür÷}”þÇþŽQy—A~3xy#j(èâ`‹„H2ÜâðaŒˆ'F¬`ñ¢…Œ7f$àñc��F’)iòdI@*W2hé̘fÒä`ó¦Í9:çœèéPŸg†º)à(RJ—2mêô)Ô¨R§R­jõjÓZ�påâõ+“°b��}8å,Zj°Ý™â­OŸæÒýbWÞ¤P1`àÚõ+`Àw�œðp b:ŠoÿîÜIֈƃ’]ˆ|ÇÀC‡66s^ã3hIF#.½êÔV³þøÑ¥Ë ²g�®�IJå?ºwãÌÙxÎãÇ(ÉìÞ]à8ò1Ê—¿hî\ôè¦SÇ++öìÚ·sÇ®µƒßÀ\ÄŽ-ëmÚµmu¾M·'ݺwó�Êׯñâ->œx±o�=Ùd”…ef™qÖ¡�VG¤¦k«¹æl-ÍF›m·ávGqºõÆÁos 7\ˆ —ÜrÊ9÷\tÐQW^ÝÙx#Ž9Bõ]x�‘Öcf¡7…Z°¥€[p½ß\v}a�^OÝ×£~_ñ7’K(Fc¿ ˜Q�2�ÿ`f[,¸™gŠ6Z„¢V¡…fÈÀ†²uè!n)ŽXâ‰(¥¸âq-ºøâ 1Ê8cÖé¸(£�ZÅã_€ýÈD�ç Yä‘Iº·$“NBYß^}QY%WæPi[v) YNVÙ` >t¦ i:a„Á9À…ÌYçw~bˆ{þÖçI*è„j(¢‰Öè(µÕ: i~>þXéC©’ì)“xJ_ö‰)©¦f©j€Žµ f�°^V&­¶††k®íÚëœV<°, °0Ã8üp{í wä‘:X|1 0묡2X÷ñ´ÖŠ<2wØŠ7)·ÞbºÞí½wÿB¹ç ¥SS²[¥»¨þÇe¼:}iA˜öʪÙf7­ïƒlöë/œg80Áœ°Â /ü0ħ01Å \Œñ²‚rl(È“|6ÚSñµî¨^•gD™ÝžuÝ]+ õ¦'DGWQn”M•ÍÙê§á…fÚΫ¶÷³d µ 4¾EÝ šü.ýï…E µÀROMµV_�uxsMñ×g¼1¡}÷ýwÚ±ËÎÔÚøÝ<�æe†ÝGØ�·O{Ïõ:È€³M*áj>âZH¢¸)0ŽPB�+(ù Hfy¿˜»¦¹Zœ[á¹ ‡.:é¥k}zÅ©ƒð>ü¬¿èzQ°Ï~?ÚµÛ~ÿrîp—É{ݺ¼žÏÄ3›ÚŽW¥ä-o̓ôZö–é¹ÀqÖ›Õ™´·¦$,�iêø >ò™OtHŸéPb·Ôé~ñ[ëèg?üÑÐZúÃÿ(¥;!M¡w¿ÓZð Ã·ú/�8\`á–÷ÀçiŠ‚‚Àf<£Ò¨Fúù­ˆ5|££nØ6Üéл›[)6@½ qxDD T‡¼$n‰<‹àâæ4ê=Š÷ºÞ)w+¥u�! Á¢´È9‚΄(\Ÿ »ÆB2–ñŒfTãeèF8²2Gr¼ÝÛâ@ß ÿˆì£ÿ¨(#Îñ+ T"â ØDE6®zŽš™2(É}Qri–\&5 5NRÍ“_eE9Fšò”¨”gØÊqÞ¨ æ<§xÌ Îu>¤îÌX‰®p…ˆ½,ZH¡™Rîy𳟤úŠÁx P‡¸Ó�Ã)B*Pô¡¡Jx(DÅC‚‰:§ ¥Uò’¡‹\ä™HXÉJ¼ Ò‘ÚmK[2a‡ƒ·nÚ¡Dx)LcúÒ Ð´¦?¸)N Ó�ö“œ>ÕÑ9јu²“ ïT<çé²÷ØSŸNÑgúéÏr! Ý‚EšP„.´¡}€hD3QTÔ¢ ÀhFÕ°QŽVÀ£ ÿUÉHIÚ5“*¥àS©ÖXêR™òµ¦5•*?wÊS~þ´°6 ª9ÓIT3´ó¨+J*=™Š(¨>UŸ€EU«Z°…Õ (Ù*WêU°>T¢mŽYÏz¦´ª•#lmë3ß ˆ¸Š´¤tµ«æð1½þ†¯}õk.+X�öÔ°ÆÍÎe/Û±Æ6€´JX¬ä±’rmk«ì=/ë¬p·»VåAgp'èvµ¡½ë� Ò«Þ±–Õ¢y¯X›>d™D¶^õjúèJ܉”+í¦oeJá·¸Ç=pU’ ØåvֹЕn{¨KFëò»HÑ.¡ºëÝÍ^Õ¢ã]lyûp^º©w½§}Aÿjá[ù’޾%ÉØ}šßÛŠNÂ. 0Ž};`ÀwF0�¡¢`©2«îtðb!üÃ�°ð>»] �à»áý0QC<â#”8½ìE­YUß´Î×Å0ŽqúºPþª…”9~3Lw,Õÿ8Èv^Ê�ûYä‚"™¨JN“ßçd((†FÁ”5¬æËëôêB·Üe|ù -¨˜A“¼2Ó÷Ì÷Mó¢Ùl7ÃùÍr®ó�Sý”<ósÏG&탕ºdðU—ÂN騡�’èî.¼Fv§£Õ i�JºË•¾´;3ý™M·ØÌ€Šq@­æÅ¡ÚÖ&u©azÙSVÕÞ^5«]ÿÝ\X'YÖ€¦õ„mÝ\çz×Üíõ•;Ýaó Ø%>¶@1­bMŽÓÈò4~I§_j[»ÚØÎö¶=…»áJa5ÄÝçuþ9Ð prÙØ}hw�Þ¿¯¼Ko{›˜¬ÍAv” fcÍÅd¸ŒNW‚üàÙfxTpîpoC\âäö³¹-Žq�iÜÐ÷¸‡CNÔ‘�xÒøæ�¾áËo5ø»O0�¶ÌMJók“áÚ,·°s‡÷ÜPÌ�¸:+ŽnýcE×u†©ŒôF+ýÑ �tÓ�}b”«œåsùÕg¬õÞÜà]÷zÂÁ¾pÅ�½ñeJ"ß…�¸¦6 YçchB“ÿÞY›…ø<è) úÑÇMò’MLÒG‘ô®·ü² WˆÙ7pe € ro�¡œ�.³/„šÔôûß˳øW°›Ý† üå�hùË/|øšûé³à;ßi<öGöø3˜žò�= 0OÍÏ„óÕæ+èC?zÑÇíN¨‡‰ê)Òú×�f꿯=¸p¯{¼ðÞ÷³¾ƒ4�ñÉ_%Ÿó Aó ôIõ±@ö=àÙl_÷A@åÕßgˆŸ�Ÿ˜_ôÉTú}Þú±_™¸ßg¤é¬Þüø%Ïý-�íé ìÞPøð hà`× ö. L5 B V‹Jž÷yøa rÿ ú} éE^ûuÈûÁAüMD ® ìÑž æßûLŸ öÞ\üžš¤OÙ�R Žˆ:_!jÈ@Rà÷Y`ø©S摟z FáÚF^¡Dd!² Î ~áþ @ÿ�áÿ9ˆ.Ê”õi aRX�Å¡'RKÒaä%!,¡ŽßLIÆÔn@vA ‚Ÿ b º“ë©à!na!Ê,"€!ÿÍ $Ö`hL¢áTbL]bd¢&RŸ“uâ'F£Ž„"÷Õa&Áå�b¦¢Z¬"L�žO¼âCä9’`hüÞàE!Ú"ýacì©Áïñ¢/ãÇ” ´ÿca #L)£26£3râpI£@Þ5Nà5f£ì¡¨"ÝXÛn@8¢C�c˜#h £Ã¨cD¢;®œ.Ê£þb#Z‡=¢éœa×ð?^¢?Nß3ä@Ƥvá(Ú¡â!òaCžŸBdOˆãD–#:FF€F²;âbG"b!ŒÄrôbHÒ#I2É=ž$%¦¤%®äw´d`É$XbMNžM–"Njcîd²âçE¤é�£P "QÎ^:žÅ:6À-j!¤[J\VäPž#]f¤]ndRêe öeTþ¥¨f̱æUºfV¦läWÚæ�!ù,7*rüÿ”Dp™Af^ZÈp–Ç=IüC±bŽ‹wiÜØ¬£GW CFI²•É“SzâÖKe0câšIó”Í›CrêäÄ“ŒOŒ«‚ꥨ"E þZÊ”—S+P1bJõÔ«VŠjõ «W�`ÊK¶¬Ù³hÓª]˶­Û·pÉ&5¸,¡B† !êMYÑ¢Ô9zìh¢°a’%Ošĸ1K>.aÅ”IsæMœ:sòää“ P¡D�"MÊ´éÓ¨«Å ukѸ°cËžM»¶íµsÚe†7¯Þˆûþù 8ð®Á„ FÜÜuw÷¾ô¸'áÃýeÜ.“h rË1ç\+ÐE×ÒKÔY‡Ëwßi7Äf�}^h^ŒGšyè©—šj¬YáÕWö¥¨âŠ,†ßn¼õÖŸC| GÜ€ˆ s‘,Ø  ÒA8™„e!†Ýåð]x¢‘gÞ/!BÉ”T²Wâ‰]µ¨å–\jù¢~2ÎXc_7—c�šÀ£� )Y„ֹʑÜyæh‡ˆ7šR žf•U’È–ti衈ÎF^AºÙÅ#�Fúv§”Ø™“¤¹¦s?>öqb„*ªœv–á�æÙdRc¡‡ SZÿ9(–‰Öjë­e-* ]0>)¤“bG¦˜jª §mzʨ¢†*'q¦&¹$‡Ôª«¼À ¡të-¡¸†+.¢ºò æ%¿«¥Ã›£±ˆ± �²ËþÕ¬³EB­†Lv¸§$׺ª-·Þv î¸'¬b¹�Þ…nºÁ^æÈÄ»û.‚�d¬1%wÜ©²Ì6ûì_ÑÚ©$žz’ð«°\ðÁ Ç,sm ççèBé2ñMWl1škœqÇ'ëiÈ£æKò¾¨ö[-Àba›mËXl0­3g­õ[5÷Š3Äëb×óÄ?­œÐCMÉÇGÛ{ïÈR•Ì/µÿ®ìÔÀU[ óÖ|÷ÿ­•t!× -„žfš$®øâ‰çŒö#¨D.ù�%Baùå÷бÙf•_nyÉ콇¢ß¤—n(à ^¸á‡+Çøë8޶ä“7عç™oÎÓí—ƒ®šèYš.üð*¢¾Œê«ÓÒºë°/.»Ð´GN9kž[ž»î¼mè®�Nü÷àÓf<ò«/oXóΧûxô¨üH\õP\¿¹Ôðû^ð…†¯ÿþo��\òÊ3Ÿ Ч¸çiìGîû üس�:�~Õ³U¬&ïñï‚‹ÿ@�€±SÚØ ÷U��l ='Á¡PЂŒáµ%ŒÚð8Ìa.vÈCÄ�Ѐ#!tÿL…iU%…*”¶Zx Êð‰2¤¡ k˜Còp‡>$ !ÄÆшTA┈-U˜ñŒ H£�Å6òOŠS¬"¯ˆE�0„¿z\óE<…‰dtÕѨÆ4²Ñ�ˆüo(G:æ"‹L×'&II ýHn ´‡"Æ@¢g�f,¤!­–ÈRo‘Tl¤#鈩œQ²’Ú¹$Ó¤r¹M¢“žä(U!ÊÒ”Àä*…!Çc¬’•grå+?aÉa’–šô#'™Ë]öò—ÁÌfß”Œnv32‘q†8ÇÙ‹ršœ.Ù£ tljúE«Døƒ¡6ç™Hnz3è„Å8ÉiÿÎræS�ðs§©àéz”žöôf>÷)Î~ú� ( ßéž‚ô¢ÀLè7ÑÉPgçŸ ’¨H¡P²+a £( &/îŒ'eŽ8pÃÈH%ZÒY�(¥85åJïéÒ{ÁTiМi)Š•½åô¨2Ü©7{Ú¬ŸRˆˆBíQ¯bT¤Z•Jí&SEåÔï@5ªP¨‚XÇJ¨ª^õ¬ßËjKÍóÒ¿Äô"`õÜXÉZÖ›¢õ®àSëVCÕÕ |5 %š«XëjW¼Ötze«OÝ T™Î4°‚%¬<KÙ™%¶4m•Ê[s TÈÎU²Á«¬h³¦-©=©¦XÉ{Ø#Ø*˜u´°žiÍ£­ÿ©vµUiíkcËÛmbëIµeÍmq;Ýž´·ÈõÛlKÜÔÞ‹= Í_r§‹ØßÒV%zat�KÝînm¹LiîU´»ÝÉz÷¼YÛ¥¶tEÞòJ½ðÕšzaÅ^½¹7´ñÍoÌæ ¨ú¾ì¾ïÕ¯€ÅÅ_*ù÷[°‚ Êõ.ª½å]°„mUà)øj÷�°†7Ìá{øÃ ±ˆGLâ›øÄ(N±ŠWÌâ»øÅ0ޱŒgLãÛøÆ8αŽwÌãûøÇ@²�‡Lä"ùÈHN²’—Ìä&;ùÉP޲”§Lå*[ùÊXβ–·Ìå.{ùË`³˜ÇLæ2»q—ѽ¦ÕŽÂfE`ÓÿÌ9E3hÕ\°6åÍpN©œ%KgoÙÙͤÌ3R÷LØ^ÊéÏxôE ]×T8úÑr‚_¢mPF—õÑ�.’¤Mi=ƒ’P¿Á´£#]½IwZ›»äQ¨EMjÏ™úÔÁL5sV�éV_îÕ°6¥1vÍkUëEÔ©°µåØ“kmãØÈæu¯gýkVkú„ªÁu±õ‡ìd+Û¾†°… öH{Ú #ÔÆMn˜ûÜÕ>vÙ&Qƒv»›}�©H"æMo¦p,Îw€Á q“{Üç>wNðu»ÛÝ•7½çý}'˜ß³ñ÷¿nn‚¼lowÂ)²p†»Åᆸl$Nî4Y|àëÿfçÆÿ Ɔƒ<Â"� ¡xdò“c*8ϹʇJ†Š´üã/ßnÌeŽ%š#èäy¸yÎq¾ó‰öœ"?oKÐ…>ô¸Ìœ95·¸Ò—Þt©>�åHtùÔ%[u«ëG·ù™–ÎtÝ­<êl‰®,æN÷¾®b·e?ËÕ“õ‹çˆí¡èºö¾÷µÈ�îs·;Þó^–½“¤ïG†ä'xÁ“Ô'>;ÐOlÄ'ž±zãÝBq]9HŸ<åÙnùxC]óg#û:ïy»‹~ôl)ýé “zÕ#£ònçyæï�ÙG�öˆ·½EqŸè¤ÐϦ†Aýê³3�q‹Ö"¶Ï}¶ô¥ÿÍÿã·‰ò›Ÿ8ãâ!îüœ@¿¯ÃT)æOv¢i¦â~÷ø}Š�ÍD~æW~÷w2« ~Ü•wí7ïgBõ§;ˆ%£Ûç}uUzÿ€h3€xß�€…5z Ø€Œ#X ö7�9P�ˆ�e¥�cãAiâ�›P€!ˆDëÇo%}˜#)¨‚È‚.¨0H(2Ø34ˆ û1Nø„sS;n='ø€)¸‚X„û·ýp¸„†Ñ„Oè„QHS8mUøƒ¤Ð†AøLÈN£0‡tHX’óa(†&@†e¸ªƒÌkx…“І¤ð†³„ô"‡t8‡vÿ9x8ƒz¸‡½Q†f8"GÄøÅxƒ¸8bˆˆh*ıˆºÓˆŽXWw‰3‰”ˆ–8~˜‰^¸‰ ø|>Hˆ ˜‚px¤¸9¦8 �ˆ ª¸Š“ȇPˆ‰4‹ûVv�¨8Ÿè†º˜ˆ¼¨,ŒØˆÁ8ŒÊÆx‰Raoæs͘8ÏxˆÑ(ŠÑ‹›ñ‹×ˆ�ÚX‰–‹Éø�"AP�ö€Ê±€°�ü˜9=ð�Y"†0�I(b¤ñƒ²†hˆâŒgbˆO("--?â-£G�öX�ø8†½Á�ýx/�¬A�‰%‰� Y Ù�¤ð�â‘m8‘¨Q‘¦r‘Ýÿ’‘É‘Lø‘ þ8’= �&i‰Dé +9 -Ù�09˜"‘NH‘%ƒ“ “;Ù‘…¡�?”#I”&y”)””KÙ”Y ™#R9Ti‘ ‚‘Œï÷~ZÙŠ ñ“@)’B)'r"–I1™#¯è’/‰–�9Ž4i-t–‘s }uÉ• é•É—Eâ— ˜Py&ƒé’O•39•5Y2�—�Y‘¹u°šxI™ÿh™âx#‘E x�I 烋¡Ù‡øw½ˆrù˜©y «Yxù8BÙ°ù—»WŠS›lw›¹é‰²–ǘ}dà›¢œ§9œÅyœhÿ“œËÍùœ4Ò¹tÔ �ºI ¯¨/Û ¿É|Á9—àÉš?9~hSž«pžhÇ<ê¹¶i‰†X�i‰�ܸ˜óiõ‰{÷I—=Iœ«I)ü)4þ  |gG‰³ž9מ陠»™� Ê�…ä�Â9¡Åi¡š1Úqè�:�Ú†˜ ‹½IŸÝˆ6dˆû�t�ãA£ Fj!¦�¤Jš‡‰�ð¤Pš9�ánHGVz¥ÅYœG°¥\Ú¥[Z”F Z÷£m¤'7¤T¤GªJº¤’˜�½¥Qz/SÚnUz¥Vš¥«é¥|z`]cZC@ÚBŠ6D:1Fª HÚ¦¦ÿÀ¤[§rÚ RêTzrxš§zÚ§^ú§bÊodJ fjq¬¨¦ŠÊ¦Œê¨v¹‘*©tJ©vj©—ª§u ©]Ê©dç©‚Z¦„zr£Š¨kš«š Â:¬i²>Ñ#KdànÔ¡ —J�C«\*'Í™†eö©7ƒt½ê‰J;9¬Ã*¬Å:;ÇêL®ZËÚ¬Ï ­G ­G­d6E5ä5 1pÙº­Ñã­ßÚC…a¬´ƒ¬�q®—ú8”Â¥�Á® §ò(hð* ×Ê«“HªÜ:ø:¬újüZ;ÐQ2Ëú­Â*°ØA°Œa°ô†°´k ªW¯¿ª+¬{±ÒC®¦²±ë±—ÿ²‚ ²óF²Ëxj'»«¢š¦‘˜¨Ò²Éð²âÚ¯2û¯ÔÁ±É`³7�³:›< kºò³x�­B‹‡D«F‹´Ð3®-4û­PkR[$ÍYµ§vµðвôºµÿ×µÀ©N ¶Ã>þêe;¬g{ iK!k[ C»4bDAŠËi “oÖK ›nÀ€ ”[¹i’3ÿÇ#§©N«êHÿ÷’£¯ø‘á{È�C 1q)a!^…*W!V“M‡+‰»¸¸;3Žkg� ¯’ëA˜;6<òŠêÔQž;6 9¢k‰¤ë¦‹º ¡ºÁºáº~»P!»p Lµ·‹»Šÿ«»ö¸¢¹é¼é’¹ÌA¼{d¼tô¹zº91ºAQº¾½— ½A½ž`½« !±[³k „¸H$'à›“2³»mÖ»ST}Õ‡¾¿ò¬PÁ̾ÐQ¼Áî{Eð ò;ô» ö«zø«¿³À¿þ ÀÙ+ÀÛkJÝ bÄm߆( Ìf6¸¬L})lÁŒÁ�±ÁÌPÇÛ3É‹ Ë[†Í Ï‹C© «k­«¯k€<ÀÜ[À¶{ÀÏæjŒnãkg9L;< = )? ÄBÌD¬ÁÌCü!<Â%¿œ1”\ÉÄ,™|Ì“�̧°ÌþëÌ.AÊP½z¼¿|Ü¿9¡Ê Çʵ E’+ �а\k‡l9à<3„É#å|ç¬ éܤ¾ÂÀ ÂüÎÏF¼Cœ<1žì!¬°ù̃Íþ<Í]͇pÍV ½ÿÍ?»tÐ �Ð �iÞì9�(º"¹Ím}Ñ�ŠëüíÌÆ— ÏÆÒ¹0ÒŽPÒ³pÒ9‘Òù Íûœ¿ýœÂÿ¬­YAAÐáŒA7�n9­ÓÜËß1ËE‘Í[Ôé6Ô䌎ì�:¼Ãi²KÝÔüÔÕûÄCTmÕX=Z ú| Qlʨ<Ö,<Ó.\Ó}ã2Þò$0ò œMˆ=?%¢Fõ±K, ’ëP½ ™sìËô µÛ²-!!ªM1Òµ[ê,¡!ßÁNÅ”CH0Ü$‘Û6áÑ‘9‚cN‡�Ÿ,eÈUp5l¡!È~ƒÙÝ¢Ù»ÁÙ¯àÙÊÿlÒ -¢Í¤M¦ÍR’Û¬¬�¼zñÚ²=ÛÖQÛ qÛcÜ€»ÛR/øÛºÜ84ÜHPÜ-}È�Ê�Ì� _ýÜžÝ|5ÝÝVÝr­5Ø-ÚmÜíÝõ Þ´ÚÕ3ÚiTÚ tÚé}©ë�Äí½LïÛ´-ßôíö�³Ÿ‚*ü½9þ} .à`}~àƒ‘àjâÜà ÝO(ÝœEݪbÝ—�7sá ‘á#ñÙ.ÞNÞ!nÞ#ŽÞé¦Þº8­= î½â-^Û/ãø $½MãAÜþ�ãúK)=~/Ë]NͽàCÞàEþàGáI>áYSáO²¬PŽËß}ÕáÝãÿ�å=ç}O%ާ'ŽÛ)þJ™3æ¶íP’¾ãº}¼­ßrÂN0"ÜÄýæØçÍ2ç«­àý9Dî„F~9L¢ä|èæ!è�å…Î>î9 ž">H$¾å&ÞåŠóå¯]éñíâ˜^ß޶g>ãû½æºêÿ=êý ç‚�ÜrŽàt®êÉÛêsðêH×~.¾'BAµ¬Ù¶Ì�á{No&ZTÒèÞ”&\. ÅNÒ¹³Ð‘Y4±¬�ð1Ü\êTZ±0’àoÉspÅ!ß®P,;"ä†îDëå.3ì³ éNëÎáíNŽðΣ¾NÆCûaïÃŽï‰ÿCÏìÞ þ>/ðÿð¬`ð[ŠðE¡ð Ï ?Ü<ÿ„oñʡ㠌 ŸI|Nî–Í7ï!?#oèíÃî~9)ï W>-o/� ÷~£@ó$oó‹•ÿN:¿óas Ïz ÏCOôEôN˜ô9°ôg/«õx¾ ÎñU¯0’{õŠ‘õ1±õûõ–ö‹.e¿ g¯ÍJñÏö\ÿ#7� 9¯ó<ïóGô^ ô _ôHøEøÓôÏꉯ£AÅøg�0Á^m�’”Ïï–�òóï,?%táò½óx úò-úÛ¥ú_÷wÿ/yOÖ«°÷œÐ÷°/ûßQûòÍôu~øQßûÞø·üÈ6ü&QüÊpü]/É�ùc$XÐàA��.cØðÒCˆ&$N$PÑ¢+Œ5btÔñÔÇY!Q�TÒ¤”)s¬ÄÕRÙK˜�dÎ YsÖÇS¬tš<ÒsåÏ«„z!ÊÉ(3¤I“"aÚÔfHœ:YÍ¡*t•3¬Y7ºšÔÕëĉ‘Ä>‰Ê“'ªT�®„ÒöÐ[¢ä @X×î]�’ôîå«WÕ_ÀÀÞJ'ÄÉ/¦ÕØ1Nœ5Ï¢M«vm"Ì™mæÀógОçÎ  ØiÔÍT¯f­šÑkØ�dÏþTÛ¶ÿ1ܹ‡í‰ìHT „WžsĪUdÉ•çbÞ¼wo²Â¥+H©ref¢Ù½(åž±ãwGdmÛ†UÞ<Ĉ`M gòGJñåŸD¹6¨Ð·‡FËÅÛß?€¾”0À0ð@Ø`3ì#ÄÐXŒ1Ç{ïÉÎ"nû2ÓŒ³ÍJ+m?JC-µÖ¼ò*Á×f›­[ÌM7ÞÆz 8é*«Ã¸ãVQn¹æ˜{NF›¦®ºú®ÃL;¢¸SÊ;ðÂ{j¼ÚÔ3EF¤l¯½ 囯$뀲*?ÿ³.û"ð¯DqÁS|P±%|¯BÊ*ËPÃD8ìÐCÐ@qÄ`ZkÆÄ®¨TQ¶]|ÿј݆�nÆ‘jLëˆ9rÔqGdzôñÇè„$RŒŸ°CRɤ˜O<(¥¤ÒÊ+ÑËRKJèu­/ß sL\ *“¯…7$·›·ÞŽî_õ =´½N’Vº'¦�€5V.‹ô?[ 6ÿ×:`pØ&ˆ”8BŠg±˜¸e7äpãŽ99äÐ Tµ^ê.ùГ=Iyå× 7Òq‹«Ê\Lk¾™]Oß5’gyIÚ‘­‰Ëh‘V:é¦{ÚÒ$AºüIà[¯s¯†´ºë¯kš°[cË®éb ðÌSO(?iÛí·e±TîÕêîånóÞûÍFý ¸‘¨:¢ªRBÓc¢—þð ¯Î¾žçUªIÈ…–|"Êg{úrÌ3ç<êëi¥zàÑD“t†L_u¹_½Û7вòþãÊ®Yµ»]*r§»}ªwv#”ÉN6¼¯o½A^ò×<”X… ä ô¤÷ÿ †pBDìv–™Q¤P…J’Ÿ¯¾'‘ðÉf|äËœÓâ#«”´E‡PXÏÜ7:½”nQ[£_‚ì÷üåoúëßÉÀŒÑJ< ¥X¢âí�Ûâ[ñÔEÂ9Ô�yƒ9¸AF/„"|ц1 ©p…ÜiáÐ^ÃGÌðr5|Ú§vØ–"é‡ÿ�ß2êȵ†Õ¯Iþ’O·–Èħøï‰�Ý ,yIÞ®Š $µ²¼-&ª‹,{)•ç åŒhLãA8 špq(”ã(X8DïÝE×ÒãÒ2×G"ý‘‡ëóá ûSÈC6G„ÌÓùÈ&fk’(F5­yILÿNQ“¹³b'±h"f ‚‹‘ £~DB1V&•«X%Òx W¾–È“edWK[Ò— {á”vy¨^–¯iÀ¬Ž0©c3ˆñÛ'ÃÒD%fâÄ™J\b4'3Mk^›7ÈdÛ6yœ+’쓳‰'Á/Vð”¨Ì *WùÎxÎ8õ¼g-où¢Èé2A¼„ù:ÁGXùñ�ÍNB  Aù6RªVµ°ÔÆ &,&2Ë„  ¬fµ9.|áwfó°‘ A¬Ch'L`b*pEe'ç+@[³bÖ—˜ $.‰TLb•Ÿè0%ÒS&8ɳŒõ®BÑ¡Àªpؽ FI¬‹SµŠðXÈšBÿ²“=Ÿ ŒrYNÓ>í´T~ò“ÒUW}IjÝ–ªž¦ê©�!¡T_2“ªZõ#YÕ*s¸ú=¯Ê¬¨+YW We HjeEeÛZ€·ÂU®¢+*ìZ¼²¥-{�^_ÿj“ɺ„äú[…Äžf±csŒc!ûØÉRö|˜5Šf×ÂÙy.q‘KD;¤¶F©¯ajj½²Zœ´vQSmDleK[¬nÕŽ¸íÈWÁÖ±–U¹éHZ?ò\Î7¹f]îßœ»VAD7zE _¹ã×çDS»!æî0W‘Ÿï†7ã}�±Ì{ÞôJ¶²ìÍì7»ÊÎÊ´õ½o^H«_Óòµþÿí €?"àØÀVEp(œ‡~æö»í­„9LaGX8' 6‰†±Ü7Ã"&±L¬ƒ‹N+¶Ja½‹X½È 5Œ�Ð�#›ã³×½@�ïqä{ˆ!‡¨ÈãKi{qZ°0¹Éì‘éH\« ØFB¶³Eð•³Ü`Ý>˜·þí„]ñ1c¸Ìn=³©¿3ײ|¸¸Û]E^§[âêžøºsë`Waç¿%ÆyÖs0øì˜O}*Ǧ¨¬}ý“B ì³ôUt‘óËšýViÉLvò) œ)kzÓUötWA½eQw¹Ô_>u…‡{a2—ÄÌÎ@3˜a= à¬Y(¶†u�aÝÖtn±ÿañ,‰b›¼�I6‘*Ûìµ<{%Ñ^ß´½Z£þBãJZ�¯Vµm¯$L9î�**eŒÅ„ÛªÙJNì«Âb­EÍmÇp�,RÁ°ç “ܤ9Öú®µtû�ë#EzqnYÅÛkZÆ—ñžßtÜã6¼:·P„i°‡�â«h–ŸD«ñ_p\5ÿ§Šž&òä�œµ#9yÊ_KUq¿‡åq¹ä´Ìå±Úüæ/Éy“vÎóY Â符÷K‚noæÄl¾µ›sÍŒ¥ïÚé‡:‹ÝÝ`bØ|‘[%Lz¬·Uë)áz×�®Ã°‹}•=+{´Î¾qît¼Wx|û¢FÿÞ¯’×]1*ŸÐÞ5Òw¢ý=Ý�|-pÞ�?ñ‰_ƒ>Ó>Ä3‰êÛ°ì{µÈ÷ºò¾¢±Ê{³ñ“³Í#¸Ïs±©¯¾(=÷«„Ô+€øƒù£¿×k‹û³|Ò?á¿„B;µk¶Û)€@ß‹»‡@À¤;É »Ã4¼[¹ä»­LèB/T>™5šk¾ç£…賉éóÀ¶ø9Çà ÿ¡#AYó5~ ?¥‹¦ó^;¿¨½ t¿ÌÁäAÙùÁ D’Ú û꿴˽µÛ½¶&|‘ß»(<@œBܨÂLÃÂK€À-ô/üÂs¼1¼2<ÚHÃ’øÀë A�ÁîK<Ê;:ËK:̳CÍ3óC?>T?$=@©A„¿øDú+Äû;DíHDŒËah!2‘#B 3ŠêȨjú±3JàjT‹iîQ—­HbXÇÈ€TȪnÇX´*ù¨§çAAi�ãA“àüGûH˜ÕÈêŽÞ+KÑ¡Ì;Ò ´{Hˆ*aÚ¡v:´Cë™ÿ ÈH�<UX´ƒˆFa¸%k\$o›E“ÐFÏq½vG¸’Ç0#G1Ç&AÇ�PGv¼·XƒÇ7qÉM«Ç7ššKÁÇÖÐGwìÇôÇ€\”�Ĉ‚¬@„Ì…Ä †¬/‡„H«”ȉl‹Š´HÏ*&��I¯¸F“, ””ú[Ém GæÇH(Gö8ÇIÇEYGbhGÓÉáIÙòI;QŸ ÌGöØG£<ʤ|‘¥t…¦ñJȶXH°kHаʫ ¦¬Ô¡­äÊùB¨¯KÀ�F±ì ²,ÁÄ;ËYáÁvêÕ\M¶Ì·<)ážÚ¡Ë±K¼l.½\ ¾¤Çø°G¡PÁDÿÂ,‰£DʵHÕ Èë2ȃtL(€L+�ÌϠ̈´ÌË„‚ÌÔÌÐéÌþK}Iðx²²´,NHÔ\¥ÕdÍ–lKw{K‰Í&©�”±É»ÄI8ÌMÅØMñÍÀÊÁ,Jâ,ÎÃÌ�Ä\̃ç„Néô ƒ°J^xP½N­\%Í«áÎîüÌ�üα$Il1ÓäÁ‰CÏôìƒÖ|Í÷TÙ„’ù¬Ë›ÁœÄªxdÏíëËÞüÉÏùÍäNˆNA(N>PÜ(ÐåtJ…ÊÇ”ÊȤJÐhPˆ„ЕÐìäÊíÄP»ðN¥À ðœ ñ$Í“,Ï”ìºÔ,ÑÖlŽ®�O˜“ ùÜÿp{ »´Ë}½4œ){þ´ AY�uGàRgk m êi.üºû+ '}H(]Ô(¥H •/©R+E,M -íÐ4}„.�C³S´\‰OÓô,Sæ8S=·5M”6U†7]Ç8‰9M—:…Œ;ŠЈÔ!Ô]dN=ôàÆb¨q�reQ6Å�smÕk!¡Xí‘ÞØ´x�WˆH)äñÓ|Ý×ÕÅ.ÜÇÝ¡åf Åð|V¦ W~ X~HYže`¨å@Žàš dC¾`DÎ`E Fæ&ææ2æM˜d›e¾ä#Xaghácxa±­f¾fÎfÎ_n&eogÿ´c!)à<–/ =ª¾Pçun�Œ8A†ç æåÅHYû”åU›‰z~Ùâi*~Š®¶„¯¶Â°ë‘RŒ=ë‡R$'±iÈÀirÖé7áiqžk†nc‡~c¼Îkÿ¥ã£^e!qNbêfuê½€j�>ì©NìA®êÿB¾ê(~­&‹Èžì°– ËF ­ÍV“´îì í¿íÙŠõéÓåÔåÕŽV�Ök↕v 2Ïú®ïìÑzju6lW8>™Å†â—è–á†ìøXéähiäþå jæ>`‘Ièfë•&¸Öˆë6íõGÙ±ëîfØïnmTŽ[ûÖ’ñŽ/ù2ïÃBoüêèõÎíö6�÷Ζø6iŨo›(îük—æoäñoBiKµ>ßÏnëÐ~ëÑÞˆŸŽÂlðíêïLUxPjT jYjæ¼!à1K�ΞÑÙº€Ð†HŠÕˆ‹ €˜ëܳàœÿi'RŽxÒ>�pGüdÀÿ—8‘H” È5uឭȪ0˜ó½0ß °Òv’ÐçÄ“žÚ!�Ö"ç…#OŠ$GÛ%+'Ï(G)×]#g+W ,·ˆ-ÿˆÉðò?¸s2sW"óí3s¯­B5O)ió7o’8Ǫ9ƒ:'NÏóâÜs •�?ÿÛ@·ÒA/t¤8ôÑMt±Zôãhtíxôƒ rIGŠ+?†,¿tùír“øò;÷ô5u•ÓQ¾4/}QTÿ8ß9§óƒ´ó;—õ£¤õë´u$ô\ÇÐ]¯rC%÷dóã±e ;÷d_†Io†J¯gÏôhÿo¤ö²vQ…n�‰R‡´‰øöÿç äËwW/w þ#B÷T÷Ëdwíp÷w'òHOö^§wD·w&Çw8Ò÷¦“~ÿ÷€×rbærOÐôƒßQ�^¤…oømŸ„� ‰ï Š7 ‹u‡zj“zîŒw“gR¬v£à ­·‚®Ç[B?ü:lv²ö›/ø´�jž×U)Tm7«æ€x‰z±¸ûVouEA¥;btú‰|/ |]§z$ÅOè•oüÿ züÈ—Ýɯz¥˜ù�7{A@û÷Ú àÜùðäÓϯB˜}¹�xº‹¼AýÔƒÕ¦�»×| ½õ…¥}’~áG|Üÿ‘ÅorÞ'ßy1ùúá{�¿|‚?{ƒOþN×ùµGžšeÐ ª„ K1LæPĈ¹&2ªhâ"Æ7bÄèé#È!"Gr*i2 Ê”9V²l¹ ̘dfZ©Yé&Ι:ÉÄìéÓ Ð †`ô(Ò¤J—2mêô)Ô¨RUñâµìê2fZ™½zé+ØSbdžiR§Ë‰ÖÖ´²á-\©H«Z½ºuë±cöxä÷ Ù�‚ úó'­NdŠ›ÿ1nìj Áƒ&dXÊa²ˆ)Zìh¢"hF~G?Yvä“'S¢L›Ö'�mqæÜÉÓçÚ܉‚ %:T.ðà‡§Z×îÖ®`ÃŽ{úìÌ´¹ÛÂ�œ.Ö»Zóòíû×``O„ v™xqcÆ�!”L¹rÇš•MÌÚóçТI—6í µYªqÂZk®µ›l6ÑVÉ/ :ØV[º­ÅP¾ýF†j(œqXe•œWËEÒœs‘TZ.MWSuo ‡rwqÇ×h€•(a†!6“bȤ§dŽ´wÐ{¨X†Ù|ôqÆ~úíGšÿ(à€x O Z± ƒ6aMîFÿ¡…lx&šgJ²&›À¸ bW]ñ÷H‘uØIy²´ Ÿ}RèE� ª” …J]Ú1ÓØ%�J6esH:iZ‡X ¦ŠæÕh£$zzʤ“:3*©Ib†§œ8ÄxƒQ¹ãNbÈ:«mdXzë!"º+]£øúëŸU;¬¡¤y,²À±Ùæ›ZÅçœuÞ9Xž|ìÙ'ŸKh±‡îª(£Ž>Zd¨’Vzi¦ÚmÊé§$–;©¥ÎwªC†±j«‚`Ë'¬:ÍJ«m¸Zª+¯»þ ,…Û&»0ÃP-»¦›ÀÀ -ÒÖ�§ž+í»Š¶†rÛ­ ¼‚˧�ÎBn¹ç‚i(š“ÿj»Í½都Òk/¾­nÜïLÿÊZ«À¹RX°Á�Òq¡ +½4RKñÄrVüž�S›q#=hR *²vá^b2Ê¡ªÌ²Ë0Ç,Ö»°ð6Üq¿�3€ùîlžm>‹´À[Ê«*� î5×L¾°ÓP;ûì+ÑR=­ Õ^‹­ßÆvMx`ß%6Ùï½{vº2¾ÌîÚ –ë¶Ü©Û{åä}òL†Þ|ãZ¹R‚Žùá¹#›x³\1î8eUcl­ÆûÒ~9ášo%6d�*ôî¿+Ýʲ1Õ³Ýè�†Ö®i’¢žzÜ«³žõ¾¯Çpß {œ”í�cn¹îñkè´¢Œ7>5e„U�ÿ–Öê'�¼×ú ÀÒ+©jTóN–�‘LJob�ºBa½ë1c]Ú ÷@â=Ÿ€OnâcÝÝZR+½+hï«]ûN(¿'bŠ»‹ˆ"a2Vа†ú³SZ*§0¤K>üá H¯^"� a ¤Á•aj‚ØKÕöN¥îÍá{,À¯´± ýÉiïS!RÚ§ 0²°ŒRqaï¶ÃÖ�†7¬Cýçµ� ê‡@ b HÄΡ‰s˜èZ¦®ì]ÂSQj¯87+�o‹éã�¿H8ÚŽŒf¼dSÐ(1í¬ñQmtã`öç®)ž²£ñ˜Ç!��~¤K¦:¼Òÿ�þAdO¹HÖŒ�|Øâ"…")I�Qòv“Ä$2™¢IEuR2ŸdÅãÈ›bA¢šÖÔä)Q©J=¶r\ IeÈ´‘®9‡<]"™E9rvÁ|Ø0çȾâ.™öDÊ29)"6¶1š£”c ¬yM4fÓŽÛdeª\ Î$Š3–$g§HtÎPY±ƒëtM;oÕExƳ[Åt_=ï)R£dG;qbNsZ¡Ò‘Æu.“ Ó™ £¦6ýQ32“Q¢§,CÒ|À2š±”�RÅ•&59§œ�gcz£Ò}4˜þ©E)VGZÒ»œô+žRi+X:—¶¦3¥©MkŠS�Š…§>ÿÅP5#T¿Õs);ê­’ŠÆÔ1µ¥ûzª€¢ú¯©‚©ª-Ê*b“¹U8¡t,`«¾øõR0�U¦iUë�Ø:¤ƒô”?•�\¿2T±Õ\xµ”^]È׺éì¯>ƒjÞ¤*0ªRȪ‰½­»¸�ˆD�‰_W‘³Vö²ÂX+AÚú¨Î~63A-]IkW³�öÁ¸.v5¹ZÔØÍµÿ¢’@«©7ÂBèO¸=/&uë;Þ~u¥À«dËJÙâ^¶;{Ѭ[= WÐFd®�¨k¤îÚ’ a7»{•[_á‹-Àª&¼�¯ÀÊ´CôR8~êíjoSê^V)x¸ó=«qíKü.÷­¡ˆkÿ¡û_阺X�¯«]³¶©Þ�xà a\I¸”þ±Ò<#W9†žZUoÕ yD~²+Dì©Î2—e˜J’‘I¤€-sÙ¨-ÉÍ­~ã`P)u°�Mÿ ù0¿¯Çÿ2œÖä­<9ËÍArù–¸ä5ÊD–2‰¨lb–aYDžâr—Mû嵄ÙWc.³ÜÎì“4ÅilÆœ› çM£iÎZ©³¡I„gl±DÉ5a²�ýeûNYÐV¾òs—shD+ÀË,³¥ÄcHÇMÒ=¡4P,Þ6[hœ>6†<Í PËZÔJ²¥öü‹>ûÐÍ´~­\èf7‡ÖµVô­Œ�kGïZ@fö5L€ía ”ؾ16²ãí/ñYÈt.r¨ïüì<çÀÔV@µ‡Tmí±`ûÕ¡ØvcÅâm[¯ׇÐu�y 7tĶj^Ö¥ —é@É»ãO¡÷´íýi|s{,£&«¿Ž�³:Ю~5½ªeZ3\-â~8¹#nîHSÜâ•^ó°1]l{¼è;chafa-1.18.2/docs/chafa-sections.txt000066400000000000000000000253341517447374300172530ustar00rootroot00000000000000
chafa-canvas ChafaCanvas chafa_canvas_new chafa_canvas_new_similar chafa_canvas_ref chafa_canvas_unref chafa_canvas_peek_config chafa_canvas_set_placement chafa_canvas_draw_all_pixels chafa_canvas_print chafa_canvas_print_rows chafa_canvas_print_rows_strv chafa_canvas_get_char_at chafa_canvas_set_char_at chafa_canvas_get_colors_at chafa_canvas_set_colors_at chafa_canvas_get_raw_colors_at chafa_canvas_set_raw_colors_at chafa_canvas_build_ansi chafa_canvas_set_contents_rgba8
chafa-canvas-config ChafaPixelMode ChafaColorSpace ChafaCanvasMode ChafaDitherMode ChafaColorExtractor ChafaOptimizations ChafaPassthrough ChafaCanvasConfig chafa_canvas_config_new chafa_canvas_config_copy chafa_canvas_config_ref chafa_canvas_config_unref chafa_canvas_config_get_geometry chafa_canvas_config_set_geometry chafa_canvas_config_get_cell_geometry chafa_canvas_config_set_cell_geometry chafa_canvas_config_get_pixel_mode chafa_canvas_config_set_pixel_mode chafa_canvas_config_get_canvas_mode chafa_canvas_config_set_canvas_mode chafa_canvas_config_get_color_extractor chafa_canvas_config_set_color_extractor chafa_canvas_config_get_color_space chafa_canvas_config_set_color_space chafa_canvas_config_get_preprocessing_enabled chafa_canvas_config_set_preprocessing_enabled chafa_canvas_config_peek_symbol_map chafa_canvas_config_set_symbol_map chafa_canvas_config_peek_fill_symbol_map chafa_canvas_config_set_fill_symbol_map chafa_canvas_config_get_transparency_threshold chafa_canvas_config_set_transparency_threshold chafa_canvas_config_get_fg_only_enabled chafa_canvas_config_set_fg_only_enabled chafa_canvas_config_get_fg_color chafa_canvas_config_set_fg_color chafa_canvas_config_get_bg_color chafa_canvas_config_set_bg_color chafa_canvas_config_get_work_factor chafa_canvas_config_set_work_factor chafa_canvas_config_get_dither_mode chafa_canvas_config_set_dither_mode chafa_canvas_config_get_dither_grain_size chafa_canvas_config_set_dither_grain_size chafa_canvas_config_get_dither_intensity chafa_canvas_config_set_dither_intensity chafa_canvas_config_get_optimizations chafa_canvas_config_set_optimizations chafa_canvas_config_get_passthrough chafa_canvas_config_set_passthrough
chafa-features ChafaFeatures chafa_get_builtin_features chafa_get_supported_features chafa_describe_features chafa_get_n_threads chafa_set_n_threads chafa_get_n_actual_threads
chafa-symbol-map CHAFA_SYMBOL_WIDTH_PIXELS CHAFA_SYMBOL_HEIGHT_PIXELS ChafaSymbolTags ChafaSymbolMap chafa_symbol_map_new chafa_symbol_map_copy chafa_symbol_map_ref chafa_symbol_map_unref chafa_symbol_map_add_by_tags chafa_symbol_map_add_by_range chafa_symbol_map_remove_by_tags chafa_symbol_map_remove_by_range chafa_symbol_map_apply_selectors chafa_symbol_map_get_allow_builtin_glyphs chafa_symbol_map_set_allow_builtin_glyphs chafa_symbol_map_get_glyph chafa_symbol_map_add_glyph
chafa-util CHAFA_MAJOR_VERSION CHAFA_MICRO_VERSION CHAFA_MINOR_VERSION CHAFA_VERSION_MIN_REQUIRED CHAFA_VERSION_MAX_ALLOWED CHAFA_VERSION_CUR_STABLE CHAFA_VERSION_PREV_STABLE CHAFA_VERSION_1_0 CHAFA_VERSION_1_2 CHAFA_VERSION_1_4 CHAFA_VERSION_1_6 CHAFA_VERSION_1_8 CHAFA_VERSION_1_10 CHAFA_VERSION_1_12 CHAFA_VERSION_1_14 CHAFA_VERSION_1_16 CHAFA_VERSION_1_18 ChafaPixelType chafa_calc_canvas_geometry chafa_free_gstring_array
chafa-term-info CHAFA_TERM_SEQ_ARGS_MAX CHAFA_TERM_SEQ_LENGTH_MAX ChafaTermSeq ChafaTermQuirks ChafaParseResult ChafaTermInfo CHAFA_TERM_INFO_ERROR ChafaTermInfoError chafa_term_info_new chafa_term_info_copy chafa_term_info_ref chafa_term_info_unref chafa_term_info_chain chafa_term_info_supplement chafa_term_info_get_name chafa_term_info_set_name chafa_term_info_get_quirks chafa_term_info_set_quirks chafa_term_info_get_safe_symbol_tags chafa_term_info_set_safe_symbol_tags chafa_term_info_get_seq chafa_term_info_set_seq chafa_term_info_have_seq chafa_term_info_get_inherit_seq chafa_term_info_set_inherit_seq chafa_term_info_emit_seq chafa_term_info_emit_seq_valist chafa_term_info_parse_seq chafa_term_info_parse_seq_varargs chafa_term_info_is_canvas_mode_supported chafa_term_info_get_best_canvas_mode chafa_term_info_is_pixel_mode_supported chafa_term_info_get_best_pixel_mode chafa_term_info_get_is_pixel_passthrough_needed chafa_term_info_set_is_pixel_passthrough_needed chafa_term_info_get_passthrough_type chafa_term_info_emit_reset_terminal_soft chafa_term_info_emit_reset_terminal_hard chafa_term_info_emit_reset_attributes chafa_term_info_emit_clear chafa_term_info_emit_cursor_to_pos chafa_term_info_emit_cursor_to_top_left chafa_term_info_emit_cursor_to_bottom_left chafa_term_info_emit_cursor_up chafa_term_info_emit_cursor_down chafa_term_info_emit_cursor_left chafa_term_info_emit_cursor_right chafa_term_info_emit_cursor_up_1 chafa_term_info_emit_cursor_down_1 chafa_term_info_emit_cursor_left_1 chafa_term_info_emit_cursor_right_1 chafa_term_info_emit_cursor_up_scroll chafa_term_info_emit_cursor_down_scroll chafa_term_info_emit_insert_cells chafa_term_info_emit_delete_cells chafa_term_info_emit_insert_rows chafa_term_info_emit_delete_rows chafa_term_info_emit_enable_cursor chafa_term_info_emit_disable_cursor chafa_term_info_emit_enable_echo chafa_term_info_emit_disable_echo chafa_term_info_emit_enable_insert chafa_term_info_emit_disable_insert chafa_term_info_emit_enable_wrap chafa_term_info_emit_disable_wrap chafa_term_info_emit_enable_bold chafa_term_info_emit_invert_colors chafa_term_info_emit_set_color_bg_8 chafa_term_info_emit_set_color_fg_8 chafa_term_info_emit_set_color_fgbg_8 chafa_term_info_emit_set_color_fg_16 chafa_term_info_emit_set_color_bg_16 chafa_term_info_emit_set_color_fgbg_16 chafa_term_info_emit_set_color_fg_256 chafa_term_info_emit_set_color_bg_256 chafa_term_info_emit_set_color_fgbg_256 chafa_term_info_emit_set_color_fg_direct chafa_term_info_emit_set_color_bg_direct chafa_term_info_emit_set_color_fgbg_direct chafa_term_info_emit_reset_color_fg chafa_term_info_emit_reset_color_bg chafa_term_info_emit_reset_color_fgbg chafa_term_info_emit_set_default_fg chafa_term_info_emit_set_default_bg chafa_term_info_emit_reset_default_fg chafa_term_info_emit_reset_default_bg chafa_term_info_emit_query_default_fg chafa_term_info_emit_query_default_bg chafa_term_info_emit_query_primary_device_attributes chafa_term_info_emit_primary_device_attributes chafa_term_info_emit_query_cell_size_px chafa_term_info_emit_cell_size_px chafa_term_info_emit_query_text_area_size_cells chafa_term_info_emit_text_area_size_cells chafa_term_info_emit_query_text_area_size_px chafa_term_info_emit_text_area_size_px chafa_term_info_emit_repeat_char chafa_term_info_emit_set_scrolling_rows chafa_term_info_emit_reset_scrolling_rows chafa_term_info_emit_save_cursor_pos chafa_term_info_emit_restore_cursor_pos chafa_term_info_emit_begin_sixels chafa_term_info_emit_end_sixels chafa_term_info_emit_enable_sixel_scrolling chafa_term_info_emit_disable_sixel_scrolling chafa_term_info_emit_set_sixel_advance_down chafa_term_info_emit_set_sixel_advance_right chafa_term_info_emit_begin_kitty_immediate_image_v1 chafa_term_info_emit_begin_kitty_immediate_virt_image_v1 chafa_term_info_emit_end_kitty_image chafa_term_info_emit_begin_kitty_image_chunk chafa_term_info_emit_end_kitty_image_chunk chafa_term_info_emit_begin_iterm2_image chafa_term_info_emit_end_iterm2_image chafa_term_info_emit_begin_screen_passthrough chafa_term_info_emit_end_screen_passthrough chafa_term_info_emit_enable_alt_screen chafa_term_info_emit_disable_alt_screen chafa_term_info_emit_begin_tmux_passthrough chafa_term_info_emit_end_tmux_passthrough chafa_term_info_emit_begin_hyperlink chafa_term_info_emit_begin_hyperlink_anchor chafa_term_info_emit_end_hyperlink chafa_term_info_emit_return_key chafa_term_info_emit_backspace_key chafa_term_info_emit_delete_key chafa_term_info_emit_delete_ctrl_key chafa_term_info_emit_delete_shift_key chafa_term_info_emit_insert_key chafa_term_info_emit_insert_ctrl_key chafa_term_info_emit_insert_shift_key chafa_term_info_emit_home_key chafa_term_info_emit_home_ctrl_key chafa_term_info_emit_home_shift_key chafa_term_info_emit_end_key chafa_term_info_emit_end_ctrl_key chafa_term_info_emit_end_shift_key chafa_term_info_emit_up_key chafa_term_info_emit_up_ctrl_key chafa_term_info_emit_up_shift_key chafa_term_info_emit_down_key chafa_term_info_emit_down_ctrl_key chafa_term_info_emit_down_shift_key chafa_term_info_emit_left_key chafa_term_info_emit_left_ctrl_key chafa_term_info_emit_left_shift_key chafa_term_info_emit_right_key chafa_term_info_emit_right_ctrl_key chafa_term_info_emit_right_shift_key chafa_term_info_emit_page_up_key chafa_term_info_emit_page_up_ctrl_key chafa_term_info_emit_page_up_shift_key chafa_term_info_emit_page_down_key chafa_term_info_emit_page_down_ctrl_key chafa_term_info_emit_page_down_shift_key chafa_term_info_emit_tab_key chafa_term_info_emit_tab_shift_key chafa_term_info_emit_f1_key chafa_term_info_emit_f1_ctrl_key chafa_term_info_emit_f1_shift_key chafa_term_info_emit_f2_key chafa_term_info_emit_f2_ctrl_key chafa_term_info_emit_f2_shift_key chafa_term_info_emit_f3_key chafa_term_info_emit_f3_ctrl_key chafa_term_info_emit_f3_shift_key chafa_term_info_emit_f4_key chafa_term_info_emit_f4_ctrl_key chafa_term_info_emit_f4_shift_key chafa_term_info_emit_f5_key chafa_term_info_emit_f5_ctrl_key chafa_term_info_emit_f5_shift_key chafa_term_info_emit_f6_key chafa_term_info_emit_f6_ctrl_key chafa_term_info_emit_f6_shift_key chafa_term_info_emit_f7_key chafa_term_info_emit_f7_ctrl_key chafa_term_info_emit_f7_shift_key chafa_term_info_emit_f8_key chafa_term_info_emit_f8_ctrl_key chafa_term_info_emit_f8_shift_key chafa_term_info_emit_f9_key chafa_term_info_emit_f9_ctrl_key chafa_term_info_emit_f9_shift_key chafa_term_info_emit_f10_key chafa_term_info_emit_f10_ctrl_key chafa_term_info_emit_f10_shift_key chafa_term_info_emit_f11_key chafa_term_info_emit_f11_ctrl_key chafa_term_info_emit_f11_shift_key chafa_term_info_emit_f12_key chafa_term_info_emit_f12_ctrl_key chafa_term_info_emit_f12_shift_key
chafa-term-db ChafaTermDb chafa_term_db_new chafa_term_db_copy chafa_term_db_ref chafa_term_db_unref chafa_term_db_get_default chafa_term_db_detect chafa_term_db_get_fallback_info
chafa-placement ChafaTuck ChafaAlign ChafaPlacement chafa_placement_new chafa_placement_ref chafa_placement_unref chafa_placement_get_tuck chafa_placement_set_tuck chafa_placement_get_halign chafa_placement_set_halign chafa_placement_get_valign chafa_placement_set_valign
chafa-image ChafaImage chafa_image_new chafa_image_ref chafa_image_unref chafa_image_set_frame
chafa-frame ChafaFrame chafa_frame_new chafa_frame_new_borrow chafa_frame_new_steal chafa_frame_ref chafa_frame_unref
chafa-1.18.2/docs/chafa.xml000066400000000000000000000545641517447374300154160ustar00rootroot00000000000000 chafa chafa Developer Hans Petter Jansson chafa 1 User Commands chafa Character art facsimile generator chafaOPTIONIMAGE Description chafa is a command-line utility that converts image data, including animated GIFs, into graphics formats or ANSI/Unicode character art suitable for display in a terminal. It has broad feature support, allowing it to be used on devices ranging from historical teleprinters to modern terminal emulators and everything in between. You can specify one or more input files, but the default behavior is slightly different with multiple files; for instance, animations will not loop forever when there is more than one input file. General options Read a list of paths to process from path, or '-' for stdin. The paths must be separated by newlines. Can be specified multiple times. Any additional paths on the command line will be processed last. Read a list of paths to process from path, or '-' for stdin. The paths must be separated by NUL bytes. This is more robust if your file system allows newlines in filenames (as POSIX does). Useful in conjunction with other tools that support it, e.g.: find . -type f -print0 | chafa --files0 - Can be specified multiple times. Any additional paths on the command line will be processed last. Show a brief help text. Probe terminal's capabilities and wait for response [auto, on, off]. A positive real number denotes the maximum time to wait for a response, in seconds. Defaults to 5.0. How to probe the terminal [any, ctty, stdio]. "Any" is the default and will probe by any means available. "Ctty" will probe the controlling tty, usually /dev/tty, which is useful when chafa is part of a pipeline. This may block if done in the background. "Stdio" will only consider standard input/output. Show version, feature and copyright information. Output encoding Set output format; one of [iterm, kitty, sixels, symbols]. The default is iterm, kitty or sixels if the connected terminal supports one of these, falling back to symbols ("ANSI art") otherwise. Compress the output by using control sequences intelligently [0-9]. 0 disables, 9 enables every available optimization. Defaults to 5, except for when used with "-c none", where it defaults to 0. Use relative cursor positioning [on, off]. When on, control sequences will be used to position images relative to the cursor. When off, newlines will be used to separate rows instead for e.g. 'less -R' interop. Defaults to off. Graphics protocol passthrough [auto, none, screen, tmux]. Used to show pixel graphics from within multiplexers. Defaults to auto, which will enable passthrough if the Kitty terminal is detected along with one of the supported multiplexers. Other combinations must be enabled manually; use with the -f option to select the appropriate graphics protocol. Polite mode [on, off]. Inhibits escape sequences that on rare occasions may confuse the terminal or other programs. Defaults to off. Size and layout Align images in viewport. The following alignments are understood: left, right, top, bottom, hcenter, vcenter, center. Two orthogonal alignments can be separated by a comma, e.g. "center,right". The meaning of "center" depends on context, and defaults to "hcenter" if ambiguous. "center,center" will center along both axes. Centering vertically makes sense when used together with "--clear", or possibly as part of a scheme where the cursor is pre-positioned at the top-left corner of the view, or a subview when used with "--relative on". Center images horizontally in the view [on, off]. Defaults to off. This option is deprecated; use "--align center" instead. Clear screen before processing each file. Try to match the input's size exactly [auto, on, off]. When on, this will override other sizing options and produce output images at the exact pixel size of the inputs. In auto mode, scaling will be avoided (in exchange for padding) if the output size is equal to or slightly bigger than the input. When off, padding will never be added, and the image is scaled to fit the containing cell extent. Defaults to auto. Fit images to the view's width, potentially exceeding its height. Target font's width/height ratio. Can be specified as a real number or a fraction. Defaults to 1/2. This will only be applied in symbol mode. Lay out images in a grid of cols columns and rows rows per screenful. Either cols or rows may be omitted, e.g. --grid 4 or --grid x4, in which case cell allocations will be approximately square. If "auto" is specified, dimensions will be picked automatically. Alias for "--grid auto". Labeling [on, off]. When this is enabled, each image will be labeled with its filename. Defaults to off. Alias for "--label on". When terminal size is detected, reserve at least this many rows at the bottom as a safety margin. Can be used to prevent images from scrolling out. Defaults to 1. When terminal size is detected, reserve at least this many columns on the right-hand side as a safety margin. Defaults to 0. Scale image, respecting terminal's maximum dimensions. 1.0 approximates original pixel dimensions. Specify "max" to use all available space. Defaults to 1.0 for pixel graphics and 4.0 for symbols. Set maximum output image dimensions in columns and rows. By default this will be equal to the view size (see --view-size). Stretch image to fit output dimensions; ignore aspect. Implies --scale max. Set the view size in columns and rows. By default this will be the size of your terminal, or 80x25 if size detection fails. If one dimension is omitted (by providing a size of e.g. 80x or x25), it will be set to a reasonable approximation of infinity. Animation and timing Whether to allow animation [on, off]. Defaults to on. When off, will show a still frame from each animation. Time to show each file, in seconds. Defaults to zero for still images and for animations when multiple files are specified. If a single animation is specified, defaults to infinite, or "inf". Animations will always be played through at least once, even if duration is e.g. zero. See the "Duration" section for more. Set the speed animations will play at. This can be either a unitless multiplier (fractions are allowed), or a real number followed by "fps" to apply a specific framerate. Watch a single input file, redisplaying it whenever its contents change. Will run until manually interrupted or, if --duration is set, until it expires. Colors and processing Background color of display (color name or hex). Partially transparent input will be blended with this color. Color names are based on those provided with X.Org. Defaults to black, or the terminal's default background color when probing is enabled (see --probe). Set output color mode; one of [none, 2, 8, 16/8 16, 240, 256, full]. The 240-color mode is recommended over the 256-color one, since the lower 16 colors are unreliable and tend to differ between terminals. 16-color mode will use aixterm extensions to produce 16 foreground and background colors. The 16/8 mode allows for 8 colors plus another "bright" 8 colors in the foreground implemented with the "bold" escape sequence. 2-color mode will only emit the ANSI codes for reverse color and attribute reset, while "none" will emit no escape sequences at all. In sixel mode, "full" will dynamically generate a 256-color palette for each image or animation frame. The other modes refer to built-in palettes. "none" and "2" are interchangeable and will use the specified foreground/background colors (see --fg and --bg). If left unspecified, an optimal default will be chosen based on the current environment. Method for extracting color from an area; one of [average, median]. Median normally produces crisper output, while average may perform better on noisy images. Defaults to average. Color space used for quantization; one of [rgb, din99d]. Defaults to rgb, which is faster but less accurate. Type of dithering to apply during quantization. One of [none, ordered, diffusion, noise]. "Bayer" is a synonym for "ordered", and "fs" (Floyd-Steinberg) is a synonym for "diffusion". Defaults to "noise" in sixel mode, otherwise "none". Dimensions of grain used when dithering. Specified as width x height, where each can be one of [1, 2, 4, 8] pixels. One character cell is by definition 8 pixels across in both dimensions. Defaults to 4x4 in symbol mode and 1x1 in sixel mode. Intensity of dithering pattern. Ranges from 0.0 to infinity, with 1.0 considered neutral. Lower values tend to reduce the amount of dithering done, while higher values increase it. In practice, values higher than 10.0 are unlikely to produce useful results. Foreground color of display (color name or hex). Together with the background color specified by --bg, this specifies the terminal's palette in color modes 2 and none. Color names are based on those provided with X.Org. Defaults to white, or the terminal's default foreground color when probing is enabled (see --probe). Invert video. For display with bright backgrounds in color modes 2 and none. Swaps --fg and --bg. Image preprocessing [on, off]. Defaults to on with 16 colors or lower, off otherwise. This enhances colors and contrast prior to conversion, which can be useful in low-color modes. Threshold above which full transparency will be used [0.0 - 1.0]. Setting this to 0.0 will render a blank image, while a value of 1.0 will replace any transparency with the background color (configurable with --bg). Resource allocation Maximum number of CPU threads to use. If left unspecified or negative, this will equal available CPU cores. How hard to work in terms of CPU and memory [1-9]. 1 is the cheapest, 9 is the most accurate. Defaults to 5. Extra options for symbol encoding Leave the background color untouched. This produces character-cell output using foreground colors only, and will avoid resetting or inverting the colors. Specify character symbols to use for fill/gradients. Defaults to none. Usage is similar to that of --symbols; see below. Load glyph information from file, which can be any font file supported by FreeType (TTF, PCF, etc). The glyph outlines will replace any existing outlines, including builtins. Useful in symbol mode for custom font support or for improving quality with a specific font. Note that this only makes sense if the output terminal is using a matching font. Can be specified multiple times. Specify character symbols to employ in final output. See below for full usage and a list of symbol classes. Exit Status chafa will return 0 on success, 1 on partial failure or 2 on complete failure (including when invoked with no arguments). Status Meaning 0Success 1Some files failed to display 2All files failed to display Symbols Accepted classes for --symbols and --fill are [all, none, space, solid, stipple, block, border, diagonal, dot, quad, half, hhalf, vhalf, inverted, braille, technical, geometric, ascii, legacy, sextant, wedge, wide, narrow]. Some symbols belong to multiple classes, e.g. diagonals are also borders. You can add specific characters with the letter "u" followed by a hexadecimal code point, e.g. "ue080", or a range of code points by separating the first and last index by "..", e.g. "u100..u200". Symbol sets can also be specified as a string of UTF-8 characters in square brackets, e.g. [abcd]. To include a closing bracket in the set, escape it with a backslash. You can specify a list of classes separated by commas, or prefix them with + and - to add or remove symbols relative to the existing set. The ordering is significant. The default symbol set is block+border+space-wide-inverted for all modes except "none", which uses block+border+space-wide (including inverse symbols). Duration In order to accommodate both interactive use and batch processing, an animation's duration is determined according to a few simple rules: If one or more --duration arguments are present, the final instance is respected and applied to every file. Otherwise, if there's a controlling terminal attached (indicating there's an interactive session), and only a single file argument is provided, and that file is an animation, it will have infinite duration. Otherwise (no controlling terminal, multiple files, file is a still image), duration will be zero, causing animations to play once and then stop. Examples chafa in.gif Show a potentially animated GIF image in the terminal. If this is an animation, it will run until the user generates an interrupt (typically ctrl-c). All parameters will be autodetected based on the current environment. chafa -c full -s 200 in.gif Like the above, but force truecolor output that is 200 characters wide and calculate the height preserving the aspect of the original image. chafa -c 16 --color-space din99d --symbols -dot in.jpg Generate 16-color output with perceptual color picking and avoid using dot symbols. chafa -c none --symbols block+border-solid in.png Generate uncolored output using block and border symbols, but avoid the solid block symbol. Further Reading See the Chafa homepage for more information. Author Written by Hans Petter Jansson hpj@hpjansson.org. chafa-1.18.2/docs/manpage.css000066400000000000000000000132741517447374300157450ustar00rootroot00000000000000/* ===== * * Reset * * ===== */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } ol, ul { list-style: none; } blockquote, q { } table { border-collapse: collapse; border-spacing: 0; } a:focus { outline: none; } /* ============ * * Theme Styles * * ============ */ body { box-sizing: border-box; color:#000; font-size: 16px; font-family: 'yorktenslabnormregular', serif; line-height: 1.5; -webkit-font-smoothing: antialiased; background: #f2f2f2; border-top: 0px solid #111; border-bottom: 1px solid #111; position: relative; max-width: 640px; padding: 10px 10px; margin: 0px auto; } h1, h2, h3, h4, h5, h6 { margin: 10px 0; font-weight: 600; color:#000; letter-spacing: -0.5px; } h1 { font-size: 36px; font-weight: 600; } h2 { padding-bottom: 5px; font-size: 32px; background: url('../img/bg-hr.png') repeat-x bottom; } h2 code { font-size: 24px; } h3 { font-size: 24px; } h4 { font-size: 21px; } h5 { font-size: 18px; } h6 { font-size: 16px; } p { margin: 10px 0 15px 0; } footer p { color: #f2f2f2; } a { text-decoration: none; color: #007ee0; text-shadow: none; } a:visited { color: #802acb; } footer a:hover { color: #f2f2f2; background-color: #007ee0; } em { font-style: italic; } strong { font-weight: bold; } img { position: relative; margin: 0 auto; max-width: 739px; padding: 5px; margin: 10px 0 10px 0; } pre, code { width: 100%; color: #111; background-color: #fff; font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; font-size: 14px; border-radius: 2px; -moz-border-radius: 2px; -webkit-border-radius: 2px; } pre { width: 100%; padding: 4px; box-shadow: 0 0 4px rgba(0,0,0,.1); overflow: auto; } code { padding: 3px; margin: 0 3px; white-space: nowrap; box-shadow: 0 0 10px rgba(0,0,0,.1); } pre code { display: block; box-shadow: none; } blockquote { color: #666; margin-bottom: 20px; padding: 0 0 0 20px; border-left: 3px solid #bbb; } ul, ol, dl { margin-bottom: 15px } ul li { list-style: outside; padding-left: 0em; margin-left: 1em; } ol li { list-style: decimal inside; padding-left: 0em; margin-left: 1em; } dl dt { font-weight: bold; } dl dd { padding-left: 20px; } dl p { padding-left: 20px; } hr { height: 1px; margin-bottom: 5px; border: none; background: url('../images/bg-hr.png') repeat-x center; } table { border: 1px solid #383838; margin-bottom: 20px; text-align: left; } th { font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; padding: 4px; background: #383838; color: #fff; } td { padding: 4px; border: 1px solid #383838; } form { background: #f2f2f2; } img { /* width: 100%; */ max-width: 100%; } figure { width: 32%; display: inline-block; text-align: center; margin: 10px 0px 0px 0px; clear: text; padding: 0; vertical-align: top; } figure img { margin: 0; padding: 0; } figcaption { font-style: italic; margin: 0; padding: 0; } /* ===== * * Fonts * * ===== */ /*! * Web Fonts from Fontspring.com * * All OpenType features and all extended glyphs have been removed. * Fully installable fonts can be purchased at http://www.fontspring.com * * The fonts included in this stylesheet are subject to the End User License you purchased * from Fontspring. The fonts are protected under domestic and international trademark and * copyright law. You are prohibited from modifying, reverse engineering, duplicating, or * distributing this font software. * * (c) 2010-2019 Fontspring * * The fonts included are copyrighted by the vendor listed below. * * Vendor: Insigne Design * License URL: https://www.fontspring.com/licenses/insigne/webfont */ @font-face { font-display: swap; font-family: 'yorktenslabnormregular'; src: url('../yorktenslabnormregular-webfont.woff2') format('woff2'), url('../yorktenslabnormregular-webfont.woff') format('woff'); font-weight: normal; font-style: normal; } /* =================== * * Small Device Styles * * =================== */ @media screen and (max-width: 500px) { body { font-size: 16px; min-width: 320px; max-width: 480px; } h1 { font-size: 28px; } h2 { font-size: 24px; } h3 { font-size: 21px; } h4 { font-size: 18px; } h5 { font-size: 14px; } h6 { font-size: 12px; } code, pre { min-width: 320px; max-width: 480px; font-size: 11px; } img { width: 100%; max-width: 100%; } figure { width: 100%; max-width: 100%; padding: 5px; } figure.two { width: 100%; max-width: 100%; padding: 5px; } } chafa-1.18.2/docs/style.css000066400000000000000000000340461517447374300154750ustar00rootroot00000000000000body { font-family: cantarell, sans-serif; font-size: 16px; line-height: 1.5em; } .synopsis, .classsynopsis { /* tango:aluminium 1/2 */ background: #eeeeec; background: rgba(238, 238, 236, 0.5); border: solid 1px rgb(238, 238, 236); padding: 0.5em; } .programlisting { /* tango:sky blue 0/1 */ /* fallback for no rgba support */ background: #e6f3ff; border: solid 1px #729fcf; background: rgba(114, 159, 207, 0.1); border: solid 1px rgba(114, 159, 207, 0.2); padding: 0.5em; } .variablelist { padding: 4px; margin-left: 3em; } .variablelist td:first-child { vertical-align: top; } span.nowrap { white-space: nowrap; } div.gallery-float { float: left; padding: 10px; } div.gallery-float img { border-style: none; } div.gallery-spacer { clear: both; } a, a:visited { text-decoration: none; /* tango:sky blue 2 */ color: #3465a4; } a:hover { text-decoration: underline; /* tango:sky blue 1 */ color: #729fcf; } div.informaltable table { border-collapse: separate; border-spacing: 1em 0.3em; border: none; } div.informaltable table td, div.informaltable table th { vertical-align: top; } .function_type, .variable_type, .property_type, .signal_type, .parameter_name, .struct_member_name, .union_member_name, .define_keyword, .datatype_keyword, .typedef_keyword { text-align: right; } /* dim non-primary columns */ .c_punctuation, .function_type, .variable_type, .property_type, .signal_type, .define_keyword, .datatype_keyword, .typedef_keyword, .property_flags, .signal_flags, .parameter_annotations, .enum_member_annotations, .struct_member_annotations, .union_member_annotations { color: #888a85; } .function_type a, .function_type a:visited, .function_type a:hover, .property_type a, .property_type a:visited, .property_type a:hover, .signal_type a, .signal_type a:visited, .signal_type a:hover, .signal_flags a, .signal_flags a:visited, .signal_flags a:hover { color: #729fcf; } td p { margin: 0.25em; } div.table table { border-collapse: collapse; border-spacing: 0px; /* tango:aluminium 3 */ border: solid 1px #babdb6; } div.table table td, div.table table th { /* tango:aluminium 3 */ border: solid 1px #babdb6; padding: 3px; vertical-align: top; } div.table table th { /* tango:aluminium 2 */ background-color: #d3d7cf; } h4 { color: #555753; margin-top: 1em; margin-bottom: 1em; } hr { /* tango:aluminium 1 */ color: #d3d7cf; background: #d3d7cf; border: none 0px; height: 1px; clear: both; margin: 2.0em 0em 2.0em 0em; } dl.toc dt { padding-bottom: 0.25em; } dl.toc > dt { padding-top: 0.25em; padding-bottom: 0.25em; font-weight: bold; } dl.toc > dl { padding-bottom: 0.5em; } .parameter { font-style: normal; } .footer { padding-top: 3.5em; /* tango:aluminium 3 */ color: #babdb6; text-align: center; font-size: 80%; } .informalfigure, .figure { margin: 1em; } .informalexample, .example { margin-top: 1em; margin-bottom: 1em; } .warning { /* tango:orange 0/1 */ background: #ffeed9; background: rgba(252, 175, 62, 0.1); border-color: #ffb04f; border-color: rgba(252, 175, 62, 0.2); } .note { /* tango:chameleon 0/0.5 */ background: #d8ffb2; background: rgba(138, 226, 52, 0.1); border-color: #abf562; border-color: rgba(138, 226, 52, 0.2); } div.blockquote { border-color: #eeeeec; } .note, .warning, div.blockquote { padding: 0.5em; border-width: 1px; border-style: solid; margin: 2em; } .note p, .warning p { margin: 0; } div.warning h3.title, div.note h3.title { display: none; } p + div.section { margin-top: 1em; } div.refnamediv, div.refsynopsisdiv, div.refsect1, div.refsect2, div.toc, div.section { margin-bottom: 1em; } /* blob links */ h2 .extralinks, h3 .extralinks { float: right; /* tango:aluminium 3 */ color: #babdb6; font-size: 80%; font-weight: normal; } .lineart { color: #d3d7cf; font-weight: normal; } .annotation { /* tango:aluminium 5 */ color: #555753; font-weight: normal; } .structfield { font-style: normal; font-weight: normal; } acronym,abbr { border-bottom: 1px dotted gray; } /* code listings */ .listing_code .programlisting .normal, .listing_code .programlisting .normal a, .listing_code .programlisting .number, .listing_code .programlisting .cbracket, .listing_code .programlisting .symbol { color: #555753; } .listing_code .programlisting .comment, .listing_code .programlisting .linenum { color: #babdb6; } /* tango: aluminium 3 */ .listing_code .programlisting .function, .listing_code .programlisting .function a, .listing_code .programlisting .preproc { color: #204a87; } /* tango: sky blue 3 */ .listing_code .programlisting .string { color: #ad7fa8; } /* tango: plum */ .listing_code .programlisting .keyword, .listing_code .programlisting .usertype, .listing_code .programlisting .type, .listing_code .programlisting .type a { color: #4e9a06; } /* tango: chameleon 3 */ .listing_frame { /* tango:sky blue 1 */ border: solid 1px #729fcf; border: solid 1px rgba(114, 159, 207, 0.2); padding: 0px; } .listing_lines, .listing_code { margin-top: 0px; margin-bottom: 0px; padding: 0.5em; } .listing_lines { /* tango:sky blue 0.5 */ background: #a6c5e3; background: rgba(114, 159, 207, 0.2); /* tango:aluminium 6 */ color: #2e3436; } .listing_code { /* tango:sky blue 0 */ background: #e6f3ff; background: rgba(114, 159, 207, 0.1); } .listing_code .programlisting { /* override from previous */ border: none 0px; padding: 0px; background: none; } .listing_lines pre, .listing_code pre { margin: 0px; } @media screen { /* these have a as a first child, but since there are no parent selectors * we can't use that. */ a.footnote { position: relative; top: 0em ! important; } /* this is needed so that the local anchors are displayed below the naviagtion */ div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name] { display: inline-block; position: relative; top:-5em; } /* this seems to be a bug in the xsl style sheets when generating indexes */ div.index div.index { top: 0em; } body { padding-top: 2.5em; max-width: 60em; } p { max-width: 60em; } /* style and size the navigation bar */ table.navigation#top { position: fixed; background: #e2e2e2; border-bottom: solid 1px #babdb6; border-spacing: 5px; margin-top: 0; margin-bottom: 0; top: 0; left: 0; z-index: 10; } table.navigation#top td { padding-left: 6px; padding-right: 6px; } .navigation a, .navigation a:visited { /* tango:sky blue 3 */ color: #204a87; } .navigation a:hover { /* tango:sky blue 2 */ color: #3465a4; } td.shortcuts { /* tango:sky blue 2 */ color: #3465a4; font-size: 80%; white-space: nowrap; } td.shortcuts .dim { color: #babdb6; } .navigation .title { max-width: none; margin: 0px; font-weight: normal; } } @media screen and (min-width: 60em) { /* screen larger than 60em */ body { margin: auto; } } @media screen and (max-width: 60em) { /* screen less than 60em */ #nav_hierarchy { display: none; } #nav_interfaces { display: none; } #nav_prerequisites { display: none; } #nav_derived_interfaces { display: none; } #nav_implementations { display: none; } #nav_child_properties { display: none; } #nav_style_properties { display: none; } #nav_index { display: none; } #nav_glossary { display: none; } .gallery_image { display: none; } .property_flags { display: none; } .signal_flags { display: none; } .parameter_annotations { display: none; } .enum_member_annotations { display: none; } .struct_member_annotations { display: none; } .union_member_annotations { display: none; } /* now that a column is hidden, optimize space */ col.parameters_name { width: auto; } col.parameters_description { width: auto; } col.struct_members_name { width: auto; } col.struct_members_description { width: auto; } col.enum_members_name { width: auto; } col.enum_members_description { width: auto; } col.union_members_name { width: auto; } col.union_members_description { width: auto; } .listing_lines { display: none; } } @media print { table.navigation { visibility: collapse; display: none; } div.titlepage table.navigation { visibility: visible; display: table; background: #e2e2e2; border: solid 1px #babdb6; margin-top: 0; margin-bottom: 0; top: 0; left: 0; height: 3em; } } div.subindex { margin: 2em 7em 1em 0em; padding-left: 90px; background-position: 0 10px; background-repeat: no-repeat; min-height: 96px; } div.subindex p { color: #666; } div.subindex h2 { padding: 0; margin: 0; font-size: 230%; } div.subindex h2 a { color: #babdb6; text-decoration: inherit; } div.subindex h2 a:hover { text-decoration: underline; } div.page_title { border: none; } a.external, a.doc-link { text-decoration: none; } a.external:hover, a.doc-link:hover { text-decoration: underline; } h1 { color: #c4a000; text-shadow: white 0 -2px; border-bottom: 1px solid #d3d7cf; } h2, h3 { color: #c4a000; } div#subindex-references { background-image: url(api-reference.png); } div#subindex-guides { background-image: url(guides.png); } div#subindex-demos { background-image: url(platform-demos.png); } div#subindex-hig { background-image: url(hig.png); } .refentry hr { margin: 10px 0; } div.sidebar dt, div.toc dt { font-size: 100%; } dd dl { margin-left: 1em; } div.homeblock { margin: 0.7em 0 1.2em 0; } div.homeblock h2 { font-size: 42px; color: #0489B7; margin: 0; padding-bottom: 1ex; } div.homeblock a { color: inherit; text-decoration: none; } div.homeblock a:hover { text-decoration: underline; } div.homeblock p { margin-top: 0; font-size: 18px; line-height: 130%; } span.module-more { font-size: 75%; } dl.doc-index dt span.module-more a { font-weight: normal; } ul.language-list { -webkit-column-width: 15em; -webkit-column-gap: 2em; -moz-column-width: 15em; -moz-column-gap: 2em; column-width: 15em; column-gap: 2em; } div.sidebar.notitle { margin-top: 3em; } #footer_art.default { background-image: url(footer_art-library.png); } div.blocky1 { width: 65%; padding: 2em; display: table-cell } div.blocky2 { width: 35%; padding: 2em; display: table-cell } div.row { width: 50%; padding: 2em; display: table-row } .grid_4.subtle_box { margin-top: 1em; } span.citem { display: table-cell; text-align: center } #platform-overview a { background: #babdb6; display: inline-block; padding: 5px 10px; -moz-border-radius: 3px; -webkit-border-radius: 3px; text-decoration: none; color: #000; margin: 5px; width: 65px; } #platform-overview a:hover { box-shadow: 0 1px 2px #0489d7, 0 1px rgba(255, 255, 255, 0.4) inset; color: #0489d7; } #platform-overview p { padding: 0; margin: 0; padding-left: 5px; margin-bottom: 0; padding-bottom: 0; font-size: 10px; } #api-doc-box { float: right; width: 205px; margin: 0; } #api-doc-box input { width: 190px; } #api-doc-box h2 { font-size: 20px; } table#platform-overview { width: 700px; table-layout: fixed; } table#platform-overview th { width: 14%; } table#platform-overview td { background: #888a85; -moz-border-radius: 5px; -webkit-border-radius: 5px; color: #2e3436; margin-bottom: 10px; border: 2px solid white; } .synopsis, .classsynopsis { background: #eee; border: solid 1px #aaa; padding: 0.5em; } .programlisting { background: #eef; border: solid 1px #aaf; padding: 0.5em; } .variablelist { padding: 4px; margin-left: 3em; } .variablelist td:first-child { vertical-align: top; } .variablelist p { margin: 0; } .listing_lines, .listing_code { margin-top: 0px; margin-bottom: 0px; padding: 0.5em; } .listing_lines { /* tango:sky blue 0.5 */ background: #a6c5e3; /* tango:aluminium 6 */ color: #2e3436; } .listing_code { /* tango:sky blue 0 */ background: #e6f3ff; } div.gtk-doc dt { color: #2e3456; margin: 0; } div.gtk-doc div.index dt { line-height: 1.2; font-size: 100%; } div.gtk-doc td.shortcuts { background: white; border: 1px solid #d3d7cf; text-align: center; } div.gtk-doc span.refpurpose { color: #555; font-weight: normal; } #container .gsc-control-cse { background: transparent; } #container ul.i18n { /* force left-to-right for language sidebar */ direction: ltr; } table, table tr, table td, table th, table tfoot, table thead, table tbody { /* those properties are reset by reset.css, restore them */ border: 1px none #2E3436; } #container div.blockquote { background-image: none; } dt { color: inherit; } acronym { border-bottom: 1px dotted; } table tbody tr td p { margin: 0.5ex 1em 0.5ex 0; } br + br { display: none; } .docbook-legal-stuff > h3 { text-align: center; cursor: pointer; font-size: 100%; } .docbook-legal-stuff > div { font-size: 80%; } .docbook-legal-stuff > div dt { font-size: 100%; } img.application-icon { padding-right: 1ex; position: relative; top: 0.8ex; max-width: 48px; max-height: 48px; } h1 img.application-icon { top: 0.4ex; } div#frontpage-indexes { clear: both; padding-top: 2em; } div#frontpage-indexes > div { margin: 0 1em 1em 0; } p.doc-feedback { margin-top: 2em; } img.attachment { max-width: 100%; } div.body.homepage { background: url(cogs.png) 90% 150px no-repeat; } div#welcome h1 { color: #c4a000; text-shadow: white 0 -2px; border-bottom: 1px solid #d3d7cf; } div#welcome div { width: 96%; } div#welcome p { font-size: 150%; width: 65%; } pre.cmdsynopsis { white-space: normal; word-break: keep-all; } h2, h3, dl dt { margin: 0; } p { margin: 0.4em 0; } p.module-more a { text-decoration: none; } p.module-more a:hover { text-decoration: underline; } dt .module-more { font-weight: normal; } dl.doc-index dt{ font-size: 120%; } p.no-translation { opacity: 0.6; } /* =================== * * Small Device Styles * * =================== */ @media screen and (max-width: 500px) { font-size: 18px; } chafa-1.18.2/docs/using.xml000066400000000000000000000101621517447374300154630ustar00rootroot00000000000000 Using Chafa in your application 3 Chafa Library Using Chafa in your application How to use Chafa Compiling your application To compile an application using Chafa, you need to tell the compiler where to find the Chafa header files and libraries. This is done with the pkg-config utility. The following interactive shell session demonstrates how pkg-config is used (the actual output on your system may be different): $ pkg-config --cflags chafa -I/usr/include/chafa -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include $ pkg-config --libs chafa -lm -lchafa -lglib-2.0 See the pkg-config website for more information about pkg-config. The simplest way to compile a program is to use the command substitution feature of the shell. If you enclose a command in backticks (not single quotes), then its output will be substituted into the command line before execution. So to compile Hello, World program using Chafa you would type the following: $ cc hello.c `pkg-config --cflags --libs chafa` -o hello Note that the name of the file must come before the other options (such as pkg-config), or else you may get an error from the linker. When using Chafa in your program, you only need to include the toplevel header chafa.h. An example The following program turns a 3x3 red X stored in a const array into an ANSI string and prints it to stdout. It can be compiled as described in the previous section and run without arguments. Note that it will output UTF-8 regardless of the current locale. #include <chafa.h> #include <stdio.h> #define PIX_WIDTH 3 #define PIX_HEIGHT 3 #define N_CHANNELS 4 int main (int argc, char *argv []) { const guint8 pixels [PIX_WIDTH * PIX_HEIGHT * N_CHANNELS] = { 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff }; ChafaSymbolMap *symbol_map; ChafaCanvasConfig *config; ChafaCanvas *canvas; GString *gs; /* Specify the symbols we want */ symbol_map = chafa_symbol_map_new (); chafa_symbol_map_add_by_tags (symbol_map, CHAFA_SYMBOL_TAG_ALL); /* Set up a configuration with the symbols and the canvas size in characters */ config = chafa_canvas_config_new (); chafa_canvas_config_set_geometry (config, 40, 20); chafa_canvas_config_set_symbol_map (config, symbol_map); /* Create canvas */ canvas = chafa_canvas_new (config); /* Draw pixels to canvas */ chafa_canvas_draw_all_pixels (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, pixels, PIX_WIDTH, PIX_HEIGHT, PIX_WIDTH * N_CHANNELS); /* Generate a string that will show the canvas contents on a terminal */ gs = chafa_canvas_print (canvas, NULL); /* Print the string */ fwrite (gs->str, sizeof (char), gs->len, stdout); fputc ('\n', stdout); /* Free resources */ g_string_free (gs, TRUE); chafa_canvas_unref (canvas); chafa_canvas_config_unref (config); chafa_symbol_map_unref (symbol_map); return 0; } chafa-1.18.2/docs/version.xml.in000066400000000000000000000000201517447374300164200ustar00rootroot00000000000000@CHAFA_VERSION@ chafa-1.18.2/examples/000077500000000000000000000000001517447374300145025ustar00rootroot00000000000000chafa-1.18.2/examples/Makefile.am000066400000000000000000000000651517447374300165370ustar00rootroot00000000000000EXTRA_DIST = \ adaptive.c \ example.c \ ncurses.c chafa-1.18.2/examples/adaptive.c000066400000000000000000000205331517447374300164460ustar00rootroot00000000000000/* This file is in the public domain, and you are free to use it as you see fit. * * Compile with: * * cc adaptive.c -o adaptive $(pkg-config --libs --cflags chafa) */ #include #include #include /* Include after chafa.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include #else # include /* ioctl */ #endif typedef struct { gint width_cells, height_cells; gint width_pixels, height_pixels; } TermSize; static void detect_terminal (ChafaTermInfo **term_info_out, ChafaCanvasMode *mode_out, ChafaPixelMode *pixel_mode_out, ChafaPassthrough *passthrough_out, ChafaSymbolMap **symbol_map_out) { ChafaCanvasMode mode; ChafaPixelMode pixel_mode; ChafaPassthrough passthrough; ChafaTermInfo *term_info; gchar **envp; /* Examine the environment variables and guess what the terminal can do */ envp = g_get_environ (); term_info = chafa_term_db_detect (chafa_term_db_get_default (), envp); /* Pick the most high-quality rendering possible */ mode = chafa_term_info_get_best_canvas_mode (term_info); pixel_mode = chafa_term_info_get_best_pixel_mode (term_info); passthrough = chafa_term_info_get_is_pixel_passthrough_needed (term_info, pixel_mode) ? chafa_term_info_get_passthrough_type (term_info) : CHAFA_PASSTHROUGH_NONE; *symbol_map_out = chafa_symbol_map_new (); chafa_symbol_map_add_by_tags (*symbol_map_out, chafa_term_info_get_safe_symbol_tags (term_info)); /* Hand over the information to caller */ *term_info_out = term_info; *mode_out = mode; *pixel_mode_out = pixel_mode; *passthrough_out = passthrough; /* Cleanup */ g_strfreev (envp); } static void get_tty_size (TermSize *term_size_out) { TermSize term_size; term_size.width_cells = term_size.height_cells = term_size.width_pixels = term_size.height_pixels = -1; #ifdef G_OS_WIN32 { HANDLE chd = GetStdHandle (STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csb_info; if (chd != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo (chd, &csb_info)) { term_size.width_cells = csb_info.srWindow.Right - csb_info.srWindow.Left + 1; term_size.height_cells = csb_info.srWindow.Bottom - csb_info.srWindow.Top + 1; } } #else { struct winsize w; gboolean have_winsz = FALSE; if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &w) >= 0 || ioctl (STDERR_FILENO, TIOCGWINSZ, &w) >= 0 || ioctl (STDIN_FILENO, TIOCGWINSZ, &w) >= 0) have_winsz = TRUE; if (have_winsz) { term_size.width_cells = w.ws_col; term_size.height_cells = w.ws_row; term_size.width_pixels = w.ws_xpixel; term_size.height_pixels = w.ws_ypixel; } } #endif if (term_size.width_cells <= 0) term_size.width_cells = -1; if (term_size.height_cells <= 2) term_size.height_cells = -1; /* If .ws_xpixel and .ws_ypixel are filled out, we can calculate * aspect information for the font used. Sixel-capable terminals * like mlterm set these fields, but most others do not. */ if (term_size.width_pixels <= 0 || term_size.height_pixels <= 0) { term_size.width_pixels = -1; term_size.height_pixels = -1; } *term_size_out = term_size; } static void tty_init (void) { #ifdef G_OS_WIN32 { HANDLE chd = GetStdHandle (STD_OUTPUT_HANDLE); saved_console_output_cp = GetConsoleOutputCP (); saved_console_input_cp = GetConsoleCP (); /* Enable ANSI escape sequence parsing etc. on MS Windows command prompt */ if (chd != INVALID_HANDLE_VALUE) { if (!SetConsoleMode (chd, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN)) win32_stdout_is_file = TRUE; } /* Set UTF-8 code page I/O */ SetConsoleOutputCP (65001); SetConsoleCP (65001); } #endif } static GString * convert_image (const void *pixels, gint pix_width, gint pix_height, gint pix_rowstride, ChafaPixelType pixel_type, gint width_cells, gint height_cells, gint cell_width, gint cell_height) { ChafaTermInfo *term_info; ChafaCanvasMode mode; ChafaPixelMode pixel_mode; ChafaPassthrough passthrough; ChafaSymbolMap *symbol_map; ChafaCanvasConfig *config; ChafaCanvas *canvas; GString *printable; detect_terminal (&term_info, &mode, &pixel_mode, &passthrough, &symbol_map); /* Set up a configuration based on detected characteristics */ config = chafa_canvas_config_new (); chafa_canvas_config_set_canvas_mode (config, mode); chafa_canvas_config_set_pixel_mode (config, pixel_mode); chafa_canvas_config_set_geometry (config, width_cells, height_cells); chafa_canvas_config_set_passthrough (config, passthrough); chafa_canvas_config_set_symbol_map (config, symbol_map); if (cell_width > 0 && cell_height > 0) { /* We know the pixel dimensions of each cell. Store it in the config. */ chafa_canvas_config_set_cell_geometry (config, cell_width, cell_height); } /* Create canvas */ canvas = chafa_canvas_new (config); /* Draw pixels to the canvas */ chafa_canvas_draw_all_pixels (canvas, pixel_type, pixels, pix_width, pix_height, pix_rowstride); /* Build printable string */ printable = chafa_canvas_print (canvas, term_info); /* Clean up and return */ chafa_canvas_unref (canvas); chafa_canvas_config_unref (config); chafa_symbol_map_unref (symbol_map); chafa_term_info_unref (term_info); return printable; } #define PIX_WIDTH 3 #define PIX_HEIGHT 3 #define N_CHANNELS 4 int main (int argc, char *argv []) { const guint8 pixels [PIX_WIDTH * PIX_HEIGHT * N_CHANNELS] = { 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff }; TermSize term_size; GString *printable; gfloat font_ratio = 0.5; gint cell_width = -1, cell_height = -1; /* Size of each character cell, in pixels */ gint width_cells, height_cells; /* Size of output image, in cells */ /* Initialize the tty device if needed */ tty_init (); /* Get the terminal dimensions and determine the output size, preserving * aspect ratio */ get_tty_size (&term_size); if (term_size.width_cells > 0 && term_size.height_cells > 0 && term_size.width_pixels > 0 && term_size.height_pixels > 0) { cell_width = term_size.width_pixels / term_size.width_cells; cell_height = term_size.height_pixels / term_size.height_cells; font_ratio = (gdouble) cell_width / (gdouble) cell_height; } width_cells = term_size.width_cells; height_cells = term_size.height_cells; chafa_calc_canvas_geometry (PIX_WIDTH, PIX_HEIGHT, &width_cells, &height_cells, font_ratio, TRUE, FALSE); /* Convert the image to a printable string */ printable = convert_image (pixels, PIX_WIDTH, PIX_HEIGHT, PIX_WIDTH * N_CHANNELS, CHAFA_PIXEL_RGBA8_UNASSOCIATED, width_cells, height_cells, cell_width, cell_height); /* Print the string */ fwrite (printable->str, sizeof (char), printable->len, stdout); fputc ('\n', stdout); /* Free resources and exit */ g_string_free (printable, TRUE); return 0; } chafa-1.18.2/examples/example.c000066400000000000000000000036231517447374300163050ustar00rootroot00000000000000/* This file is in the public domain, and you are free to use it as you see fit. * * Compile with: * * cc example.c -o example $(pkg-config --libs --cflags chafa) */ #include #include #define PIX_WIDTH 3 #define PIX_HEIGHT 3 #define N_CHANNELS 4 int main (int argc, char *argv []) { const guint8 pixels [PIX_WIDTH * PIX_HEIGHT * N_CHANNELS] = { 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff }; ChafaSymbolMap *symbol_map; ChafaCanvasConfig *config; ChafaCanvas *canvas; GString *gs; /* Specify the symbols we want */ symbol_map = chafa_symbol_map_new (); chafa_symbol_map_add_by_tags (symbol_map, CHAFA_SYMBOL_TAG_ALL); /* Set up a configuration with the symbols and the canvas size in characters */ config = chafa_canvas_config_new (); chafa_canvas_config_set_geometry (config, 40, 20); chafa_canvas_config_set_symbol_map (config, symbol_map); /* Create canvas */ canvas = chafa_canvas_new (config); /* Draw pixels to canvas */ chafa_canvas_draw_all_pixels (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, pixels, PIX_WIDTH, PIX_HEIGHT, PIX_WIDTH * N_CHANNELS); /* Generate a string that will show the canvas contents on a terminal */ gs = chafa_canvas_print (canvas, NULL); /* Print the string */ fwrite (gs->str, sizeof (char), gs->len, stdout); fputc ('\n', stdout); /* Free resources */ g_string_free (gs, TRUE); chafa_canvas_unref (canvas); chafa_canvas_config_unref (config); chafa_symbol_map_unref (symbol_map); return 0; } chafa-1.18.2/examples/ncurses.c000066400000000000000000000141301517447374300163270ustar00rootroot00000000000000/* Example program that shows how to use a Chafa canvas with ncurses. * * To build: * * gcc ncurses.c $(pkg-config --libs --cflags chafa) $(ncursesw6-config --libs --cflags) -o ncurses */ #include #include #include /* Parameters for gradient pixmap. It will be scaled automatically to fit the canvas, * so this just needs to be big enough to avoid it getting too blurry. The number * of channels is always four, corresponding to CHAFA_PIXEL_RGBA8_UNASSOCIATED. */ #define PIXMAP_WIDTH 1024 #define PIXMAP_HEIGHT 1024 #define PIXMAP_N_CHANNELS 4 /* Terminal size detected in main loop */ static int screen_width, screen_height; static ChafaCanvasMode detect_canvas_mode (void) { /* COLORS is a global variable defined by ncurses. It depends on termcap * for the terminal specified in TERM. In order to test the various modes, you * could try running this program with either of these: * * TERM=xterm * TERM=xterm-16color * TERM=xterm-256color * TERM=xterm-direct */ return COLORS >= (1 << 24) ? CHAFA_CANVAS_MODE_TRUECOLOR : COLORS >= (1 << 8) ? CHAFA_CANVAS_MODE_INDEXED_240 : COLORS >= (1 << 4) ? CHAFA_CANVAS_MODE_INDEXED_16 : COLORS >= (1 << 3) ? CHAFA_CANVAS_MODE_INDEXED_8 : CHAFA_CANVAS_MODE_FGBG; } static ChafaCanvas * create_canvas (void) { ChafaSymbolMap *symbol_map; ChafaCanvasConfig *config; ChafaCanvas *canvas; ChafaCanvasMode mode = detect_canvas_mode (); /* Specify the symbols we want: Box drawing and block elements are both * useful and widely supported. */ symbol_map = chafa_symbol_map_new (); chafa_symbol_map_add_by_tags (symbol_map, CHAFA_SYMBOL_TAG_SPACE); chafa_symbol_map_add_by_tags (symbol_map, CHAFA_SYMBOL_TAG_BLOCK); chafa_symbol_map_add_by_tags (symbol_map, CHAFA_SYMBOL_TAG_BORDER); /* Set up a configuration with the symbols and the canvas size in characters */ config = chafa_canvas_config_new (); chafa_canvas_config_set_canvas_mode (config, mode); chafa_canvas_config_set_symbol_map (config, symbol_map); /* Reserve one row below canvas for status text */ chafa_canvas_config_set_geometry (config, screen_width, screen_height - 1); /* Apply tweaks for low-color modes */ if (mode == CHAFA_CANVAS_MODE_INDEXED_240) { /* We get better color fidelity using DIN99d in 240-color mode. * This is not needed in 16-color mode because it uses an extra * preprocessing step instead, which usually performs better. */ chafa_canvas_config_set_color_space (config, CHAFA_COLOR_SPACE_DIN99D); } if (mode == CHAFA_CANVAS_MODE_FGBG) { /* Enable dithering in monochromatic mode so gradients become * somewhat legible. */ chafa_canvas_config_set_dither_mode (config, CHAFA_DITHER_MODE_ORDERED); } /* Create canvas */ canvas = chafa_canvas_new (config); chafa_symbol_map_unref (symbol_map); chafa_canvas_config_unref (config); return canvas; } static void paint_canvas (ChafaCanvas *canvas) { guint8 *pixmap; int x, y; /* Generate a gradient pixmap */ pixmap = g_malloc (PIXMAP_WIDTH * PIXMAP_HEIGHT * PIXMAP_N_CHANNELS); for (y = 0; y < PIXMAP_HEIGHT; y++) { for (x = 0; x < PIXMAP_WIDTH; x++) { guint8 *pixel = pixmap + (y * PIXMAP_WIDTH + x) * PIXMAP_N_CHANNELS; pixel [0] = (x * 255) / PIXMAP_WIDTH; pixel [1] = (y * 255) / PIXMAP_HEIGHT; pixel [2] = 0; pixel [3] = 255; } } /* Paint it to the canvas */ chafa_canvas_draw_all_pixels (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, pixmap, PIXMAP_WIDTH, PIXMAP_HEIGHT, PIXMAP_WIDTH * PIXMAP_N_CHANNELS); g_free (pixmap); } static void canvas_to_ncurses (ChafaCanvas *canvas) { ChafaCanvasMode mode = detect_canvas_mode (); int pair = 256; /* Reserve lower pairs for application in direct-color mode */ int x, y; for (y = 0; y < screen_height - 1; y++) { for (x = 0; x < screen_width; x++) { wchar_t wc [2]; cchar_t cch; int fg, bg; /* wchar_t is 32-bit in glibc, but this may not work on e.g. Windows */ wc [0] = chafa_canvas_get_char_at (canvas, x, y); wc [1] = 0; if (mode == CHAFA_CANVAS_MODE_TRUECOLOR) { chafa_canvas_get_colors_at (canvas, x, y, &fg, &bg); init_extended_pair (pair, fg, bg); } else if (mode == CHAFA_CANVAS_MODE_FGBG) { pair = 0; } else { /* In indexed color mode, we've probably got enough pairs * to just let ncurses allocate and reuse as needed. */ chafa_canvas_get_raw_colors_at (canvas, x, y, &fg, &bg); pair = alloc_pair (fg, bg); } setcchar (&cch, wc, A_NORMAL, -1, &pair); mvadd_wch (y, x, &cch); pair++; } } } static void show_image (void) { ChafaCanvas *canvas; canvas = create_canvas (); paint_canvas (canvas); canvas_to_ncurses (canvas); mvprintw (screen_height - 1, 0, "%d colors detected. Try resizing, or press any key to exit.", COLORS); chafa_canvas_unref (canvas); } int main (int argc, char *argv []) { int running = TRUE; /* Set up locale to get proper Unicode */ setlocale (LC_ALL, ""); /* Start interactive ncurses session */ initscr (); start_color (); use_default_colors (); raw (); keypad (stdscr, TRUE); noecho (); curs_set (0); /* Keep running until a key is pressed. Handle terminal resize. */ while (running) { clear (); getmaxyx (stdscr, screen_height, screen_width); show_image (); refresh (); if (getch () != KEY_RESIZE) running = FALSE; } endwin (); return 0; } chafa-1.18.2/libnsgif/000077500000000000000000000000001517447374300144615ustar00rootroot00000000000000chafa-1.18.2/libnsgif/COPYING000066400000000000000000000021071517447374300155140ustar00rootroot00000000000000Copyright (C) 2004 Richard Wilson Copyright (C) 2008 Sean Fox Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. chafa-1.18.2/libnsgif/Makefile.am000066400000000000000000000003541517447374300165170ustar00rootroot00000000000000noinst_LTLIBRARIES = libnsgif.la libnsgif_la_SOURCES = libnsgif.c libnsgif.h lzw.c lzw.h log.h libnsgif_la_CFLAGS = ${LIBNSGIF_CFLAGS} -I${top_srcdir} libnsgif_la_LDFLAGS = ${LIBNSGIF_LDFLAGS} EXTRA_DIST = COPYING README README-chafa chafa-1.18.2/libnsgif/README000066400000000000000000000035621517447374300153470ustar00rootroot00000000000000libnsgif - Decoding GIF files ============================= The functions provided by this library allow for efficient progressive GIF decoding. Whilst the initialisation does not ensure that there is sufficient image data to complete the entire frame, it does ensure that the information provided is valid. Any subsequent attempts to decode an initialised GIF are guaranteed to succeed, and any bytes of the image not present are assumed to be totally transparent. To begin decoding a GIF, the 'gif' structure must be initialised with the 'gif_data' and 'buffer_size' set to their initial values. The 'buffer_position' should initially be 0, and will be internally updated as the decoding commences. The caller should then repeatedly call gif_initialise() with the structure until the function returns 1, or no more data is avaliable. Once the initialisation has begun, the decoder completes the variables 'frame_count' and 'frame_count_partial'. The former being the total number of frames that have been successfully initialised, and the latter being the number of frames that a partial amount of data is available for. This assists the caller in managing the animation whilst decoding is continuing. To decode a frame, the caller must use gif_decode_frame() which updates the current 'frame_image' to reflect the desired frame. The required 'disposal_method' is also updated to reflect how the frame should be plotted. The caller must not assume that the current 'frame_image' will be valid between calls if initialisation is still occuring, and should either always request that the frame is decoded (no processing will occur if the 'decoded_frame' has not been invalidated by initialisation) or perform the check itself. It should be noted that gif_finalise() should always be called, even if no frames were initialised. Additionally, it is the responsibility of the caller to free 'gif_data'. chafa-1.18.2/libnsgif/README-chafa000066400000000000000000000007671517447374300164130ustar00rootroot00000000000000Notes on libnsgif as bundled with Chafa ======================================= The libnsgif bundled with Chafa is currently based on version 0.2.1. The original source is here: http://www.netsurf-browser.org/projects/libnsgif/ It has been slightly adapted from the original to make it fit into the Chafa build. It may have further modifications to make it more convenient to use in this context. It is my intention to submit any generally useful enhancements made for potential inclusion upstream. chafa-1.18.2/libnsgif/libnsgif.c000066400000000000000000001376501517447374300164360ustar00rootroot00000000000000/* * Copyright 2004 Richard Wilson * Copyright 2008 Sean Fox * * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ #include #include #include #include #include #include #include "libnsgif.h" #include "log.h" #include "lzw.h" /** * * \file * \brief GIF image decoder * * The GIF format is thoroughly documented; a full description can be found at * http://www.w3.org/Graphics/GIF/spec-gif89a.txt * * \todo Plain text and comment extensions should be implemented. */ /** Maximum colour table size */ #define GIF_MAX_COLOURS 256 /** Internal flag that the colour table needs to be processed */ #define GIF_PROCESS_COLOURS 0xaa000000 /** Internal flag that a frame is invalid/unprocessed */ #define GIF_INVALID_FRAME -1 /** Transparent colour */ #define GIF_TRANSPARENT_COLOUR 0x00 /* GIF Flags */ /* #define GIF_FRAME_COMBINE 1 */ /* Unused macro */ #define GIF_FRAME_CLEAR 2 #define GIF_FRAME_RESTORE 3 #define GIF_FRAME_QUIRKS_RESTORE 4 #define GIF_IMAGE_SEPARATOR 0x2c #define GIF_INTERLACE_MASK 0x40 #define GIF_COLOUR_TABLE_MASK 0x80 #define GIF_COLOUR_TABLE_SIZE_MASK 0x07 #define GIF_EXTENSION_INTRODUCER 0x21 #define GIF_EXTENSION_GRAPHIC_CONTROL 0xf9 #define GIF_DISPOSAL_MASK 0x1c #define GIF_TRANSPARENCY_MASK 0x01 #define GIF_EXTENSION_COMMENT 0xfe /* #define GIF_EXTENSION_PLAIN_TEXT 0x01 */ /* Unused macro */ #define GIF_EXTENSION_APPLICATION 0xff #define GIF_BLOCK_TERMINATOR 0x00 #define GIF_TRAILER 0x3b /** standard GIF header size */ #define GIF_STANDARD_HEADER_SIZE 13 /** * Updates the sprite memory size * * \param gif The animation context * \param width The width of the sprite * \param height The height of the sprite * \return GIF_INSUFFICIENT_MEMORY for a memory error GIF_OK for success */ static gif_result gif_initialise_sprite(gif_animation *gif, unsigned int width, unsigned int height) { unsigned int max_width; unsigned int max_height; struct bitmap *buffer; /* Check if we've changed */ if ((width <= gif->width) && (height <= gif->height)) { return GIF_OK; } /* Get our maximum values */ max_width = (width > gif->width) ? width : gif->width; max_height = (height > gif->height) ? height : gif->height; /* Allocate some more memory */ assert(gif->bitmap_callbacks.bitmap_create); buffer = gif->bitmap_callbacks.bitmap_create(max_width, max_height); if (buffer == NULL) { return GIF_INSUFFICIENT_MEMORY; } assert(gif->bitmap_callbacks.bitmap_destroy); gif->bitmap_callbacks.bitmap_destroy(gif->frame_image); gif->frame_image = buffer; gif->width = max_width; gif->height = max_height; /* Invalidate our currently decoded image */ gif->decoded_frame = GIF_INVALID_FRAME; return GIF_OK; } /** * Attempts to initialise the frame's extensions * * \param gif The animation context * \param frame The frame number * @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the * frame GIF_OK for successful initialisation. */ static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int frame) { const unsigned char *gif_data, *gif_end; intmax_t gif_bytes; intmax_t block_size; /* Get our buffer position etc. */ gif_data = (const unsigned char *)(gif->gif_data + gif->buffer_position); gif_end = (const unsigned char *)(gif->gif_data + gif->buffer_size); /* Initialise the extensions */ while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) { ++gif_data; if ((gif_bytes = (gif_end - gif_data)) < 1) { return GIF_INSUFFICIENT_FRAME_DATA; } /* Switch on extension label */ switch (gif_data[0]) { case GIF_EXTENSION_GRAPHIC_CONTROL: /* 6-byte Graphic Control Extension is: * * +0 CHAR Graphic Control Label * +1 CHAR Block Size * +2 CHAR __Packed Fields__ * 3BITS Reserved * 3BITS Disposal Method * 1BIT User Input Flag * 1BIT Transparent Color Flag * +3 SHORT Delay Time * +5 CHAR Transparent Color Index */ if (gif_bytes < 6) { return GIF_INSUFFICIENT_FRAME_DATA; } gif->frames[frame].frame_delay = gif_data[3] | (gif_data[4] << 8); if (gif_data[2] & GIF_TRANSPARENCY_MASK) { gif->frames[frame].transparency = true; gif->frames[frame].transparency_index = gif_data[5]; } gif->frames[frame].disposal_method = ((gif_data[2] & GIF_DISPOSAL_MASK) >> 2); /* I have encountered documentation and GIFs in the * wild that use 0x04 to restore the previous frame, * rather than the officially documented 0x03. I * believe some (older?) software may even actually * export this way. We handle this as a type of * "quirks" mode. */ if (gif->frames[frame].disposal_method == GIF_FRAME_QUIRKS_RESTORE) { gif->frames[frame].disposal_method = GIF_FRAME_RESTORE; } if ((intmax_t)(2 + gif_data[1]) > gif_bytes) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += (2 + gif_data[1]); break; case GIF_EXTENSION_APPLICATION: /* 14-byte+ Application Extension is: * * +0 CHAR Application Extension Label * +1 CHAR Block Size * +2 8CHARS Application Identifier * +10 3CHARS Appl. Authentication Code * +13 1-256 Application Data (Data sub-blocks) */ if (gif_bytes < 17) { return GIF_INSUFFICIENT_FRAME_DATA; } if ((gif_data[1] == 0x0b) && (strncmp((const char *) gif_data + 2, "NETSCAPE2.0", 11) == 0) && (gif_data[13] == 0x03) && (gif_data[14] == 0x01)) { gif->loop_count = gif_data[15] | (gif_data[16] << 8); } if ((intmax_t)(2 + gif_data[1]) > gif_bytes) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += (2 + gif_data[1]); break; case GIF_EXTENSION_COMMENT: /* Move the pointer to the first data sub-block Skip 1 * byte for the extension label */ ++gif_data; break; default: /* Move the pointer to the first data sub-block Skip 2 * bytes for the extension label and size fields Skip * the extension size itself */ if (gif_bytes < 2) { return GIF_INSUFFICIENT_FRAME_DATA; } if ((intmax_t)(2 + gif_data[1]) > gif_bytes) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += (2 + gif_data[1]); } /* Repeatedly skip blocks until we get a zero block or run out * of data This data is ignored by this gif decoder */ gif_bytes = (gif_end - gif_data); block_size = 0; while (gif_data < gif_end && gif_data[0] != GIF_BLOCK_TERMINATOR) { block_size = gif_data[0] + 1; if ((gif_bytes -= block_size) < 0) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += block_size; } if (gif_data >= gif_end) { return GIF_INSUFFICIENT_FRAME_DATA; } ++gif_data; } /* Set buffer position and return */ gif->buffer_position = (gif_data - gif->gif_data); return GIF_OK; } /** * Attempts to initialise the next frame * * \param gif The animation context * \return error code * - GIF_INSUFFICIENT_DATA for insufficient data to do anything * - GIF_FRAME_DATA_ERROR for GIF frame data error * - GIF_INSUFFICIENT_MEMORY for insufficient memory to process * - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame * - GIF_DATA_ERROR for GIF error (invalid frame header) * - GIF_OK for successful decoding * - GIF_WORKING for successful decoding if more frames are expected */ static gif_result gif_initialise_frame(gif_animation *gif) { int frame; gif_frame *temp_buf; const unsigned char *gif_data, *gif_end; intmax_t gif_bytes; unsigned int flags = 0; unsigned int width, height, offset_x, offset_y; intmax_t block_size, colour_table_size; bool first_image = true; gif_result return_value; bool premature_eof = false; /* Get the frame to decode and our data position */ frame = gif->frame_count; /* Get our buffer position etc. */ gif_data = (const unsigned char *)(gif->gif_data + gif->buffer_position); gif_end = (const unsigned char *)(gif->gif_data + gif->buffer_size); gif_bytes = (gif_end - gif_data); /* Check if we've finished */ if ((gif_bytes > 0) && (gif_data[0] == GIF_TRAILER)) { return GIF_OK; } /* Check if there is enough data remaining. The shortest block of data * is a 4-byte comment extension + 1-byte block terminator + 1-byte gif * trailer */ if (gif_bytes < 6) { return GIF_INSUFFICIENT_DATA; } /* We could theoretically get some junk data that gives us millions of * frames, so we ensure that we don't have a silly number */ if (frame > 262143) return GIF_FRAME_DATA_ERROR; /* Get some memory to store our pointers in etc. */ if ((int)gif->frame_holders <= frame) { /* Allocate more memory */ temp_buf = (gif_frame *)realloc(gif->frames, (frame + 1) * sizeof(gif_frame)); if (temp_buf == NULL) { return GIF_INSUFFICIENT_MEMORY; } gif->frames = temp_buf; gif->frame_holders = frame + 1; /* Clear all frame fields */ memset(&gif->frames[frame], 0, sizeof(gif_frame)); } /* Store our frame pointer. We would do it when allocating except we * start off with one frame allocated so we can always use realloc. */ gif->frames[frame].frame_pointer = gif->buffer_position; gif->frames[frame].display = false; gif->frames[frame].virgin = true; gif->frames[frame].disposal_method = 0; gif->frames[frame].transparency = false; gif->frames[frame].frame_delay = 0; gif->frames[frame].redraw_required = false; /* Invalidate any previous decoding we have of this frame */ if (gif->decoded_frame == frame) { gif->decoded_frame = GIF_INVALID_FRAME; } /* We pretend to initialise the frames, but really we just skip over * all the data contained within. This is all basically a cut down * version of gif_decode_frame that doesn't have any of the LZW bits in * it. */ /* Initialise any extensions */ gif->buffer_position = gif_data - gif->gif_data; return_value = gif_initialise_frame_extensions(gif, frame); if (return_value != GIF_OK) { return return_value; } gif_data = (gif->gif_data + gif->buffer_position); gif_bytes = (gif_end - gif_data); /* Check if we've finished */ if ((gif_bytes = (gif_end - gif_data)) < 1) { return GIF_INSUFFICIENT_FRAME_DATA; } if (gif_data[0] == GIF_TRAILER) { gif->buffer_position = (gif_data - gif->gif_data); gif->frame_count = frame + 1; return GIF_OK; } /* If we're not done, there should be an image descriptor */ if (gif_data[0] != GIF_IMAGE_SEPARATOR) { return GIF_FRAME_DATA_ERROR; } /* Do some simple boundary checking */ if (gif_bytes < 10) { return GIF_INSUFFICIENT_FRAME_DATA; } offset_x = gif_data[1] | (gif_data[2] << 8); offset_y = gif_data[3] | (gif_data[4] << 8); width = gif_data[5] | (gif_data[6] << 8); height = gif_data[7] | (gif_data[8] << 8); /* Set up the redraw characteristics. We have to check for extending * the area due to multi-image frames. */ if (!first_image) { if (gif->frames[frame].redraw_x > offset_x) { gif->frames[frame].redraw_width += (gif->frames[frame].redraw_x - offset_x); gif->frames[frame].redraw_x = offset_x; } if (gif->frames[frame].redraw_y > offset_y) { gif->frames[frame].redraw_height += (gif->frames[frame].redraw_y - offset_y); gif->frames[frame].redraw_y = offset_y; } if ((offset_x + width) > (gif->frames[frame].redraw_x + gif->frames[frame].redraw_width)) { gif->frames[frame].redraw_width = (offset_x + width) - gif->frames[frame].redraw_x; } if ((offset_y + height) > (gif->frames[frame].redraw_y + gif->frames[frame].redraw_height)) { gif->frames[frame].redraw_height = (offset_y + height) - gif->frames[frame].redraw_y; } } else { first_image = false; gif->frames[frame].redraw_x = offset_x; gif->frames[frame].redraw_y = offset_y; gif->frames[frame].redraw_width = width; gif->frames[frame].redraw_height = height; } /* if we are clearing the background then we need to redraw enough to * cover the previous frame too */ gif->frames[frame].redraw_required = ((gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) || (gif->frames[frame].disposal_method == GIF_FRAME_RESTORE)); /* Boundary checking - shouldn't ever happen except with junk data */ if (gif_initialise_sprite(gif, (offset_x + width), (offset_y + height))) { return GIF_INSUFFICIENT_MEMORY; } /* Decode the flags */ flags = gif_data[9]; colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK); /* Move our data onwards and remember we've got a bit of this frame */ gif_data += 10; gif_bytes = (gif_end - gif_data); gif->frame_count_partial = frame + 1; /* Skip the local colour table */ if (flags & GIF_COLOUR_TABLE_MASK) { if ((intmax_t)(3 * colour_table_size) > gif_bytes) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += 3 * colour_table_size; gif_bytes = (gif_end - gif_data); } /* Ensure we have a correct code size */ if (gif_bytes < 1) { return GIF_INSUFFICIENT_FRAME_DATA; } if (gif_data[0] > LZW_CODE_MAX) { return GIF_DATA_ERROR; } /* Move our pointer to the actual image data */ gif_data++; --gif_bytes; /* Repeatedly skip blocks until we get a zero block or run out of data * These blocks of image data are processed later by gif_decode_frame() */ block_size = 0; while (block_size != 1) { if (gif_bytes < 1) return GIF_INSUFFICIENT_FRAME_DATA; block_size = gif_data[0] + 1; /* Check if the frame data runs off the end of the file */ if ((intmax_t)(gif_bytes - block_size) < 0) { /* Try to recover by signaling the end of the gif. * Once we get garbage data, there is no logical way to * determine where the next frame is. It's probably * better to partially load the gif than not at all. */ if (gif_bytes >= 2) { gif_bytes = 1; ++gif_data; premature_eof = true; break; } else { return GIF_INSUFFICIENT_FRAME_DATA; } } else { gif_bytes -= block_size; gif_data += block_size; } } /* Add the frame and set the display flag */ gif->buffer_position = gif_data - gif->gif_data; gif->frame_count = frame + 1; gif->frames[frame].display = true; /* Check if we've finished */ if (gif_bytes < 1) { return GIF_INSUFFICIENT_FRAME_DATA; } else { if (premature_eof || gif_data[0] == GIF_TRAILER) { return GIF_OK; } } return GIF_WORKING; } /** * Skips the frame's extensions (which have been previously initialised) * * \param gif The animation context * \return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the * frame GIF_OK for successful decoding */ static gif_result gif_skip_frame_extensions(gif_animation *gif) { const unsigned char *gif_data, *gif_end; intmax_t gif_bytes; intmax_t block_size; /* Get our buffer position etc. */ gif_data = (const unsigned char *)(gif->gif_data + gif->buffer_position); gif_end = (const unsigned char *)(gif->gif_data + gif->buffer_size); gif_bytes = (gif_end - gif_data); /* Skip the extensions */ while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) { ++gif_data; if (gif_data >= gif_end) { return GIF_INSUFFICIENT_FRAME_DATA; } /* Switch on extension label */ switch(gif_data[0]) { case GIF_EXTENSION_COMMENT: /* Move the pointer to the first data sub-block * 1 byte for the extension label */ ++gif_data; break; default: /* Move the pointer to the first data sub-block 2 bytes * for the extension label and size fields Skip the * extension size itself */ if (gif_data + 1 >= gif_end) { return GIF_INSUFFICIENT_FRAME_DATA; } if ((intmax_t)(2 + gif_data[1]) > (gif_end - gif_data)) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += (2 + gif_data[1]); } /* Repeatedly skip blocks until we get a zero block or run out * of data This data is ignored by this gif decoder */ gif_bytes = (gif_end - gif_data); block_size = 0; while (gif_data < gif_end && gif_data[0] != GIF_BLOCK_TERMINATOR) { block_size = gif_data[0] + 1; if ((gif_bytes -= block_size) < 0) { return GIF_INSUFFICIENT_FRAME_DATA; } gif_data += block_size; } if (gif_data >= gif_end) { return GIF_INSUFFICIENT_FRAME_DATA; } ++gif_data; } /* Set buffer position and return */ gif->buffer_position = (gif_data - gif->gif_data); return GIF_OK; } static unsigned int gif_interlaced_line(int height, int y) { if ((y << 3) < height) { return (y << 3); } y -= ((height + 7) >> 3); if ((y << 3) < (height - 4)) { return (y << 3) + 4; } y -= ((height + 3) >> 3); if ((y << 2) < (height - 2)) { return (y << 2) + 2; } y -= ((height + 1) >> 2); return (y << 1) + 1; } static gif_result gif_error_from_lzw(lzw_result l_res) { static const gif_result g_res[] = { [LZW_OK] = GIF_OK, [LZW_OK_EOD] = GIF_END_OF_FRAME, [LZW_NO_MEM] = GIF_INSUFFICIENT_MEMORY, [LZW_NO_DATA] = GIF_INSUFFICIENT_FRAME_DATA, [LZW_EOI_CODE] = GIF_FRAME_DATA_ERROR, [LZW_BAD_ICODE] = GIF_FRAME_DATA_ERROR, [LZW_BAD_CODE] = GIF_FRAME_DATA_ERROR, }; return g_res[l_res]; } /** * decode a gif frame * * \param gif gif animation context. * \param frame The frame number to decode. * \param clear_image flag for image data being cleared instead of plotted. */ static gif_result gif_internal_decode_frame(gif_animation *gif, unsigned int frame, bool clear_image) { unsigned int index = 0; const unsigned char *gif_data, *gif_end; intmax_t gif_bytes; unsigned int width, height, offset_x, offset_y; unsigned int flags, colour_table_size, interlace; unsigned int *colour_table; unsigned int *frame_data = 0; // Set to 0 for no warnings unsigned int *frame_scanline; intmax_t save_buffer_position; unsigned int return_value = 0; unsigned int x, y, decode_y, burst_bytes; register unsigned char colour; /* If the GIF has no frame data, frame holders will not be allocated in * gif_initialise() */ if (gif->frames == NULL) { return GIF_INSUFFICIENT_DATA; } /* Ensure this frame is supposed to be decoded */ if (gif->frames[frame].display == false) { return GIF_OK; } /* Ensure the frame is in range to decode */ if (frame > gif->frame_count_partial) { return GIF_INSUFFICIENT_DATA; } /* done if frame is already decoded */ if ((!clear_image) && ((int)frame == gif->decoded_frame)) { return GIF_OK; } /* Get the start of our frame data and the end of the GIF data */ gif_data = gif->gif_data + gif->frames[frame].frame_pointer; gif_end = gif->gif_data + gif->buffer_size; gif_bytes = (gif_end - gif_data); /* * Ensure there is a minimal amount of data to proceed. The shortest * block of data is a 10-byte image descriptor + 1-byte gif trailer */ if (gif_bytes < 12) { return GIF_INSUFFICIENT_FRAME_DATA; } /* Save the buffer position */ save_buffer_position = gif->buffer_position; gif->buffer_position = gif_data - gif->gif_data; /* Skip any extensions because they have allready been processed */ if ((return_value = gif_skip_frame_extensions(gif)) != GIF_OK) { goto gif_decode_frame_exit; } gif_data = (gif->gif_data + gif->buffer_position); gif_bytes = (gif_end - gif_data); /* Ensure we have enough data for the 10-byte image descriptor + 1-byte * gif trailer */ if (gif_bytes < 12) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } /* 10-byte Image Descriptor is: * * +0 CHAR Image Separator (0x2c) * +1 SHORT Image Left Position * +3 SHORT Image Top Position * +5 SHORT Width * +7 SHORT Height * +9 CHAR __Packed Fields__ * 1BIT Local Colour Table Flag * 1BIT Interlace Flag * 1BIT Sort Flag * 2BITS Reserved * 3BITS Size of Local Colour Table */ if (gif_data[0] != GIF_IMAGE_SEPARATOR) { return_value = GIF_DATA_ERROR; goto gif_decode_frame_exit; } offset_x = gif_data[1] | (gif_data[2] << 8); offset_y = gif_data[3] | (gif_data[4] << 8); width = gif_data[5] | (gif_data[6] << 8); height = gif_data[7] | (gif_data[8] << 8); /* Boundary checking - shouldn't ever happen except unless the data has * been modified since initialisation. */ if ((offset_x + width > gif->width) || (offset_y + height > gif->height)) { return_value = GIF_DATA_ERROR; goto gif_decode_frame_exit; } /* Decode the flags */ flags = gif_data[9]; colour_table_size = 2 << (flags & GIF_COLOUR_TABLE_SIZE_MASK); interlace = flags & GIF_INTERLACE_MASK; /* Advance data pointer to next block either colour table or image * data. */ gif_data += 10; gif_bytes = (gif_end - gif_data); /* Set up the colour table */ if (flags & GIF_COLOUR_TABLE_MASK) { if (gif_bytes < (int)(3 * colour_table_size)) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } colour_table = gif->local_colour_table; if (!clear_image) { for (index = 0; index < colour_table_size; index++) { /* Gif colour map contents are r,g,b. * * We want to pack them bytewise into the * colour table, such that the red component * is in byte 0 and the alpha component is in * byte 3. */ unsigned char *entry = (unsigned char *) &colour_table[index]; entry[0] = gif_data[0]; /* r */ entry[1] = gif_data[1]; /* g */ entry[2] = gif_data[2]; /* b */ entry[3] = 0xff; /* a */ gif_data += 3; } } else { gif_data += 3 * colour_table_size; } gif_bytes = (gif_end - gif_data); } else { colour_table = gif->global_colour_table; } /* Ensure sufficient data remains */ if (gif_bytes < 1) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } /* check for an end marker */ if (gif_data[0] == GIF_TRAILER) { return_value = GIF_OK; goto gif_decode_frame_exit; } /* Get the frame data */ assert(gif->bitmap_callbacks.bitmap_get_buffer); frame_data = (void *)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image); if (!frame_data) { return GIF_INSUFFICIENT_MEMORY; } /* If we are clearing the image we just clear, if not decode */ if (!clear_image) { lzw_result res; const uint8_t *stack_base; const uint8_t *stack_pos; /* Ensure we have enough data for a 1-byte LZW code size + * 1-byte gif trailer */ if (gif_bytes < 2) { return_value = GIF_INSUFFICIENT_FRAME_DATA; goto gif_decode_frame_exit; } /* If we only have a 1-byte LZW code size + 1-byte gif trailer, * we're finished */ if ((gif_bytes == 2) && (gif_data[1] == GIF_TRAILER)) { return_value = GIF_OK; goto gif_decode_frame_exit; } /* If the previous frame's disposal method requires we restore * the background colour or this is the first frame, clear * the frame data */ if ((frame == 0) || (gif->decoded_frame == GIF_INVALID_FRAME)) { memset((char*)frame_data, GIF_TRANSPARENT_COLOUR, gif->width * gif->height * sizeof(int)); gif->decoded_frame = frame; /* The line below would fill the image with its * background color, but because GIFs support * transparency we likely wouldn't want to do that. */ /* memset((char*)frame_data, colour_table[gif->background_index], gif->width * gif->height * sizeof(int)); */ } else if ((frame != 0) && (gif->frames[frame - 1].disposal_method == GIF_FRAME_CLEAR)) { return_value = gif_internal_decode_frame(gif, (frame - 1), true); if (return_value != GIF_OK) { goto gif_decode_frame_exit; } } else if ((frame != 0) && (gif->frames[frame - 1].disposal_method == GIF_FRAME_RESTORE)) { /* * If the previous frame's disposal method requires we * restore the previous image, find the last image set * to "do not dispose" and get that frame data */ int last_undisposed_frame = frame - 2; while ((last_undisposed_frame >= 0) && (gif->frames[last_undisposed_frame].disposal_method == GIF_FRAME_RESTORE)) { last_undisposed_frame--; } /* If we don't find one, clear the frame data */ if (last_undisposed_frame == -1) { /* see notes above on transparency * vs. background color */ memset((char*)frame_data, GIF_TRANSPARENT_COLOUR, gif->width * gif->height * sizeof(int)); } else { return_value = gif_internal_decode_frame(gif, last_undisposed_frame, false); if (return_value != GIF_OK) { goto gif_decode_frame_exit; } /* Get this frame's data */ assert(gif->bitmap_callbacks.bitmap_get_buffer); frame_data = (void *)gif->bitmap_callbacks.bitmap_get_buffer(gif->frame_image); if (!frame_data) { return GIF_INSUFFICIENT_MEMORY; } } } gif->decoded_frame = frame; gif->buffer_position = (gif_data - gif->gif_data) + 1; /* Initialise the LZW decoding */ res = lzw_decode_init(gif->lzw_ctx, gif->gif_data, gif->buffer_size, gif->buffer_position, gif_data[0], &stack_base, &stack_pos); if (res != LZW_OK) { return gif_error_from_lzw(res); } /* Decompress the data */ for (y = 0; y < height; y++) { if (interlace) { decode_y = gif_interlaced_line(height, y) + offset_y; } else { decode_y = y + offset_y; } frame_scanline = frame_data + offset_x + (decode_y * gif->width); /* Rather than decoding pixel by pixel, we try to burst * out streams of data to remove the need for end-of * data checks every pixel. */ x = width; while (x > 0) { burst_bytes = (stack_pos - stack_base); if (burst_bytes > 0) { if (burst_bytes > x) { burst_bytes = x; } x -= burst_bytes; while (burst_bytes > 0) { colour = *--stack_pos; if (((gif->frames[frame].transparency) && (colour != gif->frames[frame].transparency_index)) || (!gif->frames[frame].transparency)) { *frame_scanline = colour_table[colour]; } frame_scanline++; burst_bytes--; } } else { res = lzw_decode(gif->lzw_ctx, &stack_pos); if (res != LZW_OK) { /* Unexpected end of frame, try to recover */ if (res == LZW_OK_EOD) { return_value = GIF_OK; } else { return_value = gif_error_from_lzw(res); } goto gif_decode_frame_exit; } } } } } else { /* Clear our frame */ if (gif->frames[frame].disposal_method == GIF_FRAME_CLEAR) { for (y = 0; y < height; y++) { frame_scanline = frame_data + offset_x + ((offset_y + y) * gif->width); if (gif->frames[frame].transparency) { memset(frame_scanline, GIF_TRANSPARENT_COLOUR, width * 4); } else { memset(frame_scanline, colour_table[gif->background_index], width * 4); } } } } gif_decode_frame_exit: /* Check if we should test for optimisation */ if (gif->frames[frame].virgin) { if (gif->bitmap_callbacks.bitmap_test_opaque) { gif->frames[frame].opaque = gif->bitmap_callbacks.bitmap_test_opaque(gif->frame_image); } else { gif->frames[frame].opaque = false; } gif->frames[frame].virgin = false; } if (gif->bitmap_callbacks.bitmap_set_opaque) { gif->bitmap_callbacks.bitmap_set_opaque(gif->frame_image, gif->frames[frame].opaque); } if (gif->bitmap_callbacks.bitmap_modified) { gif->bitmap_callbacks.bitmap_modified(gif->frame_image); } /* Restore the buffer position */ gif->buffer_position = save_buffer_position; return return_value; } /* exported function documented in libnsgif.h */ void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks) { memset(gif, 0, sizeof(gif_animation)); gif->bitmap_callbacks = *bitmap_callbacks; gif->decoded_frame = GIF_INVALID_FRAME; } /* exported function documented in libnsgif.h */ gif_result gif_initialise(gif_animation *gif, size_t size, const unsigned char *data) { const unsigned char *gif_data; unsigned int index; gif_result return_value; /* Initialize values */ gif->buffer_size = size; gif->gif_data = data; if (gif->lzw_ctx == NULL) { lzw_result res = lzw_context_create( (struct lzw_ctx **)&gif->lzw_ctx); if (res != LZW_OK) { return gif_error_from_lzw(res); } } /* Check for sufficient data to be a GIF (6-byte header + 7-byte * logical screen descriptor) */ if (gif->buffer_size < GIF_STANDARD_HEADER_SIZE) { return GIF_INSUFFICIENT_DATA; } /* Get our current processing position */ gif_data = gif->gif_data + gif->buffer_position; /* See if we should initialise the GIF */ if (gif->buffer_position == 0) { /* We want everything to be NULL before we start so we've no * chance of freeing bad pointers (paranoia) */ gif->frame_image = NULL; gif->frames = NULL; gif->local_colour_table = NULL; gif->global_colour_table = NULL; /* The caller may have been lazy and not reset any values */ gif->frame_count = 0; gif->frame_count_partial = 0; gif->decoded_frame = GIF_INVALID_FRAME; /* 6-byte GIF file header is: * * +0 3CHARS Signature ('GIF') * +3 3CHARS Version ('87a' or '89a') */ if (strncmp((const char *) gif_data, "GIF", 3) != 0) { return GIF_DATA_ERROR; } gif_data += 3; /* Ensure GIF reports version 87a or 89a */ /* if ((strncmp(gif_data, "87a", 3) != 0) && (strncmp(gif_data, "89a", 3) != 0)) LOG(("Unknown GIF format - proceeding anyway")); */ gif_data += 3; /* 7-byte Logical Screen Descriptor is: * * +0 SHORT Logical Screen Width * +2 SHORT Logical Screen Height * +4 CHAR __Packed Fields__ * 1BIT Global Colour Table Flag * 3BITS Colour Resolution * 1BIT Sort Flag * 3BITS Size of Global Colour Table * +5 CHAR Background Colour Index * +6 CHAR Pixel Aspect Ratio */ gif->width = gif_data[0] | (gif_data[1] << 8); gif->height = gif_data[2] | (gif_data[3] << 8); gif->global_colours = (gif_data[4] & GIF_COLOUR_TABLE_MASK); gif->colour_table_size = (2 << (gif_data[4] & GIF_COLOUR_TABLE_SIZE_MASK)); gif->background_index = gif_data[5]; gif->aspect_ratio = gif_data[6]; gif->loop_count = 1; gif_data += 7; /* Some broken GIFs report the size as the screen size they * were created in. As such, we detect for the common cases and * set the sizes as 0 if they are found which results in the * GIF being the maximum size of the frames. */ if (((gif->width == 640) && (gif->height == 480)) || ((gif->width == 640) && (gif->height == 512)) || ((gif->width == 800) && (gif->height == 600)) || ((gif->width == 1024) && (gif->height == 768)) || ((gif->width == 1280) && (gif->height == 1024)) || ((gif->width == 1600) && (gif->height == 1200)) || ((gif->width == 0) || (gif->height == 0)) || ((gif->width > 2048) || (gif->height > 2048))) { gif->width = 1; gif->height = 1; } /* Allocate some data irrespective of whether we've got any * colour tables. We always get the maximum size in case a GIF * is lying to us. It's far better to give the wrong colours * than to trample over some memory somewhere. */ gif->global_colour_table = calloc(GIF_MAX_COLOURS, sizeof(unsigned int)); gif->local_colour_table = calloc(GIF_MAX_COLOURS, sizeof(unsigned int)); if ((gif->global_colour_table == NULL) || (gif->local_colour_table == NULL)) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } /* Set the first colour to a value that will never occur in * reality so we know if we've processed it */ gif->global_colour_table[0] = GIF_PROCESS_COLOURS; /* Check if the GIF has no frame data (13-byte header + 1-byte * termination block) Although generally useless, the GIF * specification does not expressly prohibit this */ if (gif->buffer_size == (GIF_STANDARD_HEADER_SIZE + 1)) { if (gif_data[0] == GIF_TRAILER) { return GIF_OK; } else { return GIF_INSUFFICIENT_DATA; } } /* Initialise enough workspace for a frame */ if ((gif->frames = (gif_frame *)malloc(sizeof(gif_frame))) == NULL) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } gif->frame_holders = 1; /* Clear all frame fields */ memset(gif->frames, 0, sizeof(gif_frame)); /* Initialise the bitmap header */ assert(gif->bitmap_callbacks.bitmap_create); gif->frame_image = gif->bitmap_callbacks.bitmap_create(gif->width, gif->height); if (gif->frame_image == NULL) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } /* Remember we've done this now */ gif->buffer_position = gif_data - gif->gif_data; } /* Do the colour map if we haven't already. As the top byte is always * 0xff or 0x00 depending on the transparency we know if it's been * filled in. */ if (gif->global_colour_table[0] == GIF_PROCESS_COLOURS) { /* Check for a global colour map signified by bit 7 */ if (gif->global_colours) { if (gif->buffer_size < (gif->colour_table_size * 3 + GIF_STANDARD_HEADER_SIZE)) { return GIF_INSUFFICIENT_DATA; } for (index = 0; index < gif->colour_table_size; index++) { /* Gif colour map contents are r,g,b. * * We want to pack them bytewise into the * colour table, such that the red component * is in byte 0 and the alpha component is in * byte 3. */ unsigned char *entry = (unsigned char *) &gif-> global_colour_table[index]; entry[0] = gif_data[0]; /* r */ entry[1] = gif_data[1]; /* g */ entry[2] = gif_data[2]; /* b */ entry[3] = 0xff; /* a */ gif_data += 3; } gif->buffer_position = (gif_data - gif->gif_data); } else { /* Create a default colour table with the first two * colours as black and white */ unsigned int *entry = gif->global_colour_table; entry[0] = 0x00000000; /* Force Alpha channel to opaque */ ((unsigned char *) entry)[3] = 0xff; entry[1] = 0xffffffff; } } /* Repeatedly try to initialise frames */ while ((return_value = gif_initialise_frame(gif)) == GIF_WORKING); /* If there was a memory error tell the caller */ if ((return_value == GIF_INSUFFICIENT_MEMORY) || (return_value == GIF_DATA_ERROR)) { return return_value; } /* If we didn't have some frames then a GIF_INSUFFICIENT_DATA becomes a * GIF_INSUFFICIENT_FRAME_DATA */ if ((return_value == GIF_INSUFFICIENT_DATA) && (gif->frame_count_partial > 0)) { return GIF_INSUFFICIENT_FRAME_DATA; } /* Return how many we got */ return return_value; } /* exported function documented in libnsgif.h */ gif_result gif_decode_frame(gif_animation *gif, unsigned int frame) { return gif_internal_decode_frame(gif, frame, false); } /* exported function documented in libnsgif.h */ void gif_finalise(gif_animation *gif) { /* Release all our memory blocks */ if (gif->frame_image) { assert(gif->bitmap_callbacks.bitmap_destroy); gif->bitmap_callbacks.bitmap_destroy(gif->frame_image); } gif->frame_image = NULL; free(gif->frames); gif->frames = NULL; free(gif->local_colour_table); gif->local_colour_table = NULL; free(gif->global_colour_table); gif->global_colour_table = NULL; lzw_context_destroy(gif->lzw_ctx); gif->lzw_ctx = NULL; } chafa-1.18.2/libnsgif/libnsgif.h000066400000000000000000000150111517447374300164250ustar00rootroot00000000000000/* * Copyright 2004 Richard Wilson * Copyright 2008 Sean Fox * * This file is part of NetSurf's libnsgif, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ /** * \file * Interface to progressive animated GIF file decoding. */ #ifndef _LIBNSGIF_H_ #define _LIBNSGIF_H_ #include #include /* Error return values */ typedef enum { GIF_WORKING = 1, GIF_OK = 0, GIF_INSUFFICIENT_FRAME_DATA = -1, GIF_FRAME_DATA_ERROR = -2, GIF_INSUFFICIENT_DATA = -3, GIF_DATA_ERROR = -4, GIF_INSUFFICIENT_MEMORY = -5, GIF_FRAME_NO_DISPLAY = -6, GIF_END_OF_FRAME = -7 } gif_result; /** GIF frame data */ typedef struct gif_frame { /** whether the frame should be displayed/animated */ bool display; /** delay (in cs) before animating the frame */ unsigned int frame_delay; /* Internal members are listed below */ /** offset (in bytes) to the GIF frame data */ unsigned int frame_pointer; /** whether the frame has previously been used */ bool virgin; /** whether the frame is totally opaque */ bool opaque; /** whether a forcable screen redraw is required */ bool redraw_required; /** how the previous frame should be disposed; affects plotting */ unsigned char disposal_method; /** whether we acknoledge transparency */ bool transparency; /** the index designating a transparent pixel */ unsigned char transparency_index; /** x co-ordinate of redraw rectangle */ unsigned int redraw_x; /** y co-ordinate of redraw rectangle */ unsigned int redraw_y; /** width of redraw rectangle */ unsigned int redraw_width; /** height of redraw rectangle */ unsigned int redraw_height; } gif_frame; /* API for Bitmap callbacks */ typedef void* (*gif_bitmap_cb_create)(int width, int height); typedef void (*gif_bitmap_cb_destroy)(void *bitmap); typedef unsigned char* (*gif_bitmap_cb_get_buffer)(void *bitmap); typedef void (*gif_bitmap_cb_set_opaque)(void *bitmap, bool opaque); typedef bool (*gif_bitmap_cb_test_opaque)(void *bitmap); typedef void (*gif_bitmap_cb_modified)(void *bitmap); /** Bitmap callbacks function table */ typedef struct gif_bitmap_callback_vt { /** Create a bitmap. */ gif_bitmap_cb_create bitmap_create; /** Free a bitmap. */ gif_bitmap_cb_destroy bitmap_destroy; /** Return a pointer to the pixel data in a bitmap. */ gif_bitmap_cb_get_buffer bitmap_get_buffer; /* Members below are optional */ /** Sets whether a bitmap should be plotted opaque. */ gif_bitmap_cb_set_opaque bitmap_set_opaque; /** Tests whether a bitmap has an opaque alpha channel. */ gif_bitmap_cb_test_opaque bitmap_test_opaque; /** The bitmap image has changed, so flush any persistant cache. */ gif_bitmap_cb_modified bitmap_modified; } gif_bitmap_callback_vt; /** GIF animation data */ typedef struct gif_animation { /** LZW decode context */ void *lzw_ctx; /** callbacks for bitmap functions */ gif_bitmap_callback_vt bitmap_callbacks; /** pointer to GIF data */ const unsigned char *gif_data; /** width of GIF (may increase during decoding) */ unsigned int width; /** heigth of GIF (may increase during decoding) */ unsigned int height; /** number of frames decoded */ unsigned int frame_count; /** number of frames partially decoded */ unsigned int frame_count_partial; /** decoded frames */ gif_frame *frames; /** current frame decoded to bitmap */ int decoded_frame; /** currently decoded image; stored as bitmap from bitmap_create callback */ void *frame_image; /** number of times to loop animation */ int loop_count; /* Internal members are listed below */ /** current index into GIF data */ size_t buffer_position; /** total number of bytes of GIF data available */ size_t buffer_size; /** current number of frame holders */ unsigned int frame_holders; /** index in the colour table for the background colour */ unsigned int background_index; /** image aspect ratio (ignored) */ unsigned int aspect_ratio; /** size of colour table (in entries) */ unsigned int colour_table_size; /** whether the GIF has a global colour table */ bool global_colours; /** global colour table */ unsigned int *global_colour_table; /** local colour table */ unsigned int *local_colour_table; } gif_animation; /** * Initialises necessary gif_animation members. */ void gif_create(gif_animation *gif, gif_bitmap_callback_vt *bitmap_callbacks); /** * Initialises any workspace held by the animation and attempts to decode * any information that hasn't already been decoded. * If an error occurs, all previously decoded frames are retained. * * @return Error return value. * - GIF_FRAME_DATA_ERROR for GIF frame data error * - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process * any more frames * - GIF_INSUFFICIENT_MEMORY for memory error * - GIF_DATA_ERROR for GIF error * - GIF_INSUFFICIENT_DATA for insufficient data to do anything * - GIF_OK for successful decoding * - GIF_WORKING for successful decoding if more frames are expected */ gif_result gif_initialise(gif_animation *gif, size_t size, const unsigned char *data); /** * Decodes a GIF frame. * * @return Error return value. If a frame does not contain any image data, * GIF_OK is returned and gif->current_error is set to * GIF_FRAME_NO_DISPLAY * - GIF_FRAME_DATA_ERROR for GIF frame data error * - GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame * - GIF_DATA_ERROR for GIF error (invalid frame header) * - GIF_INSUFFICIENT_DATA for insufficient data to do anything * - GIF_INSUFFICIENT_MEMORY for insufficient memory to process * - GIF_OK for successful decoding */ gif_result gif_decode_frame(gif_animation *gif, unsigned int frame); /** * Releases any workspace held by a gif */ void gif_finalise(gif_animation *gif); #endif chafa-1.18.2/libnsgif/log.h000066400000000000000000000010321517447374300154070ustar00rootroot00000000000000/* * Copyright 2003 James Bursa * Copyright 2004 John Tytgat * * This file is part of NetSurf, http://www.netsurf-browser.org/ * Licenced under the MIT License, * http://www.opensource.org/licenses/mit-license.php */ #include #ifndef _LIBNSGIF_LOG_H_ #define _LIBNSGIF_LOG_H_ #ifdef NDEBUG # define LOG(x) ((void) 0) #else # define LOG(x) do { fprintf(stderr, x), fputc('\n', stderr); } while (0) #endif /* NDEBUG */ #endif /* _LIBNSGIF_LOG_H_ */ chafa-1.18.2/libnsgif/lzw.c000066400000000000000000000244211517447374300154440ustar00rootroot00000000000000/* * This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/ * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * * Copyright 2017 Michael Drake */ #include #include #include #include #include "lzw.h" /** * \file * \brief LZW decompression (implementation) * * Decoder for GIF LZW data. */ /** * Context for reading LZW data. * * LZW data is split over multiple sub-blocks. Each sub-block has a * byte at the start, which says the sub-block size, and then the data. * Zero-size sub-blocks have no data, and the biggest sub-block size is * 255, which means there are 255 bytes of data following the sub-block * size entry. * * Note that an individual LZW code can be split over up to three sub-blocks. */ struct lzw_read_ctx { const uint8_t *data; /**< Pointer to start of input data */ uint64_t data_len; /**< Input data length */ uint64_t data_sb_next; /**< Offset to sub-block size */ const uint8_t *sb_data; /**< Pointer to current sub-block in data */ uint64_t sb_bit; /**< Current bit offset in sub-block */ uint64_t sb_bit_count; /**< Bit count in sub-block */ }; /** * LZW dictionary entry. * * Records in the dictionary are composed of 1 or more entries. * Entries point to previous entries which can be followed to compose * the complete record. To compose the record in reverse order, take * the `last_value` from each entry, and move to the previous entry. * If the previous_entry's index is < the current clear_code, then it * is the last entry in the record. */ struct lzw_dictionary_entry { uint8_t last_value; /**< Last value for record ending at entry. */ uint8_t first_value; /**< First value for entry's record. */ uint16_t previous_entry; /**< Offset in dictionary to previous entry. */ }; /** * LZW decompression context. */ struct lzw_ctx { /** Input reading context */ struct lzw_read_ctx input; uint32_t previous_code; /**< Code read from input previously. */ uint32_t previous_code_first; /**< First value of previous code. */ uint32_t initial_code_size; /**< Starting LZW code size. */ uint32_t current_code_size; /**< Current LZW code size. */ uint32_t current_code_size_max; /**< Max code value for current size. */ uint32_t clear_code; /**< Special Clear code value */ uint32_t eoi_code; /**< Special End of Information code value */ uint32_t current_entry; /**< Next position in table to fill. */ /** Output value stack. */ uint8_t stack_base[1 << LZW_CODE_MAX]; /** LZW decode dictionary. Generated during decode. */ struct lzw_dictionary_entry table[1 << LZW_CODE_MAX]; }; /* Exported function, documented in lzw.h */ lzw_result lzw_context_create(struct lzw_ctx **ctx) { struct lzw_ctx *c = malloc(sizeof(*c)); if (c == NULL) { return LZW_NO_MEM; } *ctx = c; return LZW_OK; } /* Exported function, documented in lzw.h */ void lzw_context_destroy(struct lzw_ctx *ctx) { free(ctx); } /** * Advance the context to the next sub-block in the input data. * * \param[in] ctx LZW reading context, updated on success. * \return LZW_OK or LZW_OK_EOD on success, appropriate error otherwise. */ static lzw_result lzw__block_advance(struct lzw_read_ctx *ctx) { uint64_t block_size; uint64_t next_block_pos = ctx->data_sb_next; const uint8_t *data_next = ctx->data + next_block_pos; if (next_block_pos >= ctx->data_len) { return LZW_NO_DATA; } block_size = *data_next; if ((next_block_pos + block_size) >= ctx->data_len) { return LZW_NO_DATA; } ctx->sb_bit = 0; ctx->sb_bit_count = block_size * 8; if (block_size == 0) { ctx->data_sb_next += 1; return LZW_OK_EOD; } ctx->sb_data = data_next + 1; ctx->data_sb_next += block_size + 1; return LZW_OK; } /** * Get the next LZW code of given size from the raw input data. * * Reads codes from the input data stream coping with GIF data sub-blocks. * * \param[in] ctx LZW reading context, updated. * \param[in] code_size Size of LZW code to get from data. * \param[out] code_out Returns an LZW code on success. * \return LZW_OK or LZW_OK_EOD on success, appropriate error otherwise. */ static inline lzw_result lzw__next_code( struct lzw_read_ctx *ctx, uint8_t code_size, uint32_t *code_out) { uint32_t code = 0; uint8_t current_bit = ctx->sb_bit & 0x7; uint8_t byte_advance = (current_bit + code_size) >> 3; assert(byte_advance <= 2); if (ctx->sb_bit + code_size <= ctx->sb_bit_count) { /* Fast path: code fully inside this sub-block */ const uint8_t *data = ctx->sb_data + (ctx->sb_bit >> 3); switch (byte_advance) { case 2: code |= data[2] << 16; /* Fall through */ case 1: code |= data[1] << 8; /* Fall through */ case 0: code |= data[0] << 0; } ctx->sb_bit += code_size; } else { /* Slow path: code spans sub-blocks */ uint8_t byte = 0; uint8_t bits_remaining_0 = (code_size < (8 - current_bit)) ? code_size : (8 - current_bit); uint8_t bits_remaining_1 = code_size - bits_remaining_0; uint8_t bits_used[3] = { [0] = bits_remaining_0, [1] = bits_remaining_1 < 8 ? bits_remaining_1 : 8, [2] = bits_remaining_1 - 8, }; while (true) { const uint8_t *data = ctx->sb_data; lzw_result res; /* Get any data from end of this sub-block */ while (byte <= byte_advance && ctx->sb_bit < ctx->sb_bit_count) { code |= data[ctx->sb_bit >> 3] << (byte << 3); ctx->sb_bit += bits_used[byte]; byte++; } /* Check if we have all we need */ if (byte > byte_advance) { break; } /* Move to next sub-block */ res = lzw__block_advance(ctx); if (res != LZW_OK) { return res; } } } *code_out = (code >> current_bit) & ((1 << code_size) - 1); return LZW_OK; } /** * Clear LZW code dictionary. * * \param[in] ctx LZW reading context, updated. * \param[out] stack_pos_out Returns current stack position. * \return LZW_OK or error code. */ static lzw_result lzw__clear_codes( struct lzw_ctx *ctx, const uint8_t ** const stack_pos_out) { uint32_t code; uint8_t *stack_pos; /* Reset dictionary building context */ ctx->current_code_size = ctx->initial_code_size + 1; ctx->current_code_size_max = (1 << ctx->current_code_size) - 1;; ctx->current_entry = (1 << ctx->initial_code_size) + 2; /* There might be a sequence of clear codes, so process them all */ do { lzw_result res = lzw__next_code(&ctx->input, ctx->current_code_size, &code); if (res != LZW_OK) { return res; } } while (code == ctx->clear_code); /* The initial code must be from the initial dictionary. */ if (code > ctx->clear_code) { return LZW_BAD_ICODE; } /* Record this initial code as "previous" code, needed during decode. */ ctx->previous_code = code; ctx->previous_code_first = code; /* Reset the stack, and add first non-clear code added as first item. */ stack_pos = ctx->stack_base; *stack_pos++ = code; *stack_pos_out = stack_pos; return LZW_OK; } /* Exported function, documented in lzw.h */ lzw_result lzw_decode_init( struct lzw_ctx *ctx, const uint8_t *compressed_data, uint64_t compressed_data_len, uint64_t compressed_data_pos, uint8_t code_size, const uint8_t ** const stack_base_out, const uint8_t ** const stack_pos_out) { struct lzw_dictionary_entry *table = ctx->table; /* Initialise the input reading context */ ctx->input.data = compressed_data; ctx->input.data_len = compressed_data_len; ctx->input.data_sb_next = compressed_data_pos; ctx->input.sb_bit = 0; ctx->input.sb_bit_count = 0; /* Initialise the dictionary building context */ ctx->initial_code_size = code_size; ctx->clear_code = (1 << code_size) + 0; ctx->eoi_code = (1 << code_size) + 1; /* Initialise the standard dictionary entries */ for (uint32_t i = 0; i < ctx->clear_code; ++i) { table[i].first_value = i; table[i].last_value = i; } *stack_base_out = ctx->stack_base; return lzw__clear_codes(ctx, stack_pos_out); } /* Exported function, documented in lzw.h */ lzw_result lzw_decode(struct lzw_ctx *ctx, const uint8_t ** const stack_pos_out) { lzw_result res; uint32_t code_new; uint32_t code_out; uint8_t last_value; uint8_t *stack_pos = ctx->stack_base; uint32_t clear_code = ctx->clear_code; uint32_t current_entry = ctx->current_entry; struct lzw_dictionary_entry * const table = ctx->table; /* Get a new code from the input */ res = lzw__next_code(&ctx->input, ctx->current_code_size, &code_new); if (res != LZW_OK) { return res; } /* Handle the new code */ if (code_new == clear_code) { /* Got Clear code */ return lzw__clear_codes(ctx, stack_pos_out); } else if (code_new == ctx->eoi_code) { /* Got End of Information code */ return LZW_EOI_CODE; } else if (code_new > current_entry) { /* Code is invalid */ return LZW_BAD_CODE; } else if (code_new >= 1 << LZW_CODE_MAX) { /* Don't access out of bound */ return LZW_BAD_CODE; } else if (code_new < current_entry) { /* Code is in table */ code_out = code_new; last_value = table[code_new].first_value; } else { /* Code not in table */ *stack_pos++ = ctx->previous_code_first; code_out = ctx->previous_code; last_value = ctx->previous_code_first; } /* Add to the dictionary, only if there's space */ if (current_entry < (1 << LZW_CODE_MAX)) { struct lzw_dictionary_entry *entry = table + current_entry; entry->last_value = last_value; entry->first_value = ctx->previous_code_first; entry->previous_entry = ctx->previous_code; ctx->current_entry++; } /* Ensure code size is increased, if needed. */ if (current_entry == ctx->current_code_size_max) { if (ctx->current_code_size < LZW_CODE_MAX) { ctx->current_code_size++; ctx->current_code_size_max = (1 << ctx->current_code_size) - 1; } } /* Store details of this code as "previous code" to the context. */ ctx->previous_code_first = table[code_new].first_value; ctx->previous_code = code_new; /* Put rest of data for this code on output stack. * Note, in the case of "code not in table", the last entry of the * current code has already been placed on the stack above. */ while (code_out > clear_code) { struct lzw_dictionary_entry *entry = table + code_out; *stack_pos++ = entry->last_value; code_out = entry->previous_entry; } *stack_pos++ = table[code_out].last_value; *stack_pos_out = stack_pos; return LZW_OK; } chafa-1.18.2/libnsgif/lzw.h000066400000000000000000000063511517447374300154530ustar00rootroot00000000000000/* * This file is part of NetSurf's LibNSGIF, http://www.netsurf-browser.org/ * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * * Copyright 2017 Michael Drake */ #ifndef LZW_H_ #define LZW_H_ /** * \file * \brief LZW decompression (interface) * * Decoder for GIF LZW data. */ /** Maximum LZW code size in bits */ #define LZW_CODE_MAX 12 /* Declare lzw internal context structure */ struct lzw_ctx; /** LZW decoding response codes */ typedef enum lzw_result { LZW_OK, /**< Success */ LZW_OK_EOD, /**< Success; reached zero-length sub-block */ LZW_NO_MEM, /**< Error: Out of memory */ LZW_NO_DATA, /**< Error: Out of data */ LZW_EOI_CODE, /**< Error: End of Information code */ LZW_BAD_ICODE, /**< Error: Bad initial LZW code */ LZW_BAD_CODE, /**< Error: Bad LZW code */ } lzw_result; /** * Create an LZW decompression context. * * \param[out] ctx Returns an LZW decompression context. Caller owned, * free with lzw_context_destroy(). * \return LZW_OK on success, or appropriate error code otherwise. */ lzw_result lzw_context_create( struct lzw_ctx **ctx); /** * Destroy an LZW decompression context. * * \param[in] ctx The LZW decompression context to destroy. */ void lzw_context_destroy( struct lzw_ctx *ctx); /** * Initialise an LZW decompression context for decoding. * * Caller owns neither `stack_base_out` or `stack_pos_out`. * * \param[in] ctx The LZW decompression context to initialise. * \param[in] compressed_data The compressed data. * \param[in] compressed_data_len Byte length of compressed data. * \param[in] compressed_data_pos Start position in data. Must be position * of a size byte at sub-block start. * \param[in] code_size The initial LZW code size to use. * \param[out] stack_base_out Returns base of decompressed data stack. * \param[out] stack_pos_out Returns current stack position. * There are `stack_pos_out - stack_base_out` * current stack entries. * \return LZW_OK on success, or appropriate error code otherwise. */ lzw_result lzw_decode_init( struct lzw_ctx *ctx, const uint8_t *compressed_data, uint64_t compressed_data_len, uint64_t compressed_data_pos, uint8_t code_size, const uint8_t ** const stack_base_out, const uint8_t ** const stack_pos_out); /** * Fill the LZW stack with decompressed data * * Ensure anything on the stack is used before calling this, as anything * on the stack before this call will be trampled. * * Caller does not own `stack_pos_out`. * * \param[in] ctx LZW reading context, updated. * \param[out] stack_pos_out Returns current stack position. * Use with `stack_base_out` value from previous * lzw_decode_init() call. * There are `stack_pos_out - stack_base_out` * current stack entries. * \return LZW_OK on success, or appropriate error code otherwise. */ lzw_result lzw_decode( struct lzw_ctx *ctx, const uint8_t ** const stack_pos_out); #endif chafa-1.18.2/lodepng/000077500000000000000000000000001517447374300143145ustar00rootroot00000000000000chafa-1.18.2/lodepng/LICENSE000066400000000000000000000015661517447374300153310ustar00rootroot00000000000000Copyright (c) 2005-2018 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. chafa-1.18.2/lodepng/Makefile.am000066400000000000000000000003241517447374300163470ustar00rootroot00000000000000noinst_LTLIBRARIES = liblodepng.la liblodepng_la_SOURCES = lodepng.c lodepng.h liblodepng_la_CFLAGS = ${LODEPNG_CFLAGS} -I${top_srcdir} liblodepng_la_LDFLAGS = ${LODEPNG_LDFLAGS} EXTRA_DIST = LICENSE README.md chafa-1.18.2/lodepng/README.md000066400000000000000000000042761517447374300156040ustar00rootroot00000000000000LodePNG ------- PNG encoder and decoder in C and C++, without dependencies Home page: http://lodev.org/lodepng/ ### Documentation Detailed documentation is included in a large comment in the second half of the header file `lodepng.h`. Source code examples using LodePNG can be found in the examples directory. An FAQ can be found on http://lodev.org/lodepng/ ### Building Only two files are needed to encode and decode PNGs: * `lodepng.cpp` (or renamed to `lodepng.c`) * `lodepng.h` All other files are just source code examples, tests, misc utilities, etc..., which are normally not needed in projects using this. You can include the files directly in your project's source tree and its makefile, IDE project file, or other build system. No library is necessary. In addition to C++, LodePNG also supports ANSI C (C89), with all the same functionality: C++ only adds extra convenience API. For C, rename `lodepng.cpp` to `lodepng.c`. Consider using git submodules to include LodePNG in your project. ### Compiling in C++ If you have a hypothetical `your_program.cpp` that #includes and uses `lodepng.h`, you can build as follows: `g++ your_program.cpp lodepng.cpp -Wall -Wextra -pedantic -ansi -O3` or: `clang++ your_program.cpp lodepng.cpp -Wall -Wextra -pedantic -ansi -O3` This shows compiler flags it was designed for, but normally one would use the compiler or build system of their project instead of those commands, and other C++ compilers are supported. ### Compiling in C Rename `lodepng.cpp` to `lodepng.c` for this. If you have a hypothetical your_program.c that #includes and uses lodepng.h, you can build as follows: `gcc your_program.c lodepng.c -ansi -pedantic -Wall -Wextra -O3` or `clang your_program.c lodepng.c -ansi -pedantic -Wall -Wextra -O3` This shows compiler flags it was designed for, but normally one would use the compiler or build system of their project instead of those commands, and other C compilers are supported. ### Makefile There is a Makefile, but this is not intended for using LodePNG itself since the way to use that one is to include its source files in your program. The Makefile only builds development and testing utilities. It can be used as follows: `make -j` chafa-1.18.2/lodepng/lodepng.c000066400000000000000000010066271517447374300161240ustar00rootroot00000000000000/* LodePNG version 20220109 Copyright (c) 2005-2022 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ /* The manual and changelog are in the header file "lodepng.h" Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for C. */ #include "lodepng.h" #ifdef LODEPNG_COMPILE_DISK #include /* LONG_MAX */ #include /* file handling */ #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ALLOCATORS #include /* allocations */ #endif /* LODEPNG_COMPILE_ALLOCATORS */ #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ #pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ #pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ #endif /*_MSC_VER */ const char* LODEPNG_VERSION_STRING = "20220109"; /* This source file is built up in the following large parts. The code sections with the "LODEPNG_COMPILE_" #defines divide this up further in an intermixed way. -Tools for C and common code for PNG and Zlib -C Code for Zlib (huffman, deflate, ...) -C Code for PNG (file format chunks, adam7, PNG filters, color conversions, ...) -The C++ wrapper around all of the above */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // Tools for C, and common code for PNG and Zlib. // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /*The malloc, realloc and free functions defined here with "lodepng_" in front of the name, so that you can easily change them to others related to your platform if needed. Everything else in the code calls these. Pass -DLODEPNG_NO_COMPILE_ALLOCATORS to the compiler, or comment out #define LODEPNG_COMPILE_ALLOCATORS in the header, to disable the ones here and define them in your own project's source files without needing to change lodepng source code. Don't forget to remove "static" if you copypaste them from here.*/ #ifdef LODEPNG_COMPILE_ALLOCATORS static void* lodepng_malloc(size_t size) { #ifdef LODEPNG_MAX_ALLOC if(size > LODEPNG_MAX_ALLOC) return 0; #endif return malloc(size); } /* NOTE: when realloc returns NULL, it leaves the original memory untouched */ static void* lodepng_realloc(void* ptr, size_t new_size) { #ifdef LODEPNG_MAX_ALLOC if(new_size > LODEPNG_MAX_ALLOC) return 0; #endif return realloc(ptr, new_size); } static void lodepng_free(void* ptr) { free(ptr); } #else /*LODEPNG_COMPILE_ALLOCATORS*/ /* TODO: support giving additional void* payload to the custom allocators */ void* lodepng_malloc(size_t size); void* lodepng_realloc(void* ptr, size_t new_size); void lodepng_free(void* ptr); #endif /*LODEPNG_COMPILE_ALLOCATORS*/ /* convince the compiler to inline a function, for use when this measurably improves performance */ /* inline is not available in C90, but use it when supported by the compiler */ #if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || (defined(__cplusplus) && (__cplusplus >= 199711L)) #define LODEPNG_INLINE inline #else #define LODEPNG_INLINE /* not available */ #endif /* restrict is not available in C90, but use it when supported by the compiler */ #if (defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))) ||\ (defined(_MSC_VER) && (_MSC_VER >= 1400)) || \ (defined(__WATCOMC__) && (__WATCOMC__ >= 1250) && !defined(__cplusplus)) #define LODEPNG_RESTRICT __restrict #else #define LODEPNG_RESTRICT /* not available */ #endif /* Replacements for C library functions such as memcpy and strlen, to support platforms where a full C library is not available. The compiler can recognize them and compile to something as fast. */ static void lodepng_memcpy(void* LODEPNG_RESTRICT dst, const void* LODEPNG_RESTRICT src, size_t size) { size_t i; for(i = 0; i < size; i++) ((char*)dst)[i] = ((const char*)src)[i]; } static void lodepng_memset(void* LODEPNG_RESTRICT dst, int value, size_t num) { size_t i; for(i = 0; i < num; i++) ((char*)dst)[i] = (char)value; } /* does not check memory out of bounds, do not use on untrusted data */ static size_t lodepng_strlen(const char* a) { const char* orig = a; /* avoid warning about unused function in case of disabled COMPILE... macros */ (void)(&lodepng_strlen); while(*a) a++; return (size_t)(a - orig); } #define LODEPNG_MAX(a, b) (((a) > (b)) ? (a) : (b)) #ifdef LODEPNG_COMPILE_ENCODER # define LODEPNG_MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #define LODEPNG_ABS(x) ((x) < 0 ? -(x) : (x)) #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER) /* Safely check if adding two integers will overflow (no undefined behavior, compiler removing the code, etc...) and output result. */ static int lodepng_addofl(size_t a, size_t b, size_t* result) { *result = a + b; /* Unsigned addition is well defined and safe in C90 */ return *result < a; } #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_DECODER)*/ #ifdef LODEPNG_COMPILE_DECODER /* Safely check if multiplying two integers will overflow (no undefined behavior, compiler removing the code, etc...) and output result. */ static int lodepng_mulofl(size_t a, size_t b, size_t* result) { *result = a * b; /* Unsigned multiplication is well defined and safe in C90 */ return (a != 0 && *result / a != b); } #ifdef LODEPNG_COMPILE_ZLIB /* Safely check if a + b > c, even if overflow could happen. */ static int lodepng_gtofl(size_t a, size_t b, size_t c) { size_t d; if(lodepng_addofl(a, b, &d)) return 1; return d > c; } #endif /*LODEPNG_COMPILE_ZLIB*/ #endif /*LODEPNG_COMPILE_DECODER*/ /* Often in case of an error a value is assigned to a variable and then it breaks out of a loop (to go to the cleanup phase of a function). This macro does that. It makes the error handling code shorter and more readable. Example: if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83); */ #define CERROR_BREAK(errorvar, code){\ errorvar = code;\ break;\ } /*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ #define ERROR_BREAK(code) CERROR_BREAK(error, code) /*Set error var to the error code, and return it.*/ #define CERROR_RETURN_ERROR(errorvar, code){\ errorvar = code;\ return code;\ } /*Try the code, if it returns error, also return the error.*/ #define CERROR_TRY_RETURN(call){\ unsigned error = call;\ if(error) return error;\ } /*Set error var to the error code, and return from the void function.*/ #define CERROR_RETURN(errorvar, code){\ errorvar = code;\ return;\ } /* About uivector, ucvector and string: -All of them wrap dynamic arrays or text strings in a similar way. -LodePNG was originally written in C++. The vectors replace the std::vectors that were used in the C++ version. -The string tools are made to avoid problems with compilers that declare things like strncat as deprecated. -They're not used in the interface, only internally in this file as static functions. -As with many other structs in this file, the init and cleanup functions serve as ctor and dtor. */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_ENCODER /*dynamic vector of unsigned ints*/ typedef struct uivector { unsigned* data; size_t size; /*size in number of unsigned longs*/ size_t allocsize; /*allocated size in bytes*/ } uivector; static void uivector_cleanup(void* p) { ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; lodepng_free(((uivector*)p)->data); ((uivector*)p)->data = NULL; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_resize(uivector* p, size_t size) { size_t allocsize = size * sizeof(unsigned); if(allocsize > p->allocsize) { size_t newsize = allocsize + (p->allocsize >> 1u); void* data = lodepng_realloc(p->data, newsize); if(data) { p->allocsize = newsize; p->data = (unsigned*)data; } else return 0; /*error: not enough memory*/ } p->size = size; return 1; /*success*/ } static void uivector_init(uivector* p) { p->data = NULL; p->size = p->allocsize = 0; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_push_back(uivector* p, unsigned c) { if(!uivector_resize(p, p->size + 1)) return 0; p->data[p->size - 1] = c; return 1; } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ /* /////////////////////////////////////////////////////////////////////////// */ /*dynamic vector of unsigned chars*/ typedef struct ucvector { unsigned char* data; size_t size; /*used size*/ size_t allocsize; /*allocated size*/ } ucvector; /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_reserve(ucvector* p, size_t size) { if(size > p->allocsize) { size_t newsize = size + (p->allocsize >> 1u); void* data = lodepng_realloc(p->data, newsize); if(data) { p->allocsize = newsize; p->data = (unsigned char*)data; } else return 0; /*error: not enough memory*/ } return 1; /*success*/ } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_resize(ucvector* p, size_t size) { p->size = size; return ucvector_reserve(p, size); } static ucvector ucvector_init(unsigned char* buffer, size_t size) { ucvector v; v.data = buffer; v.allocsize = v.size = size; return v; } /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_PNG #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*free string pointer and set it to NULL*/ static void string_cleanup(char** out) { lodepng_free(*out); *out = NULL; } /*also appends null termination character*/ static char* alloc_string_sized(const char* in, size_t insize) { char* out = (char*)lodepng_malloc(insize + 1); if(out) { lodepng_memcpy(out, in, insize); out[insize] = 0; } return out; } /* dynamically allocates a new string with a copy of the null terminated input text */ static char* alloc_string(const char* in) { return alloc_string_sized(in, lodepng_strlen(in)); } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ #endif /*LODEPNG_COMPILE_PNG*/ /* ////////////////////////////////////////////////////////////////////////// */ #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG) static unsigned lodepng_read32bitInt(const unsigned char* buffer) { return (((unsigned)buffer[0] << 24u) | ((unsigned)buffer[1] << 16u) | ((unsigned)buffer[2] << 8u) | (unsigned)buffer[3]); } #endif /*defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_PNG)*/ #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) /*buffer must have at least 4 allocated bytes available*/ static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) { buffer[0] = (unsigned char)((value >> 24) & 0xff); buffer[1] = (unsigned char)((value >> 16) & 0xff); buffer[2] = (unsigned char)((value >> 8) & 0xff); buffer[3] = (unsigned char)((value ) & 0xff); } #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ /* ////////////////////////////////////////////////////////////////////////// */ /* / File IO / */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_DISK /* returns negative value on error. This should be pure C compatible, so no fstat. */ static long lodepng_filesize(const char* filename) { FILE* file; long size; file = fopen(filename, "rb"); if(!file) return -1; if(fseek(file, 0, SEEK_END) != 0) { fclose(file); return -1; } size = ftell(file); /* It may give LONG_MAX as directory size, this is invalid for us. */ if(size == LONG_MAX) size = -1; fclose(file); return size; } /* load file into buffer that already has the correct allocated size. Returns error code.*/ static unsigned lodepng_buffer_file(unsigned char* out, size_t size, const char* filename) { FILE* file; size_t readsize; file = fopen(filename, "rb"); if(!file) return 78; readsize = fread(out, 1, size, file); fclose(file); if(readsize != size) return 78; return 0; } unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) { long size = lodepng_filesize(filename); if(size < 0) return 78; *outsize = (size_t)size; *out = (unsigned char*)lodepng_malloc((size_t)size); if(!(*out) && size > 0) return 83; /*the above malloc failed*/ return lodepng_buffer_file(*out, (size_t)size, filename); } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { FILE* file; file = fopen(filename, "wb" ); if(!file) return 79; fwrite(buffer, 1, buffersize, file); fclose(file); return 0; } #endif /*LODEPNG_COMPILE_DISK*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // End of common code and tools. Begin of Zlib related code. // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_ENCODER typedef struct { ucvector* data; unsigned char bp; /*ok to overflow, indicates bit pos inside byte*/ } LodePNGBitWriter; static void LodePNGBitWriter_init(LodePNGBitWriter* writer, ucvector* data) { writer->data = data; writer->bp = 0; } /*TODO: this ignores potential out of memory errors*/ #define WRITEBIT(writer, bit){\ /* append new byte */\ if(((writer->bp) & 7u) == 0) {\ if(!ucvector_resize(writer->data, writer->data->size + 1)) return;\ writer->data->data[writer->data->size - 1] = 0;\ }\ (writer->data->data[writer->data->size - 1]) |= (bit << ((writer->bp) & 7u));\ ++writer->bp;\ } /* LSB of value is written first, and LSB of bytes is used first */ static void writeBits(LodePNGBitWriter* writer, unsigned value, size_t nbits) { if(nbits == 1) { /* compiler should statically compile this case if nbits == 1 */ WRITEBIT(writer, value); } else { /* TODO: increase output size only once here rather than in each WRITEBIT */ size_t i; for(i = 0; i != nbits; ++i) { WRITEBIT(writer, (unsigned char)((value >> i) & 1)); } } } /* This one is to use for adding huffman symbol, the value bits are written MSB first */ static void writeBitsReversed(LodePNGBitWriter* writer, unsigned value, size_t nbits) { size_t i; for(i = 0; i != nbits; ++i) { /* TODO: increase output size only once here rather than in each WRITEBIT */ WRITEBIT(writer, (unsigned char)((value >> (nbits - 1u - i)) & 1u)); } } #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DECODER typedef struct { const unsigned char* data; size_t size; /*size of data in bytes*/ size_t bitsize; /*size of data in bits, end of valid bp values, should be 8*size*/ size_t bp; unsigned buffer; /*buffer for reading bits. NOTE: 'unsigned' must support at least 32 bits*/ } LodePNGBitReader; /* data size argument is in bytes. Returns error if size too large causing overflow */ static unsigned LodePNGBitReader_init(LodePNGBitReader* reader, const unsigned char* data, size_t size) { size_t temp; reader->data = data; reader->size = size; /* size in bits, return error if overflow (if size_t is 32 bit this supports up to 500MB) */ if(lodepng_mulofl(size, 8u, &reader->bitsize)) return 105; /*ensure incremented bp can be compared to bitsize without overflow even when it would be incremented 32 too much and trying to ensure 32 more bits*/ if(lodepng_addofl(reader->bitsize, 64u, &temp)) return 105; reader->bp = 0; reader->buffer = 0; return 0; /*ok*/ } /* ensureBits functions: Ensures the reader can at least read nbits bits in one or more readBits calls, safely even if not enough bits are available. The nbits parameter is unused but is given for documentation purposes, error checking for amount of bits must be done beforehand. */ /*See ensureBits documentation above. This one ensures up to 9 bits */ static LODEPNG_INLINE void ensureBits9(LodePNGBitReader* reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; if(start + 1u < size) { reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u); reader->buffer >>= (reader->bp & 7u); } else { reader->buffer = 0; if(start + 0u < size) reader->buffer = reader->data[start + 0]; reader->buffer >>= (reader->bp & 7u); } (void)nbits; } /*See ensureBits documentation above. This one ensures up to 17 bits */ static LODEPNG_INLINE void ensureBits17(LodePNGBitReader* reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; if(start + 2u < size) { reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u); reader->buffer >>= (reader->bp & 7u); } else { reader->buffer = 0; if(start + 0u < size) reader->buffer |= reader->data[start + 0]; if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); reader->buffer >>= (reader->bp & 7u); } (void)nbits; } /*See ensureBits documentation above. This one ensures up to 25 bits */ static LODEPNG_INLINE void ensureBits25(LodePNGBitReader* reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; if(start + 3u < size) { reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); reader->buffer >>= (reader->bp & 7u); } else { reader->buffer = 0; if(start + 0u < size) reader->buffer |= reader->data[start + 0]; if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); reader->buffer >>= (reader->bp & 7u); } (void)nbits; } /*See ensureBits documentation above. This one ensures up to 32 bits */ static LODEPNG_INLINE void ensureBits32(LodePNGBitReader* reader, size_t nbits) { size_t start = reader->bp >> 3u; size_t size = reader->size; if(start + 4u < size) { reader->buffer = (unsigned)reader->data[start + 0] | ((unsigned)reader->data[start + 1] << 8u) | ((unsigned)reader->data[start + 2] << 16u) | ((unsigned)reader->data[start + 3] << 24u); reader->buffer >>= (reader->bp & 7u); reader->buffer |= (((unsigned)reader->data[start + 4] << 24u) << (8u - (reader->bp & 7u))); } else { reader->buffer = 0; if(start + 0u < size) reader->buffer |= reader->data[start + 0]; if(start + 1u < size) reader->buffer |= ((unsigned)reader->data[start + 1] << 8u); if(start + 2u < size) reader->buffer |= ((unsigned)reader->data[start + 2] << 16u); if(start + 3u < size) reader->buffer |= ((unsigned)reader->data[start + 3] << 24u); reader->buffer >>= (reader->bp & 7u); } (void)nbits; } /* Get bits without advancing the bit pointer. Must have enough bits available with ensureBits. Max nbits is 31. */ static LODEPNG_INLINE unsigned peekBits(LodePNGBitReader* reader, size_t nbits) { /* The shift allows nbits to be only up to 31. */ return reader->buffer & ((1u << nbits) - 1u); } /* Must have enough bits available with ensureBits */ static LODEPNG_INLINE void advanceBits(LodePNGBitReader* reader, size_t nbits) { reader->buffer >>= nbits; reader->bp += nbits; } /* Must have enough bits available with ensureBits */ static LODEPNG_INLINE unsigned readBits(LodePNGBitReader* reader, size_t nbits) { unsigned result = peekBits(reader, nbits); advanceBits(reader, nbits); return result; } #endif /*LODEPNG_COMPILE_DECODER*/ static unsigned reverseBits(unsigned bits, unsigned num) { /*TODO: implement faster lookup table based version when needed*/ unsigned i, result = 0; for(i = 0; i < num; i++) result |= ((bits >> (num - i - 1u)) & 1u) << i; return result; } /* ////////////////////////////////////////////////////////////////////////// */ /* / Deflate - Huffman / */ /* ////////////////////////////////////////////////////////////////////////// */ #define FIRST_LENGTH_CODE_INDEX 257 #define LAST_LENGTH_CODE_INDEX 285 /*256 literals, the end code, some length codes, and 2 unused codes*/ #define NUM_DEFLATE_CODE_SYMBOLS 288 /*the distance codes have their own symbols, 30 used, 2 unused*/ #define NUM_DISTANCE_SYMBOLS 32 /*the code length codes. 0-15: code lengths, 16: copy previous 3-6 times, 17: 3-10 zeros, 18: 11-138 zeros*/ #define NUM_CODE_LENGTH_CODES 19 /*the base lengths represented by codes 257-285*/ static const unsigned LENGTHBASE[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; /*the extra bits used by codes 257-285 (added to base length)*/ static const unsigned LENGTHEXTRA[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ static const unsigned DISTANCEBASE[30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; /*the extra bits of backwards distances (added to base)*/ static const unsigned DISTANCEEXTRA[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /*the order in which "code length alphabet code lengths" are stored as specified by deflate, out of this the huffman tree of the dynamic huffman tree lengths is generated*/ static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* ////////////////////////////////////////////////////////////////////////// */ /* Huffman tree struct, containing multiple representations of the tree */ typedef struct HuffmanTree { unsigned* codes; /*the huffman codes (bit patterns representing the symbols)*/ unsigned* lengths; /*the lengths of the huffman codes*/ unsigned maxbitlen; /*maximum number of bits a single code can get*/ unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ /* for reading only */ unsigned char* table_len; /*length of symbol from lookup table, or max length if secondary lookup needed*/ unsigned short* table_value; /*value of symbol from lookup table, or pointer to secondary table if needed*/ } HuffmanTree; static void HuffmanTree_init(HuffmanTree* tree) { tree->codes = 0; tree->lengths = 0; tree->table_len = 0; tree->table_value = 0; } static void HuffmanTree_cleanup(HuffmanTree* tree) { lodepng_free(tree->codes); lodepng_free(tree->lengths); lodepng_free(tree->table_len); lodepng_free(tree->table_value); } /* amount of bits for first huffman table lookup (aka root bits), see HuffmanTree_makeTable and huffmanDecodeSymbol.*/ /* values 8u and 9u work the fastest */ #define FIRSTBITS 9u /* a symbol value too big to represent any valid symbol, to indicate reading disallowed huffman bits combination, which is possible in case of only 0 or 1 present symbols. */ #define INVALIDSYMBOL 65535u /* make table for huffman decoding */ static unsigned HuffmanTree_makeTable(HuffmanTree* tree) { static const unsigned headsize = 1u << FIRSTBITS; /*size of the first table*/ static const unsigned mask = (1u << FIRSTBITS) /*headsize*/ - 1u; size_t i, numpresent, pointer, size; /*total table size*/ unsigned* maxlens = (unsigned*)lodepng_malloc(headsize * sizeof(unsigned)); if(!maxlens) return 83; /*alloc fail*/ /* compute maxlens: max total bit length of symbols sharing prefix in the first table*/ lodepng_memset(maxlens, 0, headsize * sizeof(*maxlens)); for(i = 0; i < tree->numcodes; i++) { unsigned symbol = tree->codes[i]; unsigned l = tree->lengths[i]; unsigned index; if(l <= FIRSTBITS) continue; /*symbols that fit in first table don't increase secondary table size*/ /*get the FIRSTBITS MSBs, the MSBs of the symbol are encoded first. See later comment about the reversing*/ index = reverseBits(symbol >> (l - FIRSTBITS), FIRSTBITS); maxlens[index] = LODEPNG_MAX(maxlens[index], l); } /* compute total table size: size of first table plus all secondary tables for symbols longer than FIRSTBITS */ size = headsize; for(i = 0; i < headsize; ++i) { unsigned l = maxlens[i]; if(l > FIRSTBITS) size += (1u << (l - FIRSTBITS)); } tree->table_len = (unsigned char*)lodepng_malloc(size * sizeof(*tree->table_len)); tree->table_value = (unsigned short*)lodepng_malloc(size * sizeof(*tree->table_value)); if(!tree->table_len || !tree->table_value) { lodepng_free(maxlens); /* freeing tree->table values is done at a higher scope */ return 83; /*alloc fail*/ } /*initialize with an invalid length to indicate unused entries*/ for(i = 0; i < size; ++i) tree->table_len[i] = 16; /*fill in the first table for long symbols: max prefix size and pointer to secondary tables*/ pointer = headsize; for(i = 0; i < headsize; ++i) { unsigned l = maxlens[i]; if(l <= FIRSTBITS) continue; tree->table_len[i] = l; tree->table_value[i] = pointer; pointer += (1u << (l - FIRSTBITS)); } lodepng_free(maxlens); /*fill in the first table for short symbols, or secondary table for long symbols*/ numpresent = 0; for(i = 0; i < tree->numcodes; ++i) { unsigned l = tree->lengths[i]; unsigned symbol = tree->codes[i]; /*the huffman bit pattern. i itself is the value.*/ /*reverse bits, because the huffman bits are given in MSB first order but the bit reader reads LSB first*/ unsigned reverse = reverseBits(symbol, l); if(l == 0) continue; numpresent++; if(l <= FIRSTBITS) { /*short symbol, fully in first table, replicated num times if l < FIRSTBITS*/ unsigned num = 1u << (FIRSTBITS - l); unsigned j; for(j = 0; j < num; ++j) { /*bit reader will read the l bits of symbol first, the remaining FIRSTBITS - l bits go to the MSB's*/ unsigned index = reverse | (j << l); if(tree->table_len[index] != 16) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ tree->table_len[index] = l; tree->table_value[index] = i; } } else { /*long symbol, shares prefix with other long symbols in first lookup table, needs second lookup*/ /*the FIRSTBITS MSBs of the symbol are the first table index*/ unsigned index = reverse & mask; unsigned maxlen = tree->table_len[index]; /*log2 of secondary table length, should be >= l - FIRSTBITS*/ unsigned tablelen = maxlen - FIRSTBITS; unsigned start = tree->table_value[index]; /*starting index in secondary table*/ unsigned num = 1u << (tablelen - (l - FIRSTBITS)); /*amount of entries of this symbol in secondary table*/ unsigned j; if(maxlen < l) return 55; /*invalid tree: long symbol shares prefix with short symbol*/ for(j = 0; j < num; ++j) { unsigned reverse2 = reverse >> FIRSTBITS; /* l - FIRSTBITS bits */ unsigned index2 = start + (reverse2 | (j << (l - FIRSTBITS))); tree->table_len[index2] = l; tree->table_value[index2] = i; } } } if(numpresent < 2) { /* In case of exactly 1 symbol, in theory the huffman symbol needs 0 bits, but deflate uses 1 bit instead. In case of 0 symbols, no symbols can appear at all, but such huffman tree could still exist (e.g. if distance codes are never used). In both cases, not all symbols of the table will be filled in. Fill them in with an invalid symbol value so returning them from huffmanDecodeSymbol will cause error. */ for(i = 0; i < size; ++i) { if(tree->table_len[i] == 16) { /* As length, use a value smaller than FIRSTBITS for the head table, and a value larger than FIRSTBITS for the secondary table, to ensure valid behavior for advanceBits when reading this symbol. */ tree->table_len[i] = (i < headsize) ? 1 : (FIRSTBITS + 1); tree->table_value[i] = INVALIDSYMBOL; } } } else { /* A good huffman tree has N * 2 - 1 nodes, of which N - 1 are internal nodes. If that is not the case (due to too long length codes), the table will not have been fully used, and this is an error (not all bit combinations can be decoded): an oversubscribed huffman tree, indicated by error 55. */ for(i = 0; i < size; ++i) { if(tree->table_len[i] == 16) return 55; } } return 0; } /* Second step for the ...makeFromLengths and ...makeFromFrequencies functions. numcodes, lengths and maxbitlen must already be filled in correctly. return value is error. */ static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) { unsigned* blcount; unsigned* nextcode; unsigned error = 0; unsigned bits, n; tree->codes = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); blcount = (unsigned*)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned)); nextcode = (unsigned*)lodepng_malloc((tree->maxbitlen + 1) * sizeof(unsigned)); if(!tree->codes || !blcount || !nextcode) error = 83; /*alloc fail*/ if(!error) { for(n = 0; n != tree->maxbitlen + 1; n++) blcount[n] = nextcode[n] = 0; /*step 1: count number of instances of each code length*/ for(bits = 0; bits != tree->numcodes; ++bits) ++blcount[tree->lengths[bits]]; /*step 2: generate the nextcode values*/ for(bits = 1; bits <= tree->maxbitlen; ++bits) { nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1u; } /*step 3: generate all the codes*/ for(n = 0; n != tree->numcodes; ++n) { if(tree->lengths[n] != 0) { tree->codes[n] = nextcode[tree->lengths[n]]++; /*remove superfluous bits from the code*/ tree->codes[n] &= ((1u << tree->lengths[n]) - 1u); } } } lodepng_free(blcount); lodepng_free(nextcode); if(!error) error = HuffmanTree_makeTable(tree); return error; } /* given the code lengths (as stored in the PNG file), generate the tree as defined by Deflate. maxbitlen is the maximum bits that a code in the tree can have. return value is error. */ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, size_t numcodes, unsigned maxbitlen) { unsigned i; tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); if(!tree->lengths) return 83; /*alloc fail*/ for(i = 0; i != numcodes; ++i) tree->lengths[i] = bitlen[i]; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ tree->maxbitlen = maxbitlen; return HuffmanTree_makeFromLengths2(tree); } #ifdef LODEPNG_COMPILE_ENCODER /*BPM: Boundary Package Merge, see "A Fast and Space-Economical Algorithm for Length-Limited Coding", Jyrki Katajainen, Alistair Moffat, Andrew Turpin, 1995.*/ /*chain node for boundary package merge*/ typedef struct BPMNode { int weight; /*the sum of all weights in this chain*/ unsigned index; /*index of this leaf node (called "count" in the paper)*/ struct BPMNode* tail; /*the next nodes in this chain (null if last)*/ int in_use; } BPMNode; /*lists of chains*/ typedef struct BPMLists { /*memory pool*/ unsigned memsize; BPMNode* memory; unsigned numfree; unsigned nextfree; BPMNode** freelist; /*two heads of lookahead chains per list*/ unsigned listsize; BPMNode** chains0; BPMNode** chains1; } BPMLists; /*creates a new chain node with the given parameters, from the memory in the lists */ static BPMNode* bpmnode_create(BPMLists* lists, int weight, unsigned index, BPMNode* tail) { unsigned i; BPMNode* result; /*memory full, so garbage collect*/ if(lists->nextfree >= lists->numfree) { /*mark only those that are in use*/ for(i = 0; i != lists->memsize; ++i) lists->memory[i].in_use = 0; for(i = 0; i != lists->listsize; ++i) { BPMNode* node; for(node = lists->chains0[i]; node != 0; node = node->tail) node->in_use = 1; for(node = lists->chains1[i]; node != 0; node = node->tail) node->in_use = 1; } /*collect those that are free*/ lists->numfree = 0; for(i = 0; i != lists->memsize; ++i) { if(!lists->memory[i].in_use) lists->freelist[lists->numfree++] = &lists->memory[i]; } lists->nextfree = 0; } result = lists->freelist[lists->nextfree++]; result->weight = weight; result->index = index; result->tail = tail; return result; } /*sort the leaves with stable mergesort*/ static void bpmnode_sort(BPMNode* leaves, size_t num) { BPMNode* mem = (BPMNode*)lodepng_malloc(sizeof(*leaves) * num); size_t width, counter = 0; for(width = 1; width < num; width *= 2) { BPMNode* a = (counter & 1) ? mem : leaves; BPMNode* b = (counter & 1) ? leaves : mem; size_t p; for(p = 0; p < num; p += 2 * width) { size_t q = (p + width > num) ? num : (p + width); size_t r = (p + 2 * width > num) ? num : (p + 2 * width); size_t i = p, j = q, k; for(k = p; k < r; k++) { if(i < q && (j >= r || a[i].weight <= a[j].weight)) b[k] = a[i++]; else b[k] = a[j++]; } } counter++; } if(counter & 1) lodepng_memcpy(leaves, mem, sizeof(*leaves) * num); lodepng_free(mem); } /*Boundary Package Merge step, numpresent is the amount of leaves, and c is the current chain.*/ static void boundaryPM(BPMLists* lists, BPMNode* leaves, size_t numpresent, int c, int num) { unsigned lastindex = lists->chains1[c]->index; if(c == 0) { if(lastindex >= numpresent) return; lists->chains0[c] = lists->chains1[c]; lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, 0); } else { /*sum of the weights of the head nodes of the previous lookahead chains.*/ int sum = lists->chains0[c - 1]->weight + lists->chains1[c - 1]->weight; lists->chains0[c] = lists->chains1[c]; if(lastindex < numpresent && sum > leaves[lastindex].weight) { lists->chains1[c] = bpmnode_create(lists, leaves[lastindex].weight, lastindex + 1, lists->chains1[c]->tail); return; } lists->chains1[c] = bpmnode_create(lists, sum, lastindex, lists->chains1[c - 1]); /*in the end we are only interested in the chain of the last list, so no need to recurse if we're at the last one (this gives measurable speedup)*/ if(num + 1 < (int)(2 * numpresent - 2)) { boundaryPM(lists, leaves, numpresent, c - 1, num); boundaryPM(lists, leaves, numpresent, c - 1, num); } } } unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen) { unsigned error = 0; unsigned i; size_t numpresent = 0; /*number of symbols with non-zero frequency*/ BPMNode* leaves; /*the symbols, only those with > 0 frequency*/ if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ if((1u << maxbitlen) < (unsigned)numcodes) return 80; /*error: represent all symbols*/ leaves = (BPMNode*)lodepng_malloc(numcodes * sizeof(*leaves)); if(!leaves) return 83; /*alloc fail*/ for(i = 0; i != numcodes; ++i) { if(frequencies[i] > 0) { leaves[numpresent].weight = (int)frequencies[i]; leaves[numpresent].index = i; ++numpresent; } } lodepng_memset(lengths, 0, numcodes * sizeof(*lengths)); /*ensure at least two present symbols. There should be at least one symbol according to RFC 1951 section 3.2.7. Some decoders incorrectly require two. To make these work as well ensure there are at least two symbols. The Package-Merge code below also doesn't work correctly if there's only one symbol, it'd give it the theoretical 0 bits but in practice zlib wants 1 bit*/ if(numpresent == 0) { lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ } else if(numpresent == 1) { lengths[leaves[0].index] = 1; lengths[leaves[0].index == 0 ? 1 : 0] = 1; } else { BPMLists lists; BPMNode* node; bpmnode_sort(leaves, numpresent); lists.listsize = maxbitlen; lists.memsize = 2 * maxbitlen * (maxbitlen + 1); lists.nextfree = 0; lists.numfree = lists.memsize; lists.memory = (BPMNode*)lodepng_malloc(lists.memsize * sizeof(*lists.memory)); lists.freelist = (BPMNode**)lodepng_malloc(lists.memsize * sizeof(BPMNode*)); lists.chains0 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); lists.chains1 = (BPMNode**)lodepng_malloc(lists.listsize * sizeof(BPMNode*)); if(!lists.memory || !lists.freelist || !lists.chains0 || !lists.chains1) error = 83; /*alloc fail*/ if(!error) { for(i = 0; i != lists.memsize; ++i) lists.freelist[i] = &lists.memory[i]; bpmnode_create(&lists, leaves[0].weight, 1, 0); bpmnode_create(&lists, leaves[1].weight, 2, 0); for(i = 0; i != lists.listsize; ++i) { lists.chains0[i] = &lists.memory[0]; lists.chains1[i] = &lists.memory[1]; } /*each boundaryPM call adds one chain to the last list, and we need 2 * numpresent - 2 chains.*/ for(i = 2; i != 2 * numpresent - 2; ++i) boundaryPM(&lists, leaves, numpresent, (int)maxbitlen - 1, (int)i); for(node = lists.chains1[maxbitlen - 1]; node; node = node->tail) { for(i = 0; i != node->index; ++i) ++lengths[leaves[i].index]; } } lodepng_free(lists.memory); lodepng_free(lists.freelist); lodepng_free(lists.chains0); lodepng_free(lists.chains1); } lodepng_free(leaves); return error; } /*Create the Huffman tree given the symbol frequencies*/ static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, size_t mincodes, size_t numcodes, unsigned maxbitlen) { unsigned error = 0; while(!frequencies[numcodes - 1] && numcodes > mincodes) --numcodes; /*trim zeroes*/ tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); if(!tree->lengths) return 83; /*alloc fail*/ tree->maxbitlen = maxbitlen; tree->numcodes = (unsigned)numcodes; /*number of symbols*/ error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); if(!error) error = HuffmanTree_makeFromLengths2(tree); return error; } #endif /*LODEPNG_COMPILE_ENCODER*/ /*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ static unsigned generateFixedLitLenTree(HuffmanTree* tree) { unsigned i, error = 0; unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); if(!bitlen) return 83; /*alloc fail*/ /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ for(i = 0; i <= 143; ++i) bitlen[i] = 8; for(i = 144; i <= 255; ++i) bitlen[i] = 9; for(i = 256; i <= 279; ++i) bitlen[i] = 7; for(i = 280; i <= 287; ++i) bitlen[i] = 8; error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); lodepng_free(bitlen); return error; } /*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ static unsigned generateFixedDistanceTree(HuffmanTree* tree) { unsigned i, error = 0; unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); if(!bitlen) return 83; /*alloc fail*/ /*there are 32 distance codes, but 30-31 are unused*/ for(i = 0; i != NUM_DISTANCE_SYMBOLS; ++i) bitlen[i] = 5; error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); lodepng_free(bitlen); return error; } #ifdef LODEPNG_COMPILE_DECODER /* returns the code. The bit reader must already have been ensured at least 15 bits */ static unsigned huffmanDecodeSymbol(LodePNGBitReader* reader, const HuffmanTree* codetree) { unsigned short code = peekBits(reader, FIRSTBITS); unsigned short l = codetree->table_len[code]; unsigned short value = codetree->table_value[code]; if(l <= FIRSTBITS) { advanceBits(reader, l); return value; } else { advanceBits(reader, FIRSTBITS); value += peekBits(reader, l - FIRSTBITS); advanceBits(reader, codetree->table_len[value] - FIRSTBITS); return codetree->table_value[value]; } } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_DECODER /* ////////////////////////////////////////////////////////////////////////// */ /* / Inflator (Decompressor) / */ /* ////////////////////////////////////////////////////////////////////////// */ /*get the tree of a deflated block with fixed tree, as specified in the deflate specification Returns error code.*/ static unsigned getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) { unsigned error = generateFixedLitLenTree(tree_ll); if(error) return error; return generateFixedDistanceTree(tree_d); } /*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, LodePNGBitReader* reader) { /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ unsigned error = 0; unsigned n, HLIT, HDIST, HCLEN, i; /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ unsigned* bitlen_ll = 0; /*lit,len code lengths*/ unsigned* bitlen_d = 0; /*dist code lengths*/ /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ unsigned* bitlen_cl = 0; HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ if(reader->bitsize - reader->bp < 14) return 49; /*error: the bit pointer is or will go past the memory*/ ensureBits17(reader, 14); /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ HLIT = readBits(reader, 5) + 257; /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ HDIST = readBits(reader, 5) + 1; /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ HCLEN = readBits(reader, 4) + 4; bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); if(!bitlen_cl) return 83 /*alloc fail*/; HuffmanTree_init(&tree_cl); while(!error) { /*read the code length codes out of 3 * (amount of code length codes) bits*/ if(lodepng_gtofl(reader->bp, HCLEN * 3, reader->bitsize)) { ERROR_BREAK(50); /*error: the bit pointer is or will go past the memory*/ } for(i = 0; i != HCLEN; ++i) { ensureBits9(reader, 3); /*out of bounds already checked above */ bitlen_cl[CLCL_ORDER[i]] = readBits(reader, 3); } for(i = HCLEN; i != NUM_CODE_LENGTH_CODES; ++i) { bitlen_cl[CLCL_ORDER[i]] = 0; } error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); if(error) break; /*now we can use this tree to read the lengths for the tree that this function will return*/ bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); lodepng_memset(bitlen_ll, 0, NUM_DEFLATE_CODE_SYMBOLS * sizeof(*bitlen_ll)); lodepng_memset(bitlen_d, 0, NUM_DISTANCE_SYMBOLS * sizeof(*bitlen_d)); /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ i = 0; while(i < HLIT + HDIST) { unsigned code; ensureBits25(reader, 22); /* up to 15 bits for huffman code, up to 7 extra bits below*/ code = huffmanDecodeSymbol(reader, &tree_cl); if(code <= 15) /*a length code*/ { if(i < HLIT) bitlen_ll[i] = code; else bitlen_d[i - HLIT] = code; ++i; } else if(code == 16) /*repeat previous*/ { unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ unsigned value; /*set value to the previous code*/ if(i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ replength += readBits(reader, 2); if(i < HLIT + 1) value = bitlen_ll[i - 1]; else value = bitlen_d[i - HLIT - 1]; /*repeat this value in the next lengths*/ for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = value; else bitlen_d[i - HLIT] = value; ++i; } } else if(code == 17) /*repeat "0" 3-10 times*/ { unsigned replength = 3; /*read in the bits that indicate repeat length*/ replength += readBits(reader, 3); /*repeat this value in the next lengths*/ for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = 0; else bitlen_d[i - HLIT] = 0; ++i; } } else if(code == 18) /*repeat "0" 11-138 times*/ { unsigned replength = 11; /*read in the bits that indicate repeat length*/ replength += readBits(reader, 7); /*repeat this value in the next lengths*/ for(n = 0; n < replength; ++n) { if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ if(i < HLIT) bitlen_ll[i] = 0; else bitlen_d[i - HLIT] = 0; ++i; } } else /*if(code == INVALIDSYMBOL)*/ { ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ } /*check if any of the ensureBits above went out of bounds*/ if(reader->bp > reader->bitsize) { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ /* TODO: revise error codes 10,11,50: the above comment is no longer valid */ ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ } } if(error) break; if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); if(error) break; error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); break; /*end of error-while*/ } lodepng_free(bitlen_cl); lodepng_free(bitlen_ll); lodepng_free(bitlen_d); HuffmanTree_cleanup(&tree_cl); return error; } /*inflate a block with dynamic of fixed Huffman tree. btype must be 1 or 2.*/ static unsigned inflateHuffmanBlock(ucvector* out, LodePNGBitReader* reader, unsigned btype, size_t max_output_size) { unsigned error = 0; HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ HuffmanTree tree_d; /*the huffman tree for distance codes*/ const size_t reserved_size = 260; /* must be at least 258 for max length, and a few extra for adding a few extra literals */ int done = 0; if(!ucvector_reserve(out, out->size + reserved_size)) return 83; /*alloc fail*/ HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); if(btype == 1) error = getTreeInflateFixed(&tree_ll, &tree_d); else /*if(btype == 2)*/ error = getTreeInflateDynamic(&tree_ll, &tree_d, reader); while(!error && !done) /*decode all symbols until end reached, breaks at end code*/ { /*code_ll is literal, length or end code*/ unsigned code_ll; /* ensure enough bits for 2 huffman code reads (15 bits each): if the first is a literal, a second literal is read at once. This appears to be slightly faster, than ensuring 20 bits here for 1 huffman symbol and the potential 5 extra bits for the length symbol.*/ ensureBits32(reader, 30); code_ll = huffmanDecodeSymbol(reader, &tree_ll); if(code_ll <= 255) { /*slightly faster code path if multiple literals in a row*/ out->data[out->size++] = (unsigned char)code_ll; code_ll = huffmanDecodeSymbol(reader, &tree_ll); } if(code_ll <= 255) /*literal symbol*/ { out->data[out->size++] = (unsigned char)code_ll; } else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ { unsigned code_d, distance; unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ size_t start, backward, length; /*part 1: get length base*/ length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; /*part 2: get extra bits and add the value of that to length*/ numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; if(numextrabits_l != 0) { /* bits already ensured above */ ensureBits25(reader, 5); length += readBits(reader, numextrabits_l); } /*part 3: get distance code*/ ensureBits32(reader, 28); /* up to 15 for the huffman symbol, up to 13 for the extra bits */ code_d = huffmanDecodeSymbol(reader, &tree_d); if(code_d > 29) { if(code_d <= 31) { ERROR_BREAK(18); /*error: invalid distance code (30-31 are never used)*/ } else /* if(code_d == INVALIDSYMBOL) */{ ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ } } distance = DISTANCEBASE[code_d]; /*part 4: get extra bits from distance*/ numextrabits_d = DISTANCEEXTRA[code_d]; if(numextrabits_d != 0) { /* bits already ensured above */ distance += readBits(reader, numextrabits_d); } /*part 5: fill in all the out[n] values based on the length and dist*/ start = out->size; if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ backward = start - distance; out->size += length; if(distance < length) { size_t forward; lodepng_memcpy(out->data + start, out->data + backward, distance); start += distance; for(forward = distance; forward < length; ++forward) { out->data[start++] = out->data[backward++]; } } else { lodepng_memcpy(out->data + start, out->data + backward, length); } } else if(code_ll == 256) { done = 1; /*end code, finish the loop*/ } else /*if(code_ll == INVALIDSYMBOL)*/ { ERROR_BREAK(16); /*error: tried to read disallowed huffman symbol*/ } if(out->allocsize - out->size < reserved_size) { if(!ucvector_reserve(out, out->size + reserved_size)) ERROR_BREAK(83); /*alloc fail*/ } /*check if any of the ensureBits above went out of bounds*/ if(reader->bp > reader->bitsize) { /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ /* TODO: revise error codes 10,11,50: the above comment is no longer valid */ ERROR_BREAK(51); /*error, bit pointer jumps past memory*/ } if(max_output_size && out->size > max_output_size) { ERROR_BREAK(109); /*error, larger than max size*/ } } HuffmanTree_cleanup(&tree_ll); HuffmanTree_cleanup(&tree_d); return error; } static unsigned inflateNoCompression(ucvector* out, LodePNGBitReader* reader, const LodePNGDecompressSettings* settings) { size_t bytepos; size_t size = reader->size; unsigned LEN, NLEN, error = 0; /*go to first boundary of byte*/ bytepos = (reader->bp + 7u) >> 3u; /*read LEN (2 bytes) and NLEN (2 bytes)*/ if(bytepos + 4 >= size) return 52; /*error, bit pointer will jump past memory*/ LEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u); bytepos += 2; NLEN = (unsigned)reader->data[bytepos] + ((unsigned)reader->data[bytepos + 1] << 8u); bytepos += 2; /*check if 16-bit NLEN is really the one's complement of LEN*/ if(!settings->ignore_nlen && LEN + NLEN != 65535) { return 21; /*error: NLEN is not one's complement of LEN*/ } if(!ucvector_resize(out, out->size + LEN)) return 83; /*alloc fail*/ /*read the literal data: LEN bytes are now stored in the out buffer*/ if(bytepos + LEN > size) return 23; /*error: reading outside of in buffer*/ /*out->data can be NULL (when LEN is zero), and arithmetics on NULL ptr is undefined. so we check*/ if (out->data) { lodepng_memcpy(out->data + out->size - LEN, reader->data + bytepos, LEN); bytepos += LEN; } reader->bp = bytepos << 3u; return error; } static unsigned lodepng_inflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { unsigned BFINAL = 0; LodePNGBitReader reader; unsigned error = LodePNGBitReader_init(&reader, in, insize); if(error) return error; while(!BFINAL) { unsigned BTYPE; if(reader.bitsize - reader.bp < 3) return 52; /*error, bit pointer will jump past memory*/ ensureBits9(&reader, 3); BFINAL = readBits(&reader, 1); BTYPE = readBits(&reader, 2); if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ else if(BTYPE == 0) error = inflateNoCompression(out, &reader, settings); /*no compression*/ else error = inflateHuffmanBlock(out, &reader, BTYPE, settings->max_output_size); /*compression, BTYPE 01 or 10*/ if(!error && settings->max_output_size && out->size > settings->max_output_size) error = 109; if(error) break; } return error; } unsigned lodepng_inflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { ucvector v = ucvector_init(*out, *outsize); unsigned error = lodepng_inflatev(&v, in, insize, settings); *out = v.data; *outsize = v.size; return error; } static unsigned inflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { if(settings->custom_inflate) { unsigned error = settings->custom_inflate(&out->data, &out->size, in, insize, settings); out->allocsize = out->size; if(error) { /*the custom inflate is allowed to have its own error codes, however, we translate it to code 110*/ error = 110; /*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/ if(settings->max_output_size && out->size > settings->max_output_size) error = 109; } return error; } else { return lodepng_inflatev(out, in, insize, settings); } } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* ////////////////////////////////////////////////////////////////////////// */ /* / Deflator (Compressor) / */ /* ////////////////////////////////////////////////////////////////////////// */ static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; /*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/ static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { /*binary search (only small gain over linear). TODO: use CPU log2 instruction for getting symbols instead*/ size_t left = 1; size_t right = array_size - 1; while(left <= right) { size_t mid = (left + right) >> 1; if(array[mid] >= value) right = mid - 1; else left = mid + 1; } if(left >= array_size || array[left] > value) left--; return left; } static void addLengthDistance(uivector* values, size_t length, size_t distance) { /*values in encoded vector are those used by deflate: 0-255: literal bytes 256: end 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) 286-287: invalid*/ unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); size_t pos = values->size; /*TODO: return error when this fails (out of memory)*/ unsigned ok = uivector_resize(values, values->size + 4); if(ok) { values->data[pos + 0] = length_code + FIRST_LENGTH_CODE_INDEX; values->data[pos + 1] = extra_length; values->data[pos + 2] = dist_code; values->data[pos + 3] = extra_distance; } } /*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 bytes as input because 3 is the minimum match length for deflate*/ static const unsigned HASH_NUM_VALUES = 65536; static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does not like that as initializer*/ typedef struct Hash { int* head; /*hash value to head circular pos - can be outdated if went around window*/ /*circular pos to prev circular pos*/ unsigned short* chain; int* val; /*circular pos to hash value*/ /*TODO: do this not only for zeros but for any repeated byte. However for PNG it's always going to be the zeros that dominate, so not important for PNG*/ int* headz; /*similar to head, but for chainz*/ unsigned short* chainz; /*those with same amount of zeros*/ unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ } Hash; static unsigned hash_init(Hash* hash, unsigned windowsize) { unsigned i; hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) { return 83; /*alloc fail*/ } /*initialize hash table*/ for(i = 0; i != HASH_NUM_VALUES; ++i) hash->head[i] = -1; for(i = 0; i != windowsize; ++i) hash->val[i] = -1; for(i = 0; i != windowsize; ++i) hash->chain[i] = i; /*same value as index indicates uninitialized*/ for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; ++i) hash->headz[i] = -1; for(i = 0; i != windowsize; ++i) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ return 0; } static void hash_cleanup(Hash* hash) { lodepng_free(hash->head); lodepng_free(hash->val); lodepng_free(hash->chain); lodepng_free(hash->zeros); lodepng_free(hash->headz); lodepng_free(hash->chainz); } static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { unsigned result = 0; if(pos + 2 < size) { /*A simple shift and xor hash is used. Since the data of PNGs is dominated by zeroes due to the filters, a better hash does not have a significant effect on speed in traversing the chain, and causes more time spend on calculating the hash.*/ result ^= ((unsigned)data[pos + 0] << 0u); result ^= ((unsigned)data[pos + 1] << 4u); result ^= ((unsigned)data[pos + 2] << 8u); } else { size_t amount, i; if(pos >= size) return 0; amount = size - pos; for(i = 0; i != amount; ++i) result ^= ((unsigned)data[pos + i] << (i * 8u)); } return result & HASH_BIT_MASK; } static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) { const unsigned char* start = data + pos; const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; if(end > data + size) end = data + size; data = start; while(data != end && *data == 0) ++data; /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ return (unsigned)(data - start); } /*wpos = pos & (windowsize - 1)*/ static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) { hash->val[wpos] = (int)hashval; if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; hash->head[hashval] = (int)wpos; hash->zeros[wpos] = numzeros; if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; hash->headz[numzeros] = (int)wpos; } /* LZ77-encode the data. Return value is error code. The input are raw bytes, the output is in the form of unsigned integers with codes representing for example literal bytes, or length/distance pairs. It uses a hash table technique to let it encode faster. When doing LZ77 encoding, a sliding window (of windowsize) is used, and all past bytes in that window can be used as the "dictionary". A brute force search through all possible distances would be slow, and this hash technique is one out of several ways to speed this up. */ static unsigned encodeLZ77(uivector* out, Hash* hash, const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, unsigned minmatch, unsigned nicematch, unsigned lazymatching) { size_t pos; unsigned i, error = 0; /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8u; unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ unsigned numzeros = 0; unsigned offset; /*the offset represents the distance in LZ77 terminology*/ unsigned length; unsigned lazy = 0; unsigned lazylength = 0, lazyoffset = 0; unsigned hashval; unsigned current_offset, current_length; unsigned prev_offset; const unsigned char *lastptr, *foreptr, *backptr; unsigned hashpos; if(windowsize == 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; for(pos = inpos; pos < insize; ++pos) { size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ unsigned chainlength = 0; hashval = getHash(in, insize, pos); if(usezeros && hashval == 0) { if(numzeros == 0) numzeros = countZeros(in, insize, pos); else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { numzeros = 0; } updateHashChain(hash, wpos, hashval, numzeros); /*the length and offset found for the current position*/ length = 0; offset = 0; hashpos = hash->chain[wpos]; lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; /*search for the longest string*/ prev_offset = 0; for(;;) { if(chainlength++ >= maxchainlength) break; current_offset = (unsigned)(hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize); if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ prev_offset = current_offset; if(current_offset > 0) { /*test the next characters*/ foreptr = &in[pos]; backptr = &in[pos - current_offset]; /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ if(numzeros >= 3) { unsigned skip = hash->zeros[hashpos]; if(skip > numzeros) skip = numzeros; backptr += skip; foreptr += skip; } while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ { ++backptr; ++foreptr; } current_length = (unsigned)(foreptr - &in[pos]); if(current_length > length) { length = current_length; /*the longest length*/ offset = current_offset; /*the offset that is related to this longest length*/ /*jump out once a length of max length is found (speed gain). This also jumps out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ if(current_length >= nicematch) break; } } if(hashpos == hash->chain[hashpos]) break; if(numzeros >= 3 && length > numzeros) { hashpos = hash->chainz[hashpos]; if(hash->zeros[hashpos] != numzeros) break; } else { hashpos = hash->chain[hashpos]; /*outdated hash value, happens if particular value was not encountered in whole last window*/ if(hash->val[hashpos] != (int)hashval) break; } } if(lazymatching) { if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) { lazy = 1; lazylength = length; lazyoffset = offset; continue; /*try the next byte*/ } if(lazy) { lazy = 0; if(pos == 0) ERROR_BREAK(81); if(length > lazylength + 1) { /*push the previous character as literal*/ if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); } else { length = lazylength; offset = lazyoffset; hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ hash->headz[numzeros] = -1; /*idem*/ --pos; } } } if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); /*encode it as length/distance pair or literal value*/ if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ { if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); } else if(length < minmatch || (length == 3 && offset > 4096)) { /*compensate for the fact that longer offsets have more extra bits, a length of only 3 may be not worth it then*/ if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); } else { addLengthDistance(out, length, offset); for(i = 1; i < length; ++i) { ++pos; wpos = pos & (windowsize - 1); hashval = getHash(in, insize, pos); if(usezeros && hashval == 0) { if(numzeros == 0) numzeros = countZeros(in, insize, pos); else if(pos + numzeros > insize || in[pos + numzeros - 1] != 0) --numzeros; } else { numzeros = 0; } updateHashChain(hash, wpos, hashval, numzeros); } } } /*end of the loop through each character of input*/ return error; } /* /////////////////////////////////////////////////////////////////////////// */ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) { /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ size_t i, numdeflateblocks = (datasize + 65534u) / 65535u; unsigned datapos = 0; for(i = 0; i != numdeflateblocks; ++i) { unsigned BFINAL, BTYPE, LEN, NLEN; unsigned char firstbyte; size_t pos = out->size; BFINAL = (i == numdeflateblocks - 1); BTYPE = 0; LEN = 65535; if(datasize - datapos < 65535u) LEN = (unsigned)datasize - datapos; NLEN = 65535 - LEN; if(!ucvector_resize(out, out->size + LEN + 5)) return 83; /*alloc fail*/ firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1u) << 1u) + ((BTYPE & 2u) << 1u)); out->data[pos + 0] = firstbyte; out->data[pos + 1] = (unsigned char)(LEN & 255); out->data[pos + 2] = (unsigned char)(LEN >> 8u); out->data[pos + 3] = (unsigned char)(NLEN & 255); out->data[pos + 4] = (unsigned char)(NLEN >> 8u); lodepng_memcpy(out->data + pos + 5, data + datapos, LEN); datapos += LEN; } return 0; } /* write the lz77-encoded data, which has lit, len and dist codes, to compressed stream using huffman trees. tree_ll: the tree for lit and len codes. tree_d: the tree for distance codes. */ static void writeLZ77data(LodePNGBitWriter* writer, const uivector* lz77_encoded, const HuffmanTree* tree_ll, const HuffmanTree* tree_d) { size_t i = 0; for(i = 0; i != lz77_encoded->size; ++i) { unsigned val = lz77_encoded->data[i]; writeBitsReversed(writer, tree_ll->codes[val], tree_ll->lengths[val]); if(val > 256) /*for a length code, 3 more things have to be added*/ { unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; unsigned length_extra_bits = lz77_encoded->data[++i]; unsigned distance_code = lz77_encoded->data[++i]; unsigned distance_index = distance_code; unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; unsigned distance_extra_bits = lz77_encoded->data[++i]; writeBits(writer, length_extra_bits, n_length_extra_bits); writeBitsReversed(writer, tree_d->codes[distance_code], tree_d->lengths[distance_code]); writeBits(writer, distance_extra_bits, n_distance_extra_bits); } } } /*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ static unsigned deflateDynamic(LodePNGBitWriter* writer, Hash* hash, const unsigned char* data, size_t datapos, size_t dataend, const LodePNGCompressSettings* settings, unsigned final) { unsigned error = 0; /* A block is compressed as follows: The PNG data is lz77 encoded, resulting in literal bytes and length/distance pairs. This is then huffman compressed with two huffman trees. One huffman tree is used for the lit and len values ("ll"), another huffman tree is used for the dist values ("d"). These two trees are stored using their code lengths, and to compress even more these code lengths are also run-length encoded and huffman compressed. This gives a huffman tree of code lengths "cl". The code lengths used to describe this third tree are the code length code lengths ("clcl"). */ /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ uivector lz77_encoded; HuffmanTree tree_ll; /*tree for lit,len values*/ HuffmanTree tree_d; /*tree for distance codes*/ HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ unsigned* frequencies_ll = 0; /*frequency of lit,len codes*/ unsigned* frequencies_d = 0; /*frequency of dist codes*/ unsigned* frequencies_cl = 0; /*frequency of code length codes*/ unsigned* bitlen_lld = 0; /*lit,len,dist code lengths (int bits), literally (without repeat codes).*/ unsigned* bitlen_lld_e = 0; /*bitlen_lld encoded with repeat codes (this is a rudimentary run length compression)*/ size_t datasize = dataend - datapos; /* If we could call "bitlen_cl" the the code length code lengths ("clcl"), that is the bit lengths of codes to represent tree_cl in CLCL_ORDER, then due to the huffman compression of huffman tree representations ("two levels"), there are some analogies: bitlen_lld is to tree_cl what data is to tree_ll and tree_d. bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. */ unsigned BFINAL = final; size_t i; size_t numcodes_ll, numcodes_d, numcodes_lld, numcodes_lld_e, numcodes_cl; unsigned HLIT, HDIST, HCLEN; uivector_init(&lz77_encoded); HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); HuffmanTree_init(&tree_cl); /* could fit on stack, but >1KB is on the larger side so allocate instead */ frequencies_ll = (unsigned*)lodepng_malloc(286 * sizeof(*frequencies_ll)); frequencies_d = (unsigned*)lodepng_malloc(30 * sizeof(*frequencies_d)); frequencies_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(*frequencies_cl)); if(!frequencies_ll || !frequencies_d || !frequencies_cl) error = 83; /*alloc fail*/ /*This while loop never loops due to a break at the end, it is here to allow breaking out of it to the cleanup phase on error conditions.*/ while(!error) { lodepng_memset(frequencies_ll, 0, 286 * sizeof(*frequencies_ll)); lodepng_memset(frequencies_d, 0, 30 * sizeof(*frequencies_d)); lodepng_memset(frequencies_cl, 0, NUM_CODE_LENGTH_CODES * sizeof(*frequencies_cl)); if(settings->use_lz77) { error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, settings->minmatch, settings->nicematch, settings->lazymatching); if(error) break; } else { if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); for(i = datapos; i < dataend; ++i) lz77_encoded.data[i - datapos] = data[i]; /*no LZ77, but still will be Huffman compressed*/ } /*Count the frequencies of lit, len and dist codes*/ for(i = 0; i != lz77_encoded.size; ++i) { unsigned symbol = lz77_encoded.data[i]; ++frequencies_ll[symbol]; if(symbol > 256) { unsigned dist = lz77_encoded.data[i + 2]; ++frequencies_d[dist]; i += 3; } } frequencies_ll[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll, 257, 286, 15); if(error) break; /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d, 2, 30, 15); if(error) break; numcodes_ll = LODEPNG_MIN(tree_ll.numcodes, 286); numcodes_d = LODEPNG_MIN(tree_d.numcodes, 30); /*store the code lengths of both generated trees in bitlen_lld*/ numcodes_lld = numcodes_ll + numcodes_d; bitlen_lld = (unsigned*)lodepng_malloc(numcodes_lld * sizeof(*bitlen_lld)); /*numcodes_lld_e never needs more size than bitlen_lld*/ bitlen_lld_e = (unsigned*)lodepng_malloc(numcodes_lld * sizeof(*bitlen_lld_e)); if(!bitlen_lld || !bitlen_lld_e) ERROR_BREAK(83); /*alloc fail*/ numcodes_lld_e = 0; for(i = 0; i != numcodes_ll; ++i) bitlen_lld[i] = tree_ll.lengths[i]; for(i = 0; i != numcodes_d; ++i) bitlen_lld[numcodes_ll + i] = tree_d.lengths[i]; /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeroes), 18 (11-138 zeroes)*/ for(i = 0; i != numcodes_lld; ++i) { unsigned j = 0; /*amount of repetitions*/ while(i + j + 1 < numcodes_lld && bitlen_lld[i + j + 1] == bitlen_lld[i]) ++j; if(bitlen_lld[i] == 0 && j >= 2) /*repeat code for zeroes*/ { ++j; /*include the first zero*/ if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ { bitlen_lld_e[numcodes_lld_e++] = 17; bitlen_lld_e[numcodes_lld_e++] = j - 3; } else /*repeat code 18 supports max 138 zeroes*/ { if(j > 138) j = 138; bitlen_lld_e[numcodes_lld_e++] = 18; bitlen_lld_e[numcodes_lld_e++] = j - 11; } i += (j - 1); } else if(j >= 3) /*repeat code for value other than zero*/ { size_t k; unsigned num = j / 6u, rest = j % 6u; bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i]; for(k = 0; k < num; ++k) { bitlen_lld_e[numcodes_lld_e++] = 16; bitlen_lld_e[numcodes_lld_e++] = 6 - 3; } if(rest >= 3) { bitlen_lld_e[numcodes_lld_e++] = 16; bitlen_lld_e[numcodes_lld_e++] = rest - 3; } else j -= rest; i += j; } else /*too short to benefit from repeat code*/ { bitlen_lld_e[numcodes_lld_e++] = bitlen_lld[i]; } } /*generate tree_cl, the huffmantree of huffmantrees*/ for(i = 0; i != numcodes_lld_e; ++i) { ++frequencies_cl[bitlen_lld_e[i]]; /*after a repeat code come the bits that specify the number of repetitions, those don't need to be in the frequencies_cl calculation*/ if(bitlen_lld_e[i] >= 16) ++i; } error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl, NUM_CODE_LENGTH_CODES, NUM_CODE_LENGTH_CODES, 7); if(error) break; /*compute amount of code-length-code-lengths to output*/ numcodes_cl = NUM_CODE_LENGTH_CODES; /*trim zeros at the end (using CLCL_ORDER), but minimum size must be 4 (see HCLEN below)*/ while(numcodes_cl > 4u && tree_cl.lengths[CLCL_ORDER[numcodes_cl - 1u]] == 0) { numcodes_cl--; } /* Write everything into the output After the BFINAL and BTYPE, the dynamic block consists out of the following: - 5 bits HLIT, 5 bits HDIST, 4 bits HCLEN - (HCLEN+4)*3 bits code lengths of code length alphabet - HLIT + 257 code lengths of lit/length alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18) - HDIST + 1 code lengths of distance alphabet (encoded using the code length alphabet, + possible repetition codes 16, 17, 18) - compressed data - 256 (end code) */ /*Write block type*/ writeBits(writer, BFINAL, 1); writeBits(writer, 0, 1); /*first bit of BTYPE "dynamic"*/ writeBits(writer, 1, 1); /*second bit of BTYPE "dynamic"*/ /*write the HLIT, HDIST and HCLEN values*/ /*all three sizes take trimmed ending zeroes into account, done either by HuffmanTree_makeFromFrequencies or in the loop for numcodes_cl above, which saves space. */ HLIT = (unsigned)(numcodes_ll - 257); HDIST = (unsigned)(numcodes_d - 1); HCLEN = (unsigned)(numcodes_cl - 4); writeBits(writer, HLIT, 5); writeBits(writer, HDIST, 5); writeBits(writer, HCLEN, 4); /*write the code lengths of the code length alphabet ("bitlen_cl")*/ for(i = 0; i != numcodes_cl; ++i) writeBits(writer, tree_cl.lengths[CLCL_ORDER[i]], 3); /*write the lengths of the lit/len AND the dist alphabet*/ for(i = 0; i != numcodes_lld_e; ++i) { writeBitsReversed(writer, tree_cl.codes[bitlen_lld_e[i]], tree_cl.lengths[bitlen_lld_e[i]]); /*extra bits of repeat codes*/ if(bitlen_lld_e[i] == 16) writeBits(writer, bitlen_lld_e[++i], 2); else if(bitlen_lld_e[i] == 17) writeBits(writer, bitlen_lld_e[++i], 3); else if(bitlen_lld_e[i] == 18) writeBits(writer, bitlen_lld_e[++i], 7); } /*write the compressed data symbols*/ writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d); /*error: the length of the end code 256 must be larger than 0*/ if(tree_ll.lengths[256] == 0) ERROR_BREAK(64); /*write the end code*/ writeBitsReversed(writer, tree_ll.codes[256], tree_ll.lengths[256]); break; /*end of error-while*/ } /*cleanup*/ uivector_cleanup(&lz77_encoded); HuffmanTree_cleanup(&tree_ll); HuffmanTree_cleanup(&tree_d); HuffmanTree_cleanup(&tree_cl); lodepng_free(frequencies_ll); lodepng_free(frequencies_d); lodepng_free(frequencies_cl); lodepng_free(bitlen_lld); lodepng_free(bitlen_lld_e); return error; } static unsigned deflateFixed(LodePNGBitWriter* writer, Hash* hash, const unsigned char* data, size_t datapos, size_t dataend, const LodePNGCompressSettings* settings, unsigned final) { HuffmanTree tree_ll; /*tree for literal values and length codes*/ HuffmanTree tree_d; /*tree for distance codes*/ unsigned BFINAL = final; unsigned error = 0; size_t i; HuffmanTree_init(&tree_ll); HuffmanTree_init(&tree_d); error = generateFixedLitLenTree(&tree_ll); if(!error) error = generateFixedDistanceTree(&tree_d); if(!error) { writeBits(writer, BFINAL, 1); writeBits(writer, 1, 1); /*first bit of BTYPE*/ writeBits(writer, 0, 1); /*second bit of BTYPE*/ if(settings->use_lz77) /*LZ77 encoded*/ { uivector lz77_encoded; uivector_init(&lz77_encoded); error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, settings->minmatch, settings->nicematch, settings->lazymatching); if(!error) writeLZ77data(writer, &lz77_encoded, &tree_ll, &tree_d); uivector_cleanup(&lz77_encoded); } else /*no LZ77, but still will be Huffman compressed*/ { for(i = datapos; i < dataend; ++i) { writeBitsReversed(writer, tree_ll.codes[data[i]], tree_ll.lengths[data[i]]); } } /*add END code*/ if(!error) writeBitsReversed(writer,tree_ll.codes[256], tree_ll.lengths[256]); } /*cleanup*/ HuffmanTree_cleanup(&tree_ll); HuffmanTree_cleanup(&tree_d); return error; } static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { unsigned error = 0; size_t i, blocksize, numdeflateblocks; Hash hash; LodePNGBitWriter writer; LodePNGBitWriter_init(&writer, out); if(settings->btype > 2) return 61; else if(settings->btype == 0) return deflateNoCompression(out, in, insize); else if(settings->btype == 1) blocksize = insize; else /*if(settings->btype == 2)*/ { /*on PNGs, deflate blocks of 65-262k seem to give most dense encoding*/ blocksize = insize / 8u + 8; if(blocksize < 65536) blocksize = 65536; if(blocksize > 262144) blocksize = 262144; } numdeflateblocks = (insize + blocksize - 1) / blocksize; if(numdeflateblocks == 0) numdeflateblocks = 1; error = hash_init(&hash, settings->windowsize); if(!error) { for(i = 0; i != numdeflateblocks && !error; ++i) { unsigned final = (i == numdeflateblocks - 1); size_t start = i * blocksize; size_t end = start + blocksize; if(end > insize) end = insize; if(settings->btype == 1) error = deflateFixed(&writer, &hash, in, start, end, settings, final); else if(settings->btype == 2) error = deflateDynamic(&writer, &hash, in, start, end, settings, final); } } hash_cleanup(&hash); return error; } unsigned lodepng_deflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { ucvector v = ucvector_init(*out, *outsize); unsigned error = lodepng_deflatev(&v, in, insize, settings); *out = v.data; *outsize = v.size; return error; } static unsigned deflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { if(settings->custom_deflate) { unsigned error = settings->custom_deflate(out, outsize, in, insize, settings); /*the custom deflate is allowed to have its own error codes, however, we translate it to code 111*/ return error ? 111 : 0; } else { return lodepng_deflate(out, outsize, in, insize, settings); } } #endif /*LODEPNG_COMPILE_DECODER*/ /* ////////////////////////////////////////////////////////////////////////// */ /* / Adler32 / */ /* ////////////////////////////////////////////////////////////////////////// */ static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) { unsigned s1 = adler & 0xffffu; unsigned s2 = (adler >> 16u) & 0xffffu; while(len != 0u) { unsigned i; /*at least 5552 sums can be done before the sums overflow, saving a lot of module divisions*/ unsigned amount = len > 5552u ? 5552u : len; len -= amount; for(i = 0; i != amount; ++i) { s1 += (*data++); s2 += s1; } s1 %= 65521u; s2 %= 65521u; } return (s2 << 16u) | s1; } /*Return the adler32 of the bytes data[0..len-1]*/ static unsigned adler32(const unsigned char* data, unsigned len) { return update_adler32(1u, data, len); } /* ////////////////////////////////////////////////////////////////////////// */ /* / Zlib / */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_DECODER static unsigned lodepng_zlib_decompressv(ucvector* out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { unsigned error = 0; unsigned CM, CINFO, FDICT; if(insize < 2) return 53; /*error, size of zlib data too small*/ /*read information from zlib header*/ if((in[0] * 256 + in[1]) % 31 != 0) { /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ return 24; } CM = in[0] & 15; CINFO = (in[0] >> 4) & 15; /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ FDICT = (in[1] >> 5) & 1; /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ if(CM != 8 || CINFO > 7) { /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ return 25; } if(FDICT != 0) { /*error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."*/ return 26; } error = inflatev(out, in + 2, insize - 2, settings); if(error) return error; if(!settings->ignore_adler32) { unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); unsigned checksum = adler32(out->data, (unsigned)(out->size)); if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ } return 0; /*no error*/ } unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { ucvector v = ucvector_init(*out, *outsize); unsigned error = lodepng_zlib_decompressv(&v, in, insize, settings); *out = v.data; *outsize = v.size; return error; } /*expected_size is expected output size, to avoid intermediate allocations. Set to 0 if not known. */ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { unsigned error; if(settings->custom_zlib) { error = settings->custom_zlib(out, outsize, in, insize, settings); if(error) { /*the custom zlib is allowed to have its own error codes, however, we translate it to code 110*/ error = 110; /*if there's a max output size, and the custom zlib returned error, then indicate that error instead*/ if(settings->max_output_size && *outsize > settings->max_output_size) error = 109; } } else { ucvector v = ucvector_init(*out, *outsize); if(expected_size) { /*reserve the memory to avoid intermediate reallocations*/ ucvector_resize(&v, *outsize + expected_size); v.size = *outsize; } error = lodepng_zlib_decompressv(&v, in, insize, settings); *out = v.data; *outsize = v.size; } return error; } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { size_t i; unsigned error; unsigned char* deflatedata = 0; size_t deflatesize = 0; error = deflate(&deflatedata, &deflatesize, in, insize, settings); *out = NULL; *outsize = 0; if(!error) { *outsize = deflatesize + 6; *out = (unsigned char*)lodepng_malloc(*outsize); if(!*out) error = 83; /*alloc fail*/ } if(!error) { unsigned ADLER32 = adler32(in, (unsigned)insize); /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ unsigned FLEVEL = 0; unsigned FDICT = 0; unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; unsigned FCHECK = 31 - CMFFLG % 31; CMFFLG += FCHECK; (*out)[0] = (unsigned char)(CMFFLG >> 8); (*out)[1] = (unsigned char)(CMFFLG & 255); for(i = 0; i != deflatesize; ++i) (*out)[i + 2] = deflatedata[i]; lodepng_set32bitInt(&(*out)[*outsize - 4], ADLER32); } lodepng_free(deflatedata); return error; } /* compress using the default or custom zlib function */ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { if(settings->custom_zlib) { unsigned error = settings->custom_zlib(out, outsize, in, insize, settings); /*the custom zlib is allowed to have its own error codes, however, we translate it to code 111*/ return error ? 111 : 0; } else { return lodepng_zlib_compress(out, outsize, in, insize, settings); } } #endif /*LODEPNG_COMPILE_ENCODER*/ #else /*no LODEPNG_COMPILE_ZLIB*/ #ifdef LODEPNG_COMPILE_DECODER static unsigned zlib_decompress(unsigned char** out, size_t* outsize, size_t expected_size, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings) { if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ (void)expected_size; return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings) { if(!settings->custom_zlib) return 87; /*no custom zlib function provided */ return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_ENCODER /*this is a good tradeoff between speed and compression ratio*/ #define DEFAULT_WINDOWSIZE 2048 void lodepng_compress_settings_init(LodePNGCompressSettings* settings) { /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ settings->btype = 2; settings->use_lz77 = 1; settings->windowsize = DEFAULT_WINDOWSIZE; settings->minmatch = 3; settings->nicematch = 128; settings->lazymatching = 1; settings->custom_zlib = 0; settings->custom_deflate = 0; settings->custom_context = 0; } const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DECODER void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) { settings->ignore_adler32 = 0; settings->ignore_nlen = 0; settings->max_output_size = 0; settings->custom_zlib = 0; settings->custom_inflate = 0; settings->custom_context = 0; } const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0, 0, 0}; #endif /*LODEPNG_COMPILE_DECODER*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // End of Zlib related code. Begin of PNG related code. // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_PNG /* ////////////////////////////////////////////////////////////////////////// */ /* / CRC32 / */ /* ////////////////////////////////////////////////////////////////////////// */ #ifndef LODEPNG_NO_COMPILE_CRC /* CRC polynomial: 0xedb88320 */ static unsigned lodepng_crc32_table[256] = { 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u }; /*Return the CRC of the bytes buf[0..len-1].*/ unsigned lodepng_crc32(const unsigned char* data, size_t length) { unsigned r = 0xffffffffu; size_t i; for(i = 0; i < length; ++i) { r = lodepng_crc32_table[(r ^ data[i]) & 0xffu] ^ (r >> 8u); } return r ^ 0xffffffffu; } #else /* !LODEPNG_NO_COMPILE_CRC */ unsigned lodepng_crc32(const unsigned char* data, size_t length); #endif /* !LODEPNG_NO_COMPILE_CRC */ /* ////////////////////////////////////////////////////////////////////////// */ /* / Reading and writing PNG color channel bits / */ /* ////////////////////////////////////////////////////////////////////////// */ /* The color channel bits of less-than-8-bit pixels are read with the MSB of bytes first, so LodePNGBitWriter and LodePNGBitReader can't be used for those. */ static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) { unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); ++(*bitpointer); return result; } /* TODO: make this faster */ static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { unsigned result = 0; size_t i; for(i = 0 ; i < nbits; ++i) { result <<= 1u; result |= (unsigned)readBitFromReversedStream(bitpointer, bitstream); } return result; } static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { /*the current bit in bitstream may be 0 or 1 for this to work*/ if(bit == 0) bitstream[(*bitpointer) >> 3u] &= (unsigned char)(~(1u << (7u - ((*bitpointer) & 7u)))); else bitstream[(*bitpointer) >> 3u] |= (1u << (7u - ((*bitpointer) & 7u))); ++(*bitpointer); } /* ////////////////////////////////////////////////////////////////////////// */ /* / PNG chunks / */ /* ////////////////////////////////////////////////////////////////////////// */ unsigned lodepng_chunk_length(const unsigned char* chunk) { return lodepng_read32bitInt(&chunk[0]); } void lodepng_chunk_type(char type[5], const unsigned char* chunk) { unsigned i; for(i = 0; i != 4; ++i) type[i] = (char)chunk[4 + i]; type[4] = 0; /*null termination char*/ } unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) { if(lodepng_strlen(type) != 4) return 0; return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); } unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) { return((chunk[4] & 32) != 0); } unsigned char lodepng_chunk_private(const unsigned char* chunk) { return((chunk[6] & 32) != 0); } unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) { return((chunk[7] & 32) != 0); } unsigned char* lodepng_chunk_data(unsigned char* chunk) { return &chunk[8]; } const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) { return &chunk[8]; } #ifndef LODEPNG_NO_COMPILE_CRC unsigned lodepng_chunk_check_crc(const unsigned char* chunk) { unsigned length = lodepng_chunk_length(chunk); unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ unsigned checksum = lodepng_crc32(&chunk[4], length + 4); if(CRC != checksum) return 1; else return 0; } #endif void lodepng_chunk_generate_crc(unsigned char* chunk) { unsigned length = lodepng_chunk_length(chunk); #ifndef LODEPNG_NO_COMPILE_CRC unsigned CRC = lodepng_crc32(&chunk[4], length + 4); #else unsigned CRC = 0; #endif lodepng_set32bitInt(chunk + 8 + length, CRC); } unsigned char* lodepng_chunk_next(unsigned char* chunk, unsigned char* end) { if(chunk >= end || end - chunk < 12) return end; /*too small to contain a chunk*/ if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ return chunk + 8; } else { size_t total_chunk_length; unsigned char* result; if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; result = chunk + total_chunk_length; if(result < chunk) return end; /*pointer overflow*/ return result; } } const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk, const unsigned char* end) { if(chunk >= end || end - chunk < 12) return end; /*too small to contain a chunk*/ if(chunk[0] == 0x89 && chunk[1] == 0x50 && chunk[2] == 0x4e && chunk[3] == 0x47 && chunk[4] == 0x0d && chunk[5] == 0x0a && chunk[6] == 0x1a && chunk[7] == 0x0a) { /* Is PNG magic header at start of PNG file. Jump to first actual chunk. */ return chunk + 8; } else { size_t total_chunk_length; const unsigned char* result; if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return end; result = chunk + total_chunk_length; if(result < chunk) return end; /*pointer overflow*/ return result; } } unsigned char* lodepng_chunk_find(unsigned char* chunk, unsigned char* end, const char type[5]) { for(;;) { if(chunk >= end || end - chunk < 12) return 0; /* past file end: chunk + 12 > end */ if(lodepng_chunk_type_equals(chunk, type)) return chunk; chunk = lodepng_chunk_next(chunk, end); } } const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]) { for(;;) { if(chunk >= end || end - chunk < 12) return 0; /* past file end: chunk + 12 > end */ if(lodepng_chunk_type_equals(chunk, type)) return chunk; chunk = lodepng_chunk_next_const(chunk, end); } } unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk) { unsigned i; size_t total_chunk_length, new_length; unsigned char *chunk_start, *new_buffer; if(lodepng_addofl(lodepng_chunk_length(chunk), 12, &total_chunk_length)) return 77; if(lodepng_addofl(*outsize, total_chunk_length, &new_length)) return 77; new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); if(!new_buffer) return 83; /*alloc fail*/ (*out) = new_buffer; (*outsize) = new_length; chunk_start = &(*out)[new_length - total_chunk_length]; for(i = 0; i != total_chunk_length; ++i) chunk_start[i] = chunk[i]; return 0; } /*Sets length and name and allocates the space for data and crc but does not set data or crc yet. Returns the start of the chunk in chunk. The start of the data is at chunk + 8. To finalize chunk, add the data, then use lodepng_chunk_generate_crc */ static unsigned lodepng_chunk_init(unsigned char** chunk, ucvector* out, unsigned length, const char* type) { size_t new_length = out->size; if(lodepng_addofl(new_length, length, &new_length)) return 77; if(lodepng_addofl(new_length, 12, &new_length)) return 77; if(!ucvector_resize(out, new_length)) return 83; /*alloc fail*/ *chunk = out->data + new_length - length - 12u; /*1: length*/ lodepng_set32bitInt(*chunk, length); /*2: chunk name (4 letters)*/ lodepng_memcpy(*chunk + 4, type, 4); return 0; } /* like lodepng_chunk_create but with custom allocsize */ static unsigned lodepng_chunk_createv(ucvector* out, unsigned length, const char* type, const unsigned char* data) { unsigned char* chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, length, type)); /*3: the data*/ lodepng_memcpy(chunk + 8, data, length); /*4: CRC (of the chunkname characters and the data)*/ lodepng_chunk_generate_crc(chunk); return 0; } unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length, const char* type, const unsigned char* data) { ucvector v = ucvector_init(*out, *outsize); unsigned error = lodepng_chunk_createv(&v, length, type, data); *out = v.data; *outsize = v.size; return error; } /* ////////////////////////////////////////////////////////////////////////// */ /* / Color types, channels, bits / */ /* ////////////////////////////////////////////////////////////////////////// */ /*checks if the colortype is valid and the bitdepth bd is allowed for this colortype. Return value is a LodePNG error code.*/ static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) { switch(colortype) { case LCT_GREY: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; case LCT_RGB: if(!( bd == 8 || bd == 16)) return 37; break; case LCT_PALETTE: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; case LCT_GREY_ALPHA: if(!( bd == 8 || bd == 16)) return 37; break; case LCT_RGBA: if(!( bd == 8 || bd == 16)) return 37; break; case LCT_MAX_OCTET_VALUE: return 31; /* invalid color type */ default: return 31; /* invalid color type */ } return 0; /*allowed color type / bits combination*/ } static unsigned getNumColorChannels(LodePNGColorType colortype) { switch(colortype) { case LCT_GREY: return 1; case LCT_RGB: return 3; case LCT_PALETTE: return 1; case LCT_GREY_ALPHA: return 2; case LCT_RGBA: return 4; case LCT_MAX_OCTET_VALUE: return 0; /* invalid color type */ default: return 0; /*invalid color type*/ } } static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) { /*bits per pixel is amount of channels * bits per channel*/ return getNumColorChannels(colortype) * bitdepth; } /* ////////////////////////////////////////////////////////////////////////// */ void lodepng_color_mode_init(LodePNGColorMode* info) { info->key_defined = 0; info->key_r = info->key_g = info->key_b = 0; info->colortype = LCT_RGBA; info->bitdepth = 8; info->palette = 0; info->palettesize = 0; } /*allocates palette memory if needed, and initializes all colors to black*/ static void lodepng_color_mode_alloc_palette(LodePNGColorMode* info) { size_t i; /*if the palette is already allocated, it will have size 1024 so no reallocation needed in that case*/ /*the palette must have room for up to 256 colors with 4 bytes each.*/ if(!info->palette) info->palette = (unsigned char*)lodepng_malloc(1024); if(!info->palette) return; /*alloc fail*/ for(i = 0; i != 256; ++i) { /*Initialize all unused colors with black, the value used for invalid palette indices. This is an error according to the PNG spec, but common PNG decoders make it black instead. That makes color conversion slightly faster due to no error handling needed.*/ info->palette[i * 4 + 0] = 0; info->palette[i * 4 + 1] = 0; info->palette[i * 4 + 2] = 0; info->palette[i * 4 + 3] = 255; } } void lodepng_color_mode_cleanup(LodePNGColorMode* info) { lodepng_palette_clear(info); } unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) { lodepng_color_mode_cleanup(dest); lodepng_memcpy(dest, source, sizeof(LodePNGColorMode)); if(source->palette) { dest->palette = (unsigned char*)lodepng_malloc(1024); if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ lodepng_memcpy(dest->palette, source->palette, source->palettesize * 4); } return 0; } LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth) { LodePNGColorMode result; lodepng_color_mode_init(&result); result.colortype = colortype; result.bitdepth = bitdepth; return result; } static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) { size_t i; if(a->colortype != b->colortype) return 0; if(a->bitdepth != b->bitdepth) return 0; if(a->key_defined != b->key_defined) return 0; if(a->key_defined) { if(a->key_r != b->key_r) return 0; if(a->key_g != b->key_g) return 0; if(a->key_b != b->key_b) return 0; } if(a->palettesize != b->palettesize) return 0; for(i = 0; i != a->palettesize * 4; ++i) { if(a->palette[i] != b->palette[i]) return 0; } return 1; } void lodepng_palette_clear(LodePNGColorMode* info) { if(info->palette) lodepng_free(info->palette); info->palette = 0; info->palettesize = 0; } unsigned lodepng_palette_add(LodePNGColorMode* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { if(!info->palette) /*allocate palette if empty*/ { lodepng_color_mode_alloc_palette(info); if(!info->palette) return 83; /*alloc fail*/ } if(info->palettesize >= 256) { return 108; /*too many palette values*/ } info->palette[4 * info->palettesize + 0] = r; info->palette[4 * info->palettesize + 1] = g; info->palette[4 * info->palettesize + 2] = b; info->palette[4 * info->palettesize + 3] = a; ++info->palettesize; return 0; } /*calculate bits per pixel out of colortype and bitdepth*/ unsigned lodepng_get_bpp(const LodePNGColorMode* info) { return lodepng_get_bpp_lct(info->colortype, info->bitdepth); } unsigned lodepng_get_channels(const LodePNGColorMode* info) { return getNumColorChannels(info->colortype); } unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) { return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; } unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) { return (info->colortype & 4) != 0; /*4 or 6*/ } unsigned lodepng_is_palette_type(const LodePNGColorMode* info) { return info->colortype == LCT_PALETTE; } unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) { size_t i; for(i = 0; i != info->palettesize; ++i) { if(info->palette[i * 4 + 3] < 255) return 1; } return 0; } unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) { return info->key_defined || lodepng_is_alpha_type(info) || lodepng_has_palette_alpha(info); } static size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { size_t bpp = lodepng_get_bpp_lct(colortype, bitdepth); size_t n = (size_t)w * (size_t)h; return ((n / 8u) * bpp) + ((n & 7u) * bpp + 7u) / 8u; } size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { return lodepng_get_raw_size_lct(w, h, color->colortype, color->bitdepth); } #ifdef LODEPNG_COMPILE_PNG /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer, and in addition has one extra byte per line: the filter byte. So this gives a larger result than lodepng_get_raw_size. Set h to 1 to get the size of 1 row including filter byte. */ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, unsigned bpp) { /* + 1 for the filter byte, and possibly plus padding bits per line. */ /* Ignoring casts, the expression is equal to (w * bpp + 7) / 8 + 1, but avoids overflow of w * bpp */ size_t line = ((size_t)(w / 8u) * bpp) + 1u + ((w & 7u) * bpp + 7u) / 8u; return (size_t)h * line; } #ifdef LODEPNG_COMPILE_DECODER /*Safely checks whether size_t overflow can be caused due to amount of pixels. This check is overcautious rather than precise. If this check indicates no overflow, you can safely compute in a size_t (but not an unsigned): -(size_t)w * (size_t)h * 8 -amount of bytes in IDAT (including filter, padding and Adam7 bytes) -amount of bytes in raw color model Returns 1 if overflow possible, 0 if not. */ static int lodepng_pixel_overflow(unsigned w, unsigned h, const LodePNGColorMode* pngcolor, const LodePNGColorMode* rawcolor) { size_t bpp = LODEPNG_MAX(lodepng_get_bpp(pngcolor), lodepng_get_bpp(rawcolor)); size_t numpixels, total; size_t line; /* bytes per line in worst case */ if(lodepng_mulofl((size_t)w, (size_t)h, &numpixels)) return 1; if(lodepng_mulofl(numpixels, 8, &total)) return 1; /* bit pointer with 8-bit color, or 8 bytes per channel color */ /* Bytes per scanline with the expression "(w / 8u) * bpp) + ((w & 7u) * bpp + 7u) / 8u" */ if(lodepng_mulofl((size_t)(w / 8u), bpp, &line)) return 1; if(lodepng_addofl(line, ((w & 7u) * bpp + 7u) / 8u, &line)) return 1; if(lodepng_addofl(line, 5, &line)) return 1; /* 5 bytes overhead per line: 1 filterbyte, 4 for Adam7 worst case */ if(lodepng_mulofl(line, h, &total)) return 1; /* Total bytes in worst case */ return 0; /* no overflow */ } #endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static void LodePNGUnknownChunks_init(LodePNGInfo* info) { unsigned i; for(i = 0; i != 3; ++i) info->unknown_chunks_data[i] = 0; for(i = 0; i != 3; ++i) info->unknown_chunks_size[i] = 0; } static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) { unsigned i; for(i = 0; i != 3; ++i) lodepng_free(info->unknown_chunks_data[i]); } static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) { unsigned i; LodePNGUnknownChunks_cleanup(dest); for(i = 0; i != 3; ++i) { size_t j; dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ for(j = 0; j < src->unknown_chunks_size[i]; ++j) { dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; } } return 0; } /******************************************************************************/ static void LodePNGText_init(LodePNGInfo* info) { info->text_num = 0; info->text_keys = NULL; info->text_strings = NULL; } static void LodePNGText_cleanup(LodePNGInfo* info) { size_t i; for(i = 0; i != info->text_num; ++i) { string_cleanup(&info->text_keys[i]); string_cleanup(&info->text_strings[i]); } lodepng_free(info->text_keys); lodepng_free(info->text_strings); } static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { size_t i = 0; dest->text_keys = NULL; dest->text_strings = NULL; dest->text_num = 0; for(i = 0; i != source->text_num; ++i) { CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); } return 0; } static unsigned lodepng_add_text_sized(LodePNGInfo* info, const char* key, const char* str, size_t size) { char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); if(new_keys) info->text_keys = new_keys; if(new_strings) info->text_strings = new_strings; if(!new_keys || !new_strings) return 83; /*alloc fail*/ ++info->text_num; info->text_keys[info->text_num - 1] = alloc_string(key); info->text_strings[info->text_num - 1] = alloc_string_sized(str, size); if(!info->text_keys[info->text_num - 1] || !info->text_strings[info->text_num - 1]) return 83; /*alloc fail*/ return 0; } unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) { return lodepng_add_text_sized(info, key, str, lodepng_strlen(str)); } void lodepng_clear_text(LodePNGInfo* info) { LodePNGText_cleanup(info); } /******************************************************************************/ static void LodePNGIText_init(LodePNGInfo* info) { info->itext_num = 0; info->itext_keys = NULL; info->itext_langtags = NULL; info->itext_transkeys = NULL; info->itext_strings = NULL; } static void LodePNGIText_cleanup(LodePNGInfo* info) { size_t i; for(i = 0; i != info->itext_num; ++i) { string_cleanup(&info->itext_keys[i]); string_cleanup(&info->itext_langtags[i]); string_cleanup(&info->itext_transkeys[i]); string_cleanup(&info->itext_strings[i]); } lodepng_free(info->itext_keys); lodepng_free(info->itext_langtags); lodepng_free(info->itext_transkeys); lodepng_free(info->itext_strings); } static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { size_t i = 0; dest->itext_keys = NULL; dest->itext_langtags = NULL; dest->itext_transkeys = NULL; dest->itext_strings = NULL; dest->itext_num = 0; for(i = 0; i != source->itext_num; ++i) { CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], source->itext_transkeys[i], source->itext_strings[i])); } return 0; } void lodepng_clear_itext(LodePNGInfo* info) { LodePNGIText_cleanup(info); } static unsigned lodepng_add_itext_sized(LodePNGInfo* info, const char* key, const char* langtag, const char* transkey, const char* str, size_t size) { char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); if(new_keys) info->itext_keys = new_keys; if(new_langtags) info->itext_langtags = new_langtags; if(new_transkeys) info->itext_transkeys = new_transkeys; if(new_strings) info->itext_strings = new_strings; if(!new_keys || !new_langtags || !new_transkeys || !new_strings) return 83; /*alloc fail*/ ++info->itext_num; info->itext_keys[info->itext_num - 1] = alloc_string(key); info->itext_langtags[info->itext_num - 1] = alloc_string(langtag); info->itext_transkeys[info->itext_num - 1] = alloc_string(transkey); info->itext_strings[info->itext_num - 1] = alloc_string_sized(str, size); return 0; } unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, const char* transkey, const char* str) { return lodepng_add_itext_sized(info, key, langtag, transkey, str, lodepng_strlen(str)); } /* same as set but does not delete */ static unsigned lodepng_assign_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) { if(profile_size == 0) return 100; /*invalid ICC profile size*/ info->iccp_name = alloc_string(name); info->iccp_profile = (unsigned char*)lodepng_malloc(profile_size); if(!info->iccp_name || !info->iccp_profile) return 83; /*alloc fail*/ lodepng_memcpy(info->iccp_profile, profile, profile_size); info->iccp_profile_size = profile_size; return 0; /*ok*/ } unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size) { if(info->iccp_name) lodepng_clear_icc(info); info->iccp_defined = 1; return lodepng_assign_icc(info, name, profile, profile_size); } void lodepng_clear_icc(LodePNGInfo* info) { string_cleanup(&info->iccp_name); lodepng_free(info->iccp_profile); info->iccp_profile = NULL; info->iccp_profile_size = 0; info->iccp_defined = 0; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ void lodepng_info_init(LodePNGInfo* info) { lodepng_color_mode_init(&info->color); info->interlace_method = 0; info->compression_method = 0; info->filter_method = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS info->background_defined = 0; info->background_r = info->background_g = info->background_b = 0; LodePNGText_init(info); LodePNGIText_init(info); info->time_defined = 0; info->phys_defined = 0; info->gama_defined = 0; info->chrm_defined = 0; info->srgb_defined = 0; info->iccp_defined = 0; info->iccp_name = NULL; info->iccp_profile = NULL; LodePNGUnknownChunks_init(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } void lodepng_info_cleanup(LodePNGInfo* info) { lodepng_color_mode_cleanup(&info->color); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS LodePNGText_cleanup(info); LodePNGIText_cleanup(info); lodepng_clear_icc(info); LodePNGUnknownChunks_cleanup(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) { lodepng_info_cleanup(dest); lodepng_memcpy(dest, source, sizeof(LodePNGInfo)); lodepng_color_mode_init(&dest->color); CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); if(source->iccp_defined) { CERROR_TRY_RETURN(lodepng_assign_icc(dest, source->iccp_name, source->iccp_profile, source->iccp_profile_size)); } LodePNGUnknownChunks_init(dest); CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ return 0; } /* ////////////////////////////////////////////////////////////////////////// */ /*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) { unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ unsigned p = index & m; in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ in = in << (bits * (m - p)); if(p == 0) out[index * bits / 8u] = in; else out[index * bits / 8u] |= in; } typedef struct ColorTree ColorTree; /* One node of a color tree This is the data structure used to count the number of unique colors and to get a palette index for a color. It's like an octree, but because the alpha channel is used too, each node has 16 instead of 8 children. */ struct ColorTree { ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ int index; /*the payload. Only has a meaningful value if this is in the last level*/ }; static void color_tree_init(ColorTree* tree) { lodepng_memset(tree->children, 0, 16 * sizeof(*tree->children)); tree->index = -1; } static void color_tree_cleanup(ColorTree* tree) { int i; for(i = 0; i != 16; ++i) { if(tree->children[i]) { color_tree_cleanup(tree->children[i]); lodepng_free(tree->children[i]); } } } /*returns -1 if color not present, its index otherwise*/ static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { int bit = 0; for(bit = 0; bit < 8; ++bit) { int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); if(!tree->children[i]) return -1; else tree = tree->children[i]; } return tree ? tree->index : -1; } #ifdef LODEPNG_COMPILE_ENCODER static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { return color_tree_get(tree, r, g, b, a) >= 0; } #endif /*LODEPNG_COMPILE_ENCODER*/ /*color is not allowed to already exist. Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist") Returns error code, or 0 if ok*/ static unsigned color_tree_add(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) { int bit; for(bit = 0; bit < 8; ++bit) { int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); if(!tree->children[i]) { tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); if(!tree->children[i]) return 83; /*alloc fail*/ color_tree_init(tree->children[i]); } tree = tree->children[i]; } tree->index = (int)index; return 0; } /*put a pixel, given its RGBA color, into image of any color type*/ static unsigned rgba8ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { if(mode->colortype == LCT_GREY) { unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ if(mode->bitdepth == 8) out[i] = gray; else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = gray; else { /*take the most significant bits of gray*/ gray = ((unsigned)gray >> (8u - mode->bitdepth)) & ((1u << mode->bitdepth) - 1u); addColorBits(out, i, mode->bitdepth, gray); } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { out[i * 3 + 0] = r; out[i * 3 + 1] = g; out[i * 3 + 2] = b; } else { out[i * 6 + 0] = out[i * 6 + 1] = r; out[i * 6 + 2] = out[i * 6 + 3] = g; out[i * 6 + 4] = out[i * 6 + 5] = b; } } else if(mode->colortype == LCT_PALETTE) { int index = color_tree_get(tree, r, g, b, a); if(index < 0) return 82; /*color not in palette*/ if(mode->bitdepth == 8) out[i] = index; else addColorBits(out, i, mode->bitdepth, (unsigned)index); } else if(mode->colortype == LCT_GREY_ALPHA) { unsigned char gray = r; /*((unsigned short)r + g + b) / 3u;*/ if(mode->bitdepth == 8) { out[i * 2 + 0] = gray; out[i * 2 + 1] = a; } else if(mode->bitdepth == 16) { out[i * 4 + 0] = out[i * 4 + 1] = gray; out[i * 4 + 2] = out[i * 4 + 3] = a; } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { out[i * 4 + 0] = r; out[i * 4 + 1] = g; out[i * 4 + 2] = b; out[i * 4 + 3] = a; } else { out[i * 8 + 0] = out[i * 8 + 1] = r; out[i * 8 + 2] = out[i * 8 + 3] = g; out[i * 8 + 4] = out[i * 8 + 5] = b; out[i * 8 + 6] = out[i * 8 + 7] = a; } } return 0; /*no error*/ } /*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ static void rgba16ToPixel(unsigned char* out, size_t i, const LodePNGColorMode* mode, unsigned short r, unsigned short g, unsigned short b, unsigned short a) { if(mode->colortype == LCT_GREY) { unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ out[i * 2 + 0] = (gray >> 8) & 255; out[i * 2 + 1] = gray & 255; } else if(mode->colortype == LCT_RGB) { out[i * 6 + 0] = (r >> 8) & 255; out[i * 6 + 1] = r & 255; out[i * 6 + 2] = (g >> 8) & 255; out[i * 6 + 3] = g & 255; out[i * 6 + 4] = (b >> 8) & 255; out[i * 6 + 5] = b & 255; } else if(mode->colortype == LCT_GREY_ALPHA) { unsigned short gray = r; /*((unsigned)r + g + b) / 3u;*/ out[i * 4 + 0] = (gray >> 8) & 255; out[i * 4 + 1] = gray & 255; out[i * 4 + 2] = (a >> 8) & 255; out[i * 4 + 3] = a & 255; } else if(mode->colortype == LCT_RGBA) { out[i * 8 + 0] = (r >> 8) & 255; out[i * 8 + 1] = r & 255; out[i * 8 + 2] = (g >> 8) & 255; out[i * 8 + 3] = g & 255; out[i * 8 + 4] = (b >> 8) & 255; out[i * 8 + 5] = b & 255; out[i * 8 + 6] = (a >> 8) & 255; out[i * 8 + 7] = a & 255; } } /*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a, const unsigned char* in, size_t i, const LodePNGColorMode* mode) { if(mode->colortype == LCT_GREY) { if(mode->bitdepth == 8) { *r = *g = *b = in[i]; if(mode->key_defined && *r == mode->key_r) *a = 0; else *a = 255; } else if(mode->bitdepth == 16) { *r = *g = *b = in[i * 2 + 0]; if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; else *a = 255; } else { unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ size_t j = i * mode->bitdepth; unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); *r = *g = *b = (value * 255) / highest; if(mode->key_defined && value == mode->key_r) *a = 0; else *a = 255; } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; else *a = 255; } else { *r = in[i * 6 + 0]; *g = in[i * 6 + 2]; *b = in[i * 6 + 4]; if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; else *a = 255; } } else if(mode->colortype == LCT_PALETTE) { unsigned index; if(mode->bitdepth == 8) index = in[i]; else { size_t j = i * mode->bitdepth; index = readBitsFromReversedStream(&j, in, mode->bitdepth); } /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ *r = mode->palette[index * 4 + 0]; *g = mode->palette[index * 4 + 1]; *b = mode->palette[index * 4 + 2]; *a = mode->palette[index * 4 + 3]; } else if(mode->colortype == LCT_GREY_ALPHA) { if(mode->bitdepth == 8) { *r = *g = *b = in[i * 2 + 0]; *a = in[i * 2 + 1]; } else { *r = *g = *b = in[i * 4 + 0]; *a = in[i * 4 + 2]; } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { *r = in[i * 4 + 0]; *g = in[i * 4 + 1]; *b = in[i * 4 + 2]; *a = in[i * 4 + 3]; } else { *r = in[i * 8 + 0]; *g = in[i * 8 + 2]; *b = in[i * 8 + 4]; *a = in[i * 8 + 6]; } } } /*Similar to getPixelColorRGBA8, but with all the for loops inside of the color mode test cases, optimized to convert the colors much faster, when converting to the common case of RGBA with 8 bit per channel. buffer must be RGBA with enough memory.*/ static void getPixelColorsRGBA8(unsigned char* LODEPNG_RESTRICT buffer, size_t numpixels, const unsigned char* LODEPNG_RESTRICT in, const LodePNGColorMode* mode) { unsigned num_channels = 4; size_t i; if(mode->colortype == LCT_GREY) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i]; buffer[3] = 255; } if(mode->key_defined) { buffer -= numpixels * num_channels; for(i = 0; i != numpixels; ++i, buffer += num_channels) { if(buffer[0] == mode->key_r) buffer[3] = 0; } } } else if(mode->bitdepth == 16) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2]; buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; } } else { unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ size_t j = 0; for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; } } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { lodepng_memcpy(buffer, &in[i * 3], 3); buffer[3] = 255; } if(mode->key_defined) { buffer -= numpixels * num_channels; for(i = 0; i != numpixels; ++i, buffer += num_channels) { if(buffer[0] == mode->key_r && buffer[1]== mode->key_g && buffer[2] == mode->key_b) buffer[3] = 0; } } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 6 + 0]; buffer[1] = in[i * 6 + 2]; buffer[2] = in[i * 6 + 4]; buffer[3] = mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; } } } else if(mode->colortype == LCT_PALETTE) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned index = in[i]; /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ lodepng_memcpy(buffer, &mode->palette[index * 4], 4); } } else { size_t j = 0; for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth); /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ lodepng_memcpy(buffer, &mode->palette[index * 4], 4); } } } else if(mode->colortype == LCT_GREY_ALPHA) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; buffer[3] = in[i * 2 + 1]; } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; buffer[3] = in[i * 4 + 2]; } } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { lodepng_memcpy(buffer, in, numpixels * 4); } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 8 + 0]; buffer[1] = in[i * 8 + 2]; buffer[2] = in[i * 8 + 4]; buffer[3] = in[i * 8 + 6]; } } } } /*Similar to getPixelColorsRGBA8, but with 3-channel RGB output.*/ static void getPixelColorsRGB8(unsigned char* LODEPNG_RESTRICT buffer, size_t numpixels, const unsigned char* LODEPNG_RESTRICT in, const LodePNGColorMode* mode) { const unsigned num_channels = 3; size_t i; if(mode->colortype == LCT_GREY) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i]; } } else if(mode->bitdepth == 16) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2]; } } else { unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ size_t j = 0; for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; } } } else if(mode->colortype == LCT_RGB) { if(mode->bitdepth == 8) { lodepng_memcpy(buffer, in, numpixels * 3); } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 6 + 0]; buffer[1] = in[i * 6 + 2]; buffer[2] = in[i * 6 + 4]; } } } else if(mode->colortype == LCT_PALETTE) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned index = in[i]; /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ lodepng_memcpy(buffer, &mode->palette[index * 4], 3); } } else { size_t j = 0; for(i = 0; i != numpixels; ++i, buffer += num_channels) { unsigned index = readBitsFromReversedStream(&j, in, mode->bitdepth); /*out of bounds of palette not checked: see lodepng_color_mode_alloc_palette.*/ lodepng_memcpy(buffer, &mode->palette[index * 4], 3); } } } else if(mode->colortype == LCT_GREY_ALPHA) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; } } } else if(mode->colortype == LCT_RGBA) { if(mode->bitdepth == 8) { for(i = 0; i != numpixels; ++i, buffer += num_channels) { lodepng_memcpy(buffer, &in[i * 4], 3); } } else { for(i = 0; i != numpixels; ++i, buffer += num_channels) { buffer[0] = in[i * 8 + 0]; buffer[1] = in[i * 8 + 2]; buffer[2] = in[i * 8 + 4]; } } } } /*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with given color type, but the given color type must be 16-bit itself.*/ static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, const unsigned char* in, size_t i, const LodePNGColorMode* mode) { if(mode->colortype == LCT_GREY) { *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; else *a = 65535; } else if(mode->colortype == LCT_RGB) { *r = 256u * in[i * 6 + 0] + in[i * 6 + 1]; *g = 256u * in[i * 6 + 2] + in[i * 6 + 3]; *b = 256u * in[i * 6 + 4] + in[i * 6 + 5]; if(mode->key_defined && 256u * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256u * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256u * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; else *a = 65535; } else if(mode->colortype == LCT_GREY_ALPHA) { *r = *g = *b = 256u * in[i * 4 + 0] + in[i * 4 + 1]; *a = 256u * in[i * 4 + 2] + in[i * 4 + 3]; } else if(mode->colortype == LCT_RGBA) { *r = 256u * in[i * 8 + 0] + in[i * 8 + 1]; *g = 256u * in[i * 8 + 2] + in[i * 8 + 3]; *b = 256u * in[i * 8 + 4] + in[i * 8 + 5]; *a = 256u * in[i * 8 + 6] + in[i * 8 + 7]; } } unsigned lodepng_convert(unsigned char* out, const unsigned char* in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h) { size_t i; ColorTree tree; size_t numpixels = (size_t)w * (size_t)h; unsigned error = 0; if(mode_in->colortype == LCT_PALETTE && !mode_in->palette) { return 107; /* error: must provide palette if input mode is palette */ } if(lodepng_color_mode_equal(mode_out, mode_in)) { size_t numbytes = lodepng_get_raw_size(w, h, mode_in); lodepng_memcpy(out, in, numbytes); return 0; } if(mode_out->colortype == LCT_PALETTE) { size_t palettesize = mode_out->palettesize; const unsigned char* palette = mode_out->palette; size_t palsize = (size_t)1u << mode_out->bitdepth; /*if the user specified output palette but did not give the values, assume they want the values of the input color type (assuming that one is palette). Note that we never create a new palette ourselves.*/ if(palettesize == 0) { palettesize = mode_in->palettesize; palette = mode_in->palette; /*if the input was also palette with same bitdepth, then the color types are also equal, so copy literally. This to preserve the exact indices that were in the PNG even in case there are duplicate colors in the palette.*/ if(mode_in->colortype == LCT_PALETTE && mode_in->bitdepth == mode_out->bitdepth) { size_t numbytes = lodepng_get_raw_size(w, h, mode_in); lodepng_memcpy(out, in, numbytes); return 0; } } if(palettesize < palsize) palsize = palettesize; color_tree_init(&tree); for(i = 0; i != palsize; ++i) { const unsigned char* p = &palette[i * 4]; error = color_tree_add(&tree, p[0], p[1], p[2], p[3], (unsigned)i); if(error) break; } } if(!error) { if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) { for(i = 0; i != numpixels; ++i) { unsigned short r = 0, g = 0, b = 0, a = 0; getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); rgba16ToPixel(out, i, mode_out, r, g, b, a); } } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) { getPixelColorsRGBA8(out, numpixels, in, mode_in); } else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) { getPixelColorsRGB8(out, numpixels, in, mode_in); } else { unsigned char r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); error = rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); if(error) break; } } } if(mode_out->colortype == LCT_PALETTE) { color_tree_cleanup(&tree); } return error; } /* Converts a single rgb color without alpha from one type to another, color bits truncated to their bitdepth. In case of single channel (gray or palette), only the r channel is used. Slow function, do not use to process all pixels of an image. Alpha channel not supported on purpose: this is for bKGD, supporting alpha may prevent it from finding a color in the palette, from the specification it looks like bKGD should ignore the alpha values of the palette since it can use any palette index but doesn't have an alpha channel. Idem with ignoring color key. */ unsigned lodepng_convert_rgb( unsigned* r_out, unsigned* g_out, unsigned* b_out, unsigned r_in, unsigned g_in, unsigned b_in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in) { unsigned r = 0, g = 0, b = 0; unsigned mul = 65535 / ((1u << mode_in->bitdepth) - 1u); /*65535, 21845, 4369, 257, 1*/ unsigned shift = 16 - mode_out->bitdepth; if(mode_in->colortype == LCT_GREY || mode_in->colortype == LCT_GREY_ALPHA) { r = g = b = r_in * mul; } else if(mode_in->colortype == LCT_RGB || mode_in->colortype == LCT_RGBA) { r = r_in * mul; g = g_in * mul; b = b_in * mul; } else if(mode_in->colortype == LCT_PALETTE) { if(r_in >= mode_in->palettesize) return 82; r = mode_in->palette[r_in * 4 + 0] * 257u; g = mode_in->palette[r_in * 4 + 1] * 257u; b = mode_in->palette[r_in * 4 + 2] * 257u; } else { return 31; } /* now convert to output format */ if(mode_out->colortype == LCT_GREY || mode_out->colortype == LCT_GREY_ALPHA) { *r_out = r >> shift ; } else if(mode_out->colortype == LCT_RGB || mode_out->colortype == LCT_RGBA) { *r_out = r >> shift ; *g_out = g >> shift ; *b_out = b >> shift ; } else if(mode_out->colortype == LCT_PALETTE) { unsigned i; /* a 16-bit color cannot be in the palette */ if((r >> 8) != (r & 255) || (g >> 8) != (g & 255) || (b >> 8) != (b & 255)) return 82; for(i = 0; i < mode_out->palettesize; i++) { unsigned j = i * 4; if((r >> 8) == mode_out->palette[j + 0] && (g >> 8) == mode_out->palette[j + 1] && (b >> 8) == mode_out->palette[j + 2]) { *r_out = i; return 0; } } return 82; } else { return 31; } return 0; } #ifdef LODEPNG_COMPILE_ENCODER void lodepng_color_stats_init(LodePNGColorStats* stats) { /*stats*/ stats->colored = 0; stats->key = 0; stats->key_r = stats->key_g = stats->key_b = 0; stats->alpha = 0; stats->numcolors = 0; stats->bits = 1; stats->numpixels = 0; /*settings*/ stats->allow_palette = 1; stats->allow_greyscale = 1; } /*function used for debug purposes with C++*/ /*void printColorStats(LodePNGColorStats* p) { std::cout << "colored: " << (int)p->colored << ", "; std::cout << "key: " << (int)p->key << ", "; std::cout << "key_r: " << (int)p->key_r << ", "; std::cout << "key_g: " << (int)p->key_g << ", "; std::cout << "key_b: " << (int)p->key_b << ", "; std::cout << "alpha: " << (int)p->alpha << ", "; std::cout << "numcolors: " << (int)p->numcolors << ", "; std::cout << "bits: " << (int)p->bits << std::endl; }*/ /*Returns how many bits needed to represent given value (max 8 bit)*/ static unsigned getValueRequiredBits(unsigned char value) { if(value == 0 || value == 255) return 1; /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; return 8; } /*stats must already have been inited. */ unsigned lodepng_compute_color_stats(LodePNGColorStats* stats, const unsigned char* in, unsigned w, unsigned h, const LodePNGColorMode* mode_in) { size_t i; ColorTree tree; size_t numpixels = (size_t)w * (size_t)h; unsigned error = 0; /* mark things as done already if it would be impossible to have a more expensive case */ unsigned colored_done = lodepng_is_greyscale_type(mode_in) ? 1 : 0; unsigned alpha_done = lodepng_can_have_alpha(mode_in) ? 0 : 1; unsigned numcolors_done = 0; unsigned bpp = lodepng_get_bpp(mode_in); unsigned bits_done = (stats->bits == 1 && bpp == 1) ? 1 : 0; unsigned sixteen = 0; /* whether the input image is 16 bit */ unsigned maxnumcolors = 257; if(bpp <= 8) maxnumcolors = LODEPNG_MIN(257, stats->numcolors + (1u << bpp)); stats->numpixels += numpixels; /*if palette not allowed, no need to compute numcolors*/ if(!stats->allow_palette) numcolors_done = 1; color_tree_init(&tree); /*If the stats was already filled in from previous data, fill its palette in tree and mark things as done already if we know they are the most expensive case already*/ if(stats->alpha) alpha_done = 1; if(stats->colored) colored_done = 1; if(stats->bits == 16) numcolors_done = 1; if(stats->bits >= bpp) bits_done = 1; if(stats->numcolors >= maxnumcolors) numcolors_done = 1; if(!numcolors_done) { for(i = 0; i < stats->numcolors; i++) { const unsigned char* color = &stats->palette[i * 4]; error = color_tree_add(&tree, color[0], color[1], color[2], color[3], i); if(error) goto cleanup; } } /*Check if the 16-bit input is truly 16-bit*/ if(mode_in->bitdepth == 16 && !sixteen) { unsigned short r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); if((r & 255) != ((r >> 8) & 255) || (g & 255) != ((g >> 8) & 255) || (b & 255) != ((b >> 8) & 255) || (a & 255) != ((a >> 8) & 255)) /*first and second byte differ*/ { stats->bits = 16; sixteen = 1; bits_done = 1; numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ break; } } } if(sixteen) { unsigned short r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); if(!colored_done && (r != g || r != b)) { stats->colored = 1; colored_done = 1; } if(!alpha_done) { unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b); if(a != 65535 && (a != 0 || (stats->key && !matchkey))) { stats->alpha = 1; stats->key = 0; alpha_done = 1; } else if(a == 0 && !stats->alpha && !stats->key) { stats->key = 1; stats->key_r = r; stats->key_g = g; stats->key_b = b; } else if(a == 65535 && stats->key && matchkey) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ stats->alpha = 1; stats->key = 0; alpha_done = 1; } } if(alpha_done && numcolors_done && colored_done && bits_done) break; } if(stats->key && !stats->alpha) { for(i = 0; i != numpixels; ++i) { getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ stats->alpha = 1; stats->key = 0; alpha_done = 1; } } } } else /* < 16-bit */ { unsigned char r = 0, g = 0, b = 0, a = 0; for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); if(!bits_done && stats->bits < 8) { /*only r is checked, < 8 bits is only relevant for grayscale*/ unsigned bits = getValueRequiredBits(r); if(bits > stats->bits) stats->bits = bits; } bits_done = (stats->bits >= bpp); if(!colored_done && (r != g || r != b)) { stats->colored = 1; colored_done = 1; if(stats->bits < 8) stats->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ } if(!alpha_done) { unsigned matchkey = (r == stats->key_r && g == stats->key_g && b == stats->key_b); if(a != 255 && (a != 0 || (stats->key && !matchkey))) { stats->alpha = 1; stats->key = 0; alpha_done = 1; if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } else if(a == 0 && !stats->alpha && !stats->key) { stats->key = 1; stats->key_r = r; stats->key_g = g; stats->key_b = b; } else if(a == 255 && stats->key && matchkey) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ stats->alpha = 1; stats->key = 0; alpha_done = 1; if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } } if(!numcolors_done) { if(!color_tree_has(&tree, r, g, b, a)) { error = color_tree_add(&tree, r, g, b, a, stats->numcolors); if(error) goto cleanup; if(stats->numcolors < 256) { unsigned char* p = stats->palette; unsigned n = stats->numcolors; p[n * 4 + 0] = r; p[n * 4 + 1] = g; p[n * 4 + 2] = b; p[n * 4 + 3] = a; } ++stats->numcolors; numcolors_done = stats->numcolors >= maxnumcolors; } } if(alpha_done && numcolors_done && colored_done && bits_done) break; } if(stats->key && !stats->alpha) { for(i = 0; i != numpixels; ++i) { getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); if(a != 0 && r == stats->key_r && g == stats->key_g && b == stats->key_b) { /* Color key cannot be used if an opaque pixel also has that RGB color. */ stats->alpha = 1; stats->key = 0; alpha_done = 1; if(stats->bits < 8) stats->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } } } /*make the stats's key always 16-bit for consistency - repeat each byte twice*/ stats->key_r += (stats->key_r << 8); stats->key_g += (stats->key_g << 8); stats->key_b += (stats->key_b << 8); } cleanup: color_tree_cleanup(&tree); return error; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*Adds a single color to the color stats. The stats must already have been inited. The color must be given as 16-bit (with 2 bytes repeating for 8-bit and 65535 for opaque alpha channel). This function is expensive, do not call it for all pixels of an image but only for a few additional values. */ static unsigned lodepng_color_stats_add(LodePNGColorStats* stats, unsigned r, unsigned g, unsigned b, unsigned a) { unsigned error = 0; unsigned char image[8]; LodePNGColorMode mode; lodepng_color_mode_init(&mode); image[0] = r >> 8; image[1] = r; image[2] = g >> 8; image[3] = g; image[4] = b >> 8; image[5] = b; image[6] = a >> 8; image[7] = a; mode.bitdepth = 16; mode.colortype = LCT_RGBA; error = lodepng_compute_color_stats(stats, image, 1, 1, &mode); lodepng_color_mode_cleanup(&mode); return error; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*Computes a minimal PNG color model that can contain all colors as indicated by the stats. The stats should be computed with lodepng_compute_color_stats. mode_in is raw color profile of the image the stats were computed on, to copy palette order from when relevant. Minimal PNG color model means the color type and bit depth that gives smallest amount of bits in the output image, e.g. gray if only grayscale pixels, palette if less than 256 colors, color key if only single transparent color, ... This is used if auto_convert is enabled (it is by default). */ static unsigned auto_choose_color(LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, const LodePNGColorStats* stats) { unsigned error = 0; unsigned palettebits; size_t i, n; size_t numpixels = stats->numpixels; unsigned palette_ok, gray_ok; unsigned alpha = stats->alpha; unsigned key = stats->key; unsigned bits = stats->bits; mode_out->key_defined = 0; if(key && numpixels <= 16) { alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ key = 0; if(bits < 8) bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ } gray_ok = !stats->colored; if(!stats->allow_greyscale) gray_ok = 0; if(!gray_ok && bits < 8) bits = 8; n = stats->numcolors; palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); palette_ok = n <= 256 && bits <= 8 && n != 0; /*n==0 means likely numcolors wasn't computed*/ if(numpixels < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ if(gray_ok && !alpha && bits <= palettebits) palette_ok = 0; /*gray is less overhead*/ if(!stats->allow_palette) palette_ok = 0; if(palette_ok) { const unsigned char* p = stats->palette; lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ for(i = 0; i != stats->numcolors; ++i) { error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); if(error) break; } mode_out->colortype = LCT_PALETTE; mode_out->bitdepth = palettebits; if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize && mode_in->bitdepth == mode_out->bitdepth) { /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ lodepng_color_mode_cleanup(mode_out); lodepng_color_mode_copy(mode_out, mode_in); } } else /*8-bit or 16-bit per channel*/ { mode_out->bitdepth = bits; mode_out->colortype = alpha ? (gray_ok ? LCT_GREY_ALPHA : LCT_RGBA) : (gray_ok ? LCT_GREY : LCT_RGB); if(key) { unsigned mask = (1u << mode_out->bitdepth) - 1u; /*stats always uses 16-bit, mask converts it*/ mode_out->key_r = stats->key_r & mask; mode_out->key_g = stats->key_g & mask; mode_out->key_b = stats->key_b & mask; mode_out->key_defined = 1; } } return error; } #endif /* #ifdef LODEPNG_COMPILE_ENCODER */ /* Paeth predictor, used by PNG filter type 4 The parameters are of type short, but should come from unsigned chars, the shorts are only needed to make the paeth calculation correct. */ static unsigned char paethPredictor(short a, short b, short c) { short pa = LODEPNG_ABS(b - c); short pb = LODEPNG_ABS(a - c); short pc = LODEPNG_ABS(a + b - c - c); /* return input value associated with smallest of pa, pb, pc (with certain priority if equal) */ if(pb < pa) { a = b; pa = pb; } return (pc < pa) ? c : a; } /*shared values used by multiple Adam7 related functions*/ static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ /* Outputs various dimensions and positions in the image related to the Adam7 reduced images. passw: output containing the width of the 7 passes passh: output containing the height of the 7 passes filter_passstart: output containing the index of the start and end of each reduced image with filter bytes padded_passstart output containing the index of the start and end of each reduced image when without filter bytes but with padded scanlines passstart: output containing the index of the start and end of each reduced image without padding between scanlines, but still padding between the images w, h: width and height of non-interlaced image bpp: bits per pixel "padded" is only relevant if bpp is less than 8 and a scanline or image does not end at a full byte */ static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) { /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ unsigned i; /*calculate width and height in pixels of each pass*/ for(i = 0; i != 7; ++i) { passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; if(passw[i] == 0) passh[i] = 0; if(passh[i] == 0) passw[i] = 0; } filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; for(i = 0; i != 7; ++i) { /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1u + (passw[i] * bpp + 7u) / 8u) : 0); /*bits padded if needed to fill full byte at end of each scanline*/ padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7u) / 8u); /*only padded at end of reduced image*/ passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7u) / 8u; } } #ifdef LODEPNG_COMPILE_DECODER /* ////////////////////////////////////////////////////////////////////////// */ /* / PNG Decoder / */ /* ////////////////////////////////////////////////////////////////////////// */ /*read the information from the header and store it in the LodePNGInfo. return value is error*/ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { unsigned width, height; LodePNGInfo* info = &state->info_png; if(insize == 0 || in == 0) { CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ } if(insize < 33) { CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ } /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ /* TODO: remove this. One should use a new LodePNGState for new sessions */ lodepng_info_cleanup(info); lodepng_info_init(info); if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) { CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ } if(lodepng_chunk_length(in + 8) != 13) { CERROR_RETURN_ERROR(state->error, 94); /*error: header size must be 13 bytes*/ } if(!lodepng_chunk_type_equals(in + 8, "IHDR")) { CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ } /*read the values given in the header*/ width = lodepng_read32bitInt(&in[16]); height = lodepng_read32bitInt(&in[20]); /*TODO: remove the undocumented feature that allows to give null pointers to width or height*/ if(w) *w = width; if(h) *h = height; info->color.bitdepth = in[24]; info->color.colortype = (LodePNGColorType)in[25]; info->compression_method = in[26]; info->filter_method = in[27]; info->interlace_method = in[28]; /*errors returned only after the parsing so other values are still output*/ /*error: invalid image size*/ if(width == 0 || height == 0) CERROR_RETURN_ERROR(state->error, 93); /*error: invalid colortype or bitdepth combination*/ state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); if(state->error) return state->error; /*error: only compression method 0 is allowed in the specification*/ if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); /*error: only filter method 0 is allowed in the specification*/ if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); /*error: only interlace methods 0 and 1 exist in the specification*/ if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); #ifndef LODEPNG_NO_COMPILE_CRC if(!state->decoder.ignore_crc) { unsigned CRC = lodepng_read32bitInt(&in[29]); unsigned checksum = lodepng_crc32(&in[12], 17); if(CRC != checksum) { CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ } } #endif return state->error; } static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, size_t bytewidth, unsigned char filterType, size_t length) { /* For PNG filter method 0 unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, the filter works byte per byte (bytewidth = 1) precon is the previous unfiltered scanline, recon the result, scanline the current one the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead recon and scanline MAY be the same memory address! precon must be disjoint. */ size_t i; switch(filterType) { case 0: for(i = 0; i != length; ++i) recon[i] = scanline[i]; break; case 1: { size_t j = 0; for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + recon[j]; break; } case 2: if(precon) { for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; } else { for(i = 0; i != length; ++i) recon[i] = scanline[i]; } break; case 3: if(precon) { size_t j = 0; for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u); /* Unroll independent paths of this predictor. A 6x and 8x version is also possible but that adds too much code. Whether this speeds up anything depends on compiler and settings. */ if(bytewidth >= 4) { for(; i + 3 < length; i += 4, j += 4) { unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3]; unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3]; unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3]; recon[i + 0] = s0 + ((r0 + p0) >> 1u); recon[i + 1] = s1 + ((r1 + p1) >> 1u); recon[i + 2] = s2 + ((r2 + p2) >> 1u); recon[i + 3] = s3 + ((r3 + p3) >> 1u); } } else if(bytewidth >= 3) { for(; i + 2 < length; i += 3, j += 3) { unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2]; unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2]; unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2]; recon[i + 0] = s0 + ((r0 + p0) >> 1u); recon[i + 1] = s1 + ((r1 + p1) >> 1u); recon[i + 2] = s2 + ((r2 + p2) >> 1u); } } else if(bytewidth >= 2) { for(; i + 1 < length; i += 2, j += 2) { unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1]; unsigned char r0 = recon[j + 0], r1 = recon[j + 1]; unsigned char p0 = precon[i + 0], p1 = precon[i + 1]; recon[i + 0] = s0 + ((r0 + p0) >> 1u); recon[i + 1] = s1 + ((r1 + p1) >> 1u); } } for(; i != length; ++i, ++j) recon[i] = scanline[i] + ((recon[j] + precon[i]) >> 1u); } else { size_t j = 0; for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; for(i = bytewidth; i != length; ++i, ++j) recon[i] = scanline[i] + (recon[j] >> 1u); } break; case 4: if(precon) { size_t j = 0; for(i = 0; i != bytewidth; ++i) { recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ } /* Unroll independent paths of the paeth predictor. A 6x and 8x version is also possible but that adds too much code. Whether this speeds up anything depends on compiler and settings. */ if(bytewidth >= 4) { for(; i + 3 < length; i += 4, j += 4) { unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3]; unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3]; unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3]; unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2], q3 = precon[j + 3]; recon[i + 0] = s0 + paethPredictor(r0, p0, q0); recon[i + 1] = s1 + paethPredictor(r1, p1, q1); recon[i + 2] = s2 + paethPredictor(r2, p2, q2); recon[i + 3] = s3 + paethPredictor(r3, p3, q3); } } else if(bytewidth >= 3) { for(; i + 2 < length; i += 3, j += 3) { unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2]; unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2]; unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2]; unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2]; recon[i + 0] = s0 + paethPredictor(r0, p0, q0); recon[i + 1] = s1 + paethPredictor(r1, p1, q1); recon[i + 2] = s2 + paethPredictor(r2, p2, q2); } } else if(bytewidth >= 2) { for(; i + 1 < length; i += 2, j += 2) { unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1]; unsigned char r0 = recon[j + 0], r1 = recon[j + 1]; unsigned char p0 = precon[i + 0], p1 = precon[i + 1]; unsigned char q0 = precon[j + 0], q1 = precon[j + 1]; recon[i + 0] = s0 + paethPredictor(r0, p0, q0); recon[i + 1] = s1 + paethPredictor(r1, p1, q1); } } for(; i != length; ++i, ++j) { recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[j])); } } else { size_t j = 0; for(i = 0; i != bytewidth; ++i) { recon[i] = scanline[i]; } for(i = bytewidth; i != length; ++i, ++j) { /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ recon[i] = (scanline[i] + recon[j]); } } break; default: return 36; /*error: invalid filter type given*/ } return 0; } static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { /* For PNG filter method 0 this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) */ unsigned y; unsigned char* prevline = 0; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ size_t bytewidth = (bpp + 7u) / 8u; /*the width of a scanline in bytes, not including the filter type*/ size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u; for(y = 0; y < h; ++y) { size_t outindex = linebytes * y; size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ unsigned char filterType = in[inindex]; CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); prevline = &out[outindex]; } return 0; } /* in: Adam7 interlaced image, with no padding bits between scanlines, but between reduced images so that each reduced image starts at a byte. out: the same pixels, but re-ordered so that they're now a non-interlaced image with size w*h bpp: bits per pixel out has the following size in bits: w * h * bpp. in is possibly bigger due to padding bits between reduced images. out must be big enough AND must be 0 everywhere if bpp < 8 in the current implementation (because that's likely a little bit faster) NOTE: comments about padding bits are only relevant if bpp < 8 */ static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned i; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); if(bpp >= 8) { for(i = 0; i != 7; ++i) { unsigned x, y, b; size_t bytewidth = bpp / 8u; for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; size_t pixeloutstart = ((ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * (size_t)w + ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bytewidth; for(b = 0; b < bytewidth; ++b) { out[pixeloutstart + b] = in[pixelinstart + b]; } } } } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { for(i = 0; i != 7; ++i) { unsigned x, y, b; unsigned ilinebits = bpp * passw[i]; unsigned olinebits = bpp * w; size_t obp, ibp; /*bit pointers (for out and in buffer)*/ for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); obp = (ADAM7_IY[i] + (size_t)y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + (size_t)x * ADAM7_DX[i]) * bpp; for(b = 0; b < bpp; ++b) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } } } } } static void removePaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h) { /* After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers for the Adam7 code, the color convert code and the output to the user. in and out are allowed to be the same buffer, in may also be higher but still overlapping; in must have >= ilinebits*h bits, out must have >= olinebits*h bits, olinebits must be <= ilinebits also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 only useful if (ilinebits - olinebits) is a value in the range 1..7 */ unsigned y; size_t diff = ilinebits - olinebits; size_t ibp = 0, obp = 0; /*input and output bit pointers*/ for(y = 0; y < h; ++y) { size_t x; for(x = 0; x < olinebits; ++x) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } ibp += diff; } } /*out must be buffer big enough to contain full image, and in must contain the full decompressed data from the IDAT chunks (with filter index bytes and possible padding bits) return value is error*/ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, unsigned w, unsigned h, const LodePNGInfo* info_png) { /* This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. Steps: *) if no Adam7: 1) unfilter 2) remove padding bits (= possible extra bits per scanline if bpp < 8) *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace NOTE: the in buffer will be overwritten with intermediate data! */ unsigned bpp = lodepng_get_bpp(&info_png->color); if(bpp == 0) return 31; /*error: invalid colortype*/ if(info_png->interlace_method == 0) { if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) { CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); removePaddingBits(out, in, w * bpp, ((w * bpp + 7u) / 8u) * 8u, h); } /*we can immediately filter into the out buffer, no other steps needed*/ else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); } else /*interlace_method is 1 (Adam7)*/ { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned i; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); for(i = 0; i != 7; ++i) { CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, move bytes instead of bits or move not at all*/ if(bpp < 8) { /*remove padding bits in scanlines; after this there still may be padding bits between the different reduced images: each reduced image still starts nicely at a byte*/ removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, ((passw[i] * bpp + 7u) / 8u) * 8u, passh[i]); } } Adam7_deinterlace(out, in, w, h, bpp); } return 0; } static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { unsigned pos = 0, i; color->palettesize = chunkLength / 3u; if(color->palettesize == 0 || color->palettesize > 256) return 38; /*error: palette too small or big*/ lodepng_color_mode_alloc_palette(color); if(!color->palette && color->palettesize) { color->palettesize = 0; return 83; /*alloc fail*/ } for(i = 0; i != color->palettesize; ++i) { color->palette[4 * i + 0] = data[pos++]; /*R*/ color->palette[4 * i + 1] = data[pos++]; /*G*/ color->palette[4 * i + 2] = data[pos++]; /*B*/ color->palette[4 * i + 3] = 255; /*alpha*/ } return 0; /* OK */ } static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { unsigned i; if(color->colortype == LCT_PALETTE) { /*error: more alpha values given than there are palette entries*/ if(chunkLength > color->palettesize) return 39; for(i = 0; i != chunkLength; ++i) color->palette[4 * i + 3] = data[i]; } else if(color->colortype == LCT_GREY) { /*error: this chunk must be 2 bytes for grayscale image*/ if(chunkLength != 2) return 30; color->key_defined = 1; color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; } else if(color->colortype == LCT_RGB) { /*error: this chunk must be 6 bytes for RGB image*/ if(chunkLength != 6) return 41; color->key_defined = 1; color->key_r = 256u * data[0] + data[1]; color->key_g = 256u * data[2] + data[3]; color->key_b = 256u * data[4] + data[5]; } else return 42; /*error: tRNS chunk not allowed for other color models*/ return 0; /* OK */ } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*background color chunk (bKGD)*/ static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(info->color.colortype == LCT_PALETTE) { /*error: this chunk must be 1 byte for indexed color image*/ if(chunkLength != 1) return 43; /*error: invalid palette index, or maybe this chunk appeared before PLTE*/ if(data[0] >= info->color.palettesize) return 103; info->background_defined = 1; info->background_r = info->background_g = info->background_b = data[0]; } else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { /*error: this chunk must be 2 bytes for grayscale image*/ if(chunkLength != 2) return 44; /*the values are truncated to bitdepth in the PNG file*/ info->background_defined = 1; info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { /*error: this chunk must be 6 bytes for grayscale image*/ if(chunkLength != 6) return 45; /*the values are truncated to bitdepth in the PNG file*/ info->background_defined = 1; info->background_r = 256u * data[0] + data[1]; info->background_g = 256u * data[2] + data[3]; info->background_b = 256u * data[4] + data[5]; } return 0; /* OK */ } /*text chunk (tEXt)*/ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { unsigned error = 0; char *key = 0, *str = 0; while(!error) /*not really a while loop, only used to break on error*/ { unsigned length, string2_begin; length = 0; while(length < chunkLength && data[length] != 0) ++length; /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ key = (char*)lodepng_malloc(length + 1); if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ lodepng_memcpy(key, data, length); key[length] = 0; string2_begin = length + 1; /*skip keyword null terminator*/ length = (unsigned)(chunkLength < string2_begin ? 0 : chunkLength - string2_begin); str = (char*)lodepng_malloc(length + 1); if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ lodepng_memcpy(str, data + string2_begin, length); str[length] = 0; error = lodepng_add_text(info, key, str); break; } lodepng_free(key); lodepng_free(str); return error; } /*compressed text chunk (zTXt)*/ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecoderSettings* decoder, const unsigned char* data, size_t chunkLength) { unsigned error = 0; /*copy the object to change parameters in it*/ LodePNGDecompressSettings zlibsettings = decoder->zlibsettings; unsigned length, string2_begin; char *key = 0; unsigned char* str = 0; size_t size = 0; while(!error) /*not really a while loop, only used to break on error*/ { for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ key = (char*)lodepng_malloc(length + 1); if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ lodepng_memcpy(key, data, length); key[length] = 0; if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ string2_begin = length + 2; if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ length = (unsigned)chunkLength - string2_begin; zlibsettings.max_output_size = decoder->max_text_size; /*will fail if zlib error, e.g. if length is too small*/ error = zlib_decompress(&str, &size, 0, &data[string2_begin], length, &zlibsettings); /*error: compressed text larger than decoder->max_text_size*/ if(error && size > zlibsettings.max_output_size) error = 112; if(error) break; error = lodepng_add_text_sized(info, key, (char*)str, size); break; } lodepng_free(key); lodepng_free(str); return error; } /*international text chunk (iTXt)*/ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecoderSettings* decoder, const unsigned char* data, size_t chunkLength) { unsigned error = 0; unsigned i; /*copy the object to change parameters in it*/ LodePNGDecompressSettings zlibsettings = decoder->zlibsettings; unsigned length, begin, compressed; char *key = 0, *langtag = 0, *transkey = 0; while(!error) /*not really a while loop, only used to break on error*/ { /*Quick check if the chunk length isn't too small. Even without check it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ /*read the key*/ for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ key = (char*)lodepng_malloc(length + 1); if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ lodepng_memcpy(key, data, length); key[length] = 0; /*read the compression method*/ compressed = data[length + 1]; if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty for the next 3 texts*/ /*read the langtag*/ begin = length + 3; length = 0; for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; langtag = (char*)lodepng_malloc(length + 1); if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ lodepng_memcpy(langtag, data + begin, length); langtag[length] = 0; /*read the transkey*/ begin += length + 1; length = 0; for(i = begin; i < chunkLength && data[i] != 0; ++i) ++length; transkey = (char*)lodepng_malloc(length + 1); if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ lodepng_memcpy(transkey, data + begin, length); transkey[length] = 0; /*read the actual text*/ begin += length + 1; length = (unsigned)chunkLength < begin ? 0 : (unsigned)chunkLength - begin; if(compressed) { unsigned char* str = 0; size_t size = 0; zlibsettings.max_output_size = decoder->max_text_size; /*will fail if zlib error, e.g. if length is too small*/ error = zlib_decompress(&str, &size, 0, &data[begin], length, &zlibsettings); /*error: compressed text larger than decoder->max_text_size*/ if(error && size > zlibsettings.max_output_size) error = 112; if(!error) error = lodepng_add_itext_sized(info, key, langtag, transkey, (char*)str, size); lodepng_free(str); } else { error = lodepng_add_itext_sized(info, key, langtag, transkey, (const char*)(data + begin), length); } break; } lodepng_free(key); lodepng_free(langtag); lodepng_free(transkey); return error; } static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ info->time_defined = 1; info->time.year = 256u * data[0] + data[1]; info->time.month = data[2]; info->time.day = data[3]; info->time.hour = data[4]; info->time.minute = data[5]; info->time.second = data[6]; return 0; /* OK */ } static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ info->phys_defined = 1; info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; info->phys_unit = data[8]; return 0; /* OK */ } static unsigned readChunk_gAMA(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 4) return 96; /*invalid gAMA chunk size*/ info->gama_defined = 1; info->gama_gamma = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; return 0; /* OK */ } static unsigned readChunk_cHRM(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 32) return 97; /*invalid cHRM chunk size*/ info->chrm_defined = 1; info->chrm_white_x = 16777216u * data[ 0] + 65536u * data[ 1] + 256u * data[ 2] + data[ 3]; info->chrm_white_y = 16777216u * data[ 4] + 65536u * data[ 5] + 256u * data[ 6] + data[ 7]; info->chrm_red_x = 16777216u * data[ 8] + 65536u * data[ 9] + 256u * data[10] + data[11]; info->chrm_red_y = 16777216u * data[12] + 65536u * data[13] + 256u * data[14] + data[15]; info->chrm_green_x = 16777216u * data[16] + 65536u * data[17] + 256u * data[18] + data[19]; info->chrm_green_y = 16777216u * data[20] + 65536u * data[21] + 256u * data[22] + data[23]; info->chrm_blue_x = 16777216u * data[24] + 65536u * data[25] + 256u * data[26] + data[27]; info->chrm_blue_y = 16777216u * data[28] + 65536u * data[29] + 256u * data[30] + data[31]; return 0; /* OK */ } static unsigned readChunk_sRGB(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { if(chunkLength != 1) return 98; /*invalid sRGB chunk size (this one is never ignored)*/ info->srgb_defined = 1; info->srgb_intent = data[0]; return 0; /* OK */ } static unsigned readChunk_iCCP(LodePNGInfo* info, const LodePNGDecoderSettings* decoder, const unsigned char* data, size_t chunkLength) { unsigned error = 0; unsigned i; size_t size = 0; /*copy the object to change parameters in it*/ LodePNGDecompressSettings zlibsettings = decoder->zlibsettings; unsigned length, string2_begin; info->iccp_defined = 1; if(info->iccp_name) lodepng_clear_icc(info); for(length = 0; length < chunkLength && data[length] != 0; ++length) ; if(length + 2 >= chunkLength) return 75; /*no null termination, corrupt?*/ if(length < 1 || length > 79) return 89; /*keyword too short or long*/ info->iccp_name = (char*)lodepng_malloc(length + 1); if(!info->iccp_name) return 83; /*alloc fail*/ info->iccp_name[length] = 0; for(i = 0; i != length; ++i) info->iccp_name[i] = (char)data[i]; if(data[length + 1] != 0) return 72; /*the 0 byte indicating compression must be 0*/ string2_begin = length + 2; if(string2_begin > chunkLength) return 75; /*no null termination, corrupt?*/ length = (unsigned)chunkLength - string2_begin; zlibsettings.max_output_size = decoder->max_icc_size; error = zlib_decompress(&info->iccp_profile, &size, 0, &data[string2_begin], length, &zlibsettings); /*error: ICC profile larger than decoder->max_icc_size*/ if(error && size > zlibsettings.max_output_size) error = 113; info->iccp_profile_size = size; if(!error && !info->iccp_profile_size) error = 100; /*invalid ICC profile size*/ return error; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, const unsigned char* in, size_t insize) { const unsigned char* chunk = in + pos; unsigned chunkLength; const unsigned char* data; unsigned unhandled = 0; unsigned error = 0; if(pos + 4 > insize) return 30; chunkLength = lodepng_chunk_length(chunk); if(chunkLength > 2147483647) return 63; data = lodepng_chunk_data_const(chunk); if(data + chunkLength + 4 > in + insize) return 30; if(lodepng_chunk_type_equals(chunk, "PLTE")) { error = readChunk_PLTE(&state->info_png.color, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "tRNS")) { error = readChunk_tRNS(&state->info_png.color, data, chunkLength); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS } else if(lodepng_chunk_type_equals(chunk, "bKGD")) { error = readChunk_bKGD(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "tEXt")) { error = readChunk_tEXt(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "zTXt")) { error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "iTXt")) { error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "tIME")) { error = readChunk_tIME(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { error = readChunk_pHYs(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "gAMA")) { error = readChunk_gAMA(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "cHRM")) { error = readChunk_cHRM(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "sRGB")) { error = readChunk_sRGB(&state->info_png, data, chunkLength); } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } else { /* unhandled chunk is ok (is not an error) */ unhandled = 1; } if(!error && !unhandled && !state->decoder.ignore_crc) { #ifndef LODEPNG_NO_COMPILE_CRC if(lodepng_chunk_check_crc(chunk)) return 57; /*invalid CRC*/ #endif } return error; } /*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { unsigned char IEND = 0; const unsigned char* chunk; unsigned char* idat; /*the data from idat chunks, zlib compressed*/ size_t idatsize = 0; unsigned char* scanlines = 0; size_t scanlines_size = 0, expected_size = 0; size_t outsize = 0; /*for unknown chunk order*/ unsigned unknown = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /* safe output values in case error happens */ *out = 0; *w = *h = 0; state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ if(state->error) return; if(lodepng_pixel_overflow(*w, *h, &state->info_png.color, &state->info_raw)) { CERROR_RETURN(state->error, 92); /*overflow possible due to amount of pixels*/ } /*the input filesize is a safe upper bound for the sum of idat chunks size*/ idat = (unsigned char*)lodepng_malloc(insize); if(!idat) CERROR_RETURN(state->error, 83); /*alloc fail*/ chunk = &in[33]; /*first byte of the first chunk after the header*/ /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer*/ while(!IEND && !state->error) { unsigned chunkLength; const unsigned char* data; /*the data in the chunk*/ /*error: size of the in buffer too small to contain next chunk*/ if((size_t)((chunk - in) + 12) > insize || chunk < in) { if(state->decoder.ignore_end) break; /*other errors may still happen though*/ CERROR_BREAK(state->error, 30); } /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ chunkLength = lodepng_chunk_length(chunk); /*error: chunk length larger than the max PNG chunk size*/ if(chunkLength > 2147483647) { if(state->decoder.ignore_end) break; /*other errors may still happen though*/ CERROR_BREAK(state->error, 63); } if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) { CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ } data = lodepng_chunk_data_const(chunk); unknown = 0; /*IDAT chunk, containing compressed image data*/ if(lodepng_chunk_type_equals(chunk, "IDAT")) { size_t newsize; if(lodepng_addofl(idatsize, chunkLength, &newsize)) CERROR_BREAK(state->error, 95); if(newsize > insize) CERROR_BREAK(state->error, 95); lodepng_memcpy(idat + idatsize, data, chunkLength); idatsize += chunkLength; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS critical_pos = 3; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } else if(lodepng_chunk_type_equals(chunk, "IEND")) { /*IEND chunk*/ IEND = 1; } else if(lodepng_chunk_type_equals(chunk, "PLTE")) { /*palette chunk (PLTE)*/ state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); if(state->error) break; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS critical_pos = 2; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } else if(lodepng_chunk_type_equals(chunk, "tRNS")) { /*palette transparency chunk (tRNS). Even though this one is an ancillary chunk , it is still compiled in without 'LODEPNG_COMPILE_ANCILLARY_CHUNKS' because it contains essential color information that affects the alpha channel of pixels. */ state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); if(state->error) break; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*background color chunk (bKGD)*/ } else if(lodepng_chunk_type_equals(chunk, "bKGD")) { state->error = readChunk_bKGD(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "tEXt")) { /*text chunk (tEXt)*/ if(state->decoder.read_text_chunks) { state->error = readChunk_tEXt(&state->info_png, data, chunkLength); if(state->error) break; } } else if(lodepng_chunk_type_equals(chunk, "zTXt")) { /*compressed text chunk (zTXt)*/ if(state->decoder.read_text_chunks) { state->error = readChunk_zTXt(&state->info_png, &state->decoder, data, chunkLength); if(state->error) break; } } else if(lodepng_chunk_type_equals(chunk, "iTXt")) { /*international text chunk (iTXt)*/ if(state->decoder.read_text_chunks) { state->error = readChunk_iTXt(&state->info_png, &state->decoder, data, chunkLength); if(state->error) break; } } else if(lodepng_chunk_type_equals(chunk, "tIME")) { state->error = readChunk_tIME(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "pHYs")) { state->error = readChunk_pHYs(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "gAMA")) { state->error = readChunk_gAMA(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "cHRM")) { state->error = readChunk_cHRM(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "sRGB")) { state->error = readChunk_sRGB(&state->info_png, data, chunkLength); if(state->error) break; } else if(lodepng_chunk_type_equals(chunk, "iCCP")) { state->error = readChunk_iCCP(&state->info_png, &state->decoder, data, chunkLength); if(state->error) break; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } else /*it's not an implemented chunk type, so ignore it: skip over the data*/ { /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ if(!state->decoder.ignore_critical && !lodepng_chunk_ancillary(chunk)) { CERROR_BREAK(state->error, 69); } unknown = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(state->decoder.remember_unknown_chunks) { state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); if(state->error) break; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ { #ifndef LODEPNG_NO_COMPILE_CRC if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ #endif } if(!IEND) chunk = lodepng_chunk_next_const(chunk, in + insize); } if(!state->error && state->info_png.color.colortype == LCT_PALETTE && !state->info_png.color.palette) { state->error = 106; /* error: PNG file must have PLTE chunk if color type is palette */ } if(!state->error) { /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. If the decompressed size does not match the prediction, the image must be corrupt.*/ if(state->info_png.interlace_method == 0) { size_t bpp = lodepng_get_bpp(&state->info_png.color); expected_size = lodepng_get_raw_size_idat(*w, *h, bpp); } else { size_t bpp = lodepng_get_bpp(&state->info_png.color); /*Adam-7 interlaced: expected size is the sum of the 7 sub-images sizes*/ expected_size = 0; expected_size += lodepng_get_raw_size_idat((*w + 7) >> 3, (*h + 7) >> 3, bpp); if(*w > 4) expected_size += lodepng_get_raw_size_idat((*w + 3) >> 3, (*h + 7) >> 3, bpp); expected_size += lodepng_get_raw_size_idat((*w + 3) >> 2, (*h + 3) >> 3, bpp); if(*w > 2) expected_size += lodepng_get_raw_size_idat((*w + 1) >> 2, (*h + 3) >> 2, bpp); expected_size += lodepng_get_raw_size_idat((*w + 1) >> 1, (*h + 1) >> 2, bpp); if(*w > 1) expected_size += lodepng_get_raw_size_idat((*w + 0) >> 1, (*h + 1) >> 1, bpp); expected_size += lodepng_get_raw_size_idat((*w + 0), (*h + 0) >> 1, bpp); } if(expected_size > LODEPNG_IMAGE_DATA_SIZE_MAX) { state->error = 114; } } if (!state->error) { state->error = zlib_decompress(&scanlines, &scanlines_size, expected_size, idat, idatsize, &state->decoder.zlibsettings); } if(!state->error && scanlines_size != expected_size) state->error = 91; /*decompressed size doesn't match prediction*/ lodepng_free(idat); if(!state->error) { outsize = lodepng_get_raw_size(*w, *h, &state->info_png.color); if (outsize > LODEPNG_IMAGE_DATA_SIZE_MAX) { state->error = 114; } } if(!state->error) { *out = (unsigned char*)lodepng_malloc(outsize); if(!*out) state->error = 83; /*alloc fail*/ } if(!state->error) { lodepng_memset(*out, 0, outsize); state->error = postProcessScanlines(*out, scanlines, *w, *h, &state->info_png); } lodepng_free(scanlines); } unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize) { *out = 0; decodeGeneric(out, w, h, state, in, insize); if(state->error) return state->error; if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) { /*same color type, no copying or converting of data needed*/ /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype the raw image has to the end user*/ if(!state->decoder.color_convert) { state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); if(state->error) return state->error; } } else { /*color conversion needed*/ unsigned char* data = *out; size_t outsize; /*TODO: check if this works according to the statement in the documentation: "The converter can convert from grayscale input color type, to 8-bit grayscale or grayscale with alpha"*/ if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) && !(state->info_raw.bitdepth == 8)) { return 56; /*unsupported color mode conversion*/ } outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); *out = (unsigned char*)lodepng_malloc(outsize); if(!(*out)) { state->error = 83; /*alloc fail*/ } else state->error = lodepng_convert(*out, data, &state->info_raw, &state->info_png.color, *w, *h); lodepng_free(data); } return state->error; } unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize, LodePNGColorType colortype, unsigned bitdepth) { unsigned error; LodePNGState state; lodepng_state_init(&state); state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*disable reading things that this function doesn't output*/ state.decoder.read_text_chunks = 0; state.decoder.remember_unknown_chunks = 0; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ error = lodepng_decode(out, w, h, &state, in, insize); lodepng_state_cleanup(&state); return error; } unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); } unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); } #ifdef LODEPNG_COMPILE_DISK unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer = 0; size_t buffersize; unsigned error; /* safe output values in case error happens */ *out = 0; *w = *h = 0; error = lodepng_load_file(&buffer, &buffersize, filename); if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); lodepng_free(buffer); return error; } unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); } unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); } #endif /*LODEPNG_COMPILE_DISK*/ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) { settings->color_convert = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS settings->read_text_chunks = 1; settings->remember_unknown_chunks = 0; settings->max_text_size = 16777216; settings->max_icc_size = 16777216; /* 16MB is much more than enough for any reasonable ICC profile */ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ settings->ignore_crc = 0; settings->ignore_critical = 0; settings->ignore_end = 0; lodepng_decompress_settings_init(&settings->zlibsettings); } #endif /*LODEPNG_COMPILE_DECODER*/ #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) void lodepng_state_init(LodePNGState* state) { #ifdef LODEPNG_COMPILE_DECODER lodepng_decoder_settings_init(&state->decoder); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER lodepng_encoder_settings_init(&state->encoder); #endif /*LODEPNG_COMPILE_ENCODER*/ lodepng_color_mode_init(&state->info_raw); lodepng_info_init(&state->info_png); state->error = 1; } void lodepng_state_cleanup(LodePNGState* state) { lodepng_color_mode_cleanup(&state->info_raw); lodepng_info_cleanup(&state->info_png); } void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) { lodepng_state_cleanup(dest); *dest = *source; lodepng_color_mode_init(&dest->info_raw); lodepng_info_init(&dest->info_png); dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; } #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ #ifdef LODEPNG_COMPILE_ENCODER /* ////////////////////////////////////////////////////////////////////////// */ /* / PNG Encoder / */ /* ////////////////////////////////////////////////////////////////////////// */ static unsigned writeSignature(ucvector* out) { size_t pos = out->size; const unsigned char signature[] = {137, 80, 78, 71, 13, 10, 26, 10}; /*8 bytes PNG signature, aka the magic bytes*/ if(!ucvector_resize(out, out->size + 8)) return 83; /*alloc fail*/ lodepng_memcpy(out->data + pos, signature, 8); return 0; } static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) { unsigned char *chunk, *data; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 13, "IHDR")); data = chunk + 8; lodepng_set32bitInt(data + 0, w); /*width*/ lodepng_set32bitInt(data + 4, h); /*height*/ data[8] = (unsigned char)bitdepth; /*bit depth*/ data[9] = (unsigned char)colortype; /*color type*/ data[10] = 0; /*compression method*/ data[11] = 0; /*filter method*/ data[12] = interlace_method; /*interlace method*/ lodepng_chunk_generate_crc(chunk); return 0; } /* only adds the chunk if needed (there is a key or palette with alpha) */ static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) { unsigned char* chunk; size_t i, j = 8; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, info->palettesize * 3, "PLTE")); for(i = 0; i != info->palettesize; ++i) { /*add all channels except alpha channel*/ chunk[j++] = info->palette[i * 4 + 0]; chunk[j++] = info->palette[i * 4 + 1]; chunk[j++] = info->palette[i * 4 + 2]; } lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { unsigned char* chunk = 0; if(info->colortype == LCT_PALETTE) { size_t i, amount = info->palettesize; /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ for(i = info->palettesize; i != 0; --i) { if(info->palette[4 * (i - 1) + 3] != 255) break; --amount; } if(amount) { CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, amount, "tRNS")); /*add the alpha channel values from the palette*/ for(i = 0; i != amount; ++i) chunk[8 + i] = info->palette[4 * i + 3]; } } else if(info->colortype == LCT_GREY) { if(info->key_defined) { CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "tRNS")); chunk[8] = (unsigned char)(info->key_r >> 8); chunk[9] = (unsigned char)(info->key_r & 255); } } else if(info->colortype == LCT_RGB) { if(info->key_defined) { CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 6, "tRNS")); chunk[8] = (unsigned char)(info->key_r >> 8); chunk[9] = (unsigned char)(info->key_r & 255); chunk[10] = (unsigned char)(info->key_g >> 8); chunk[11] = (unsigned char)(info->key_g & 255); chunk[12] = (unsigned char)(info->key_b >> 8); chunk[13] = (unsigned char)(info->key_b & 255); } } if(chunk) lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, LodePNGCompressSettings* zlibsettings) { unsigned error = 0; unsigned char* zlib = 0; size_t zlibsize = 0; error = zlib_compress(&zlib, &zlibsize, data, datasize, zlibsettings); if(!error) { error = lodepng_chunk_createv(out, zlibsize, "IDAT", zlib); } lodepng_free(zlib); return error; } static unsigned addChunk_IEND(ucvector* out) { return lodepng_chunk_createv(out, 0, "IEND", 0); } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) { unsigned char* chunk = 0; size_t keysize = lodepng_strlen(keyword), textsize = lodepng_strlen(textstring); size_t size = keysize + 1 + textsize; if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, size, "tEXt")); lodepng_memcpy(chunk + 8, keyword, keysize); chunk[8 + keysize] = 0; /*null termination char*/ lodepng_memcpy(chunk + 9 + keysize, textstring, textsize); lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, LodePNGCompressSettings* zlibsettings) { unsigned error = 0; unsigned char* chunk = 0; unsigned char* compressed = 0; size_t compressedsize = 0; size_t textsize = lodepng_strlen(textstring); size_t keysize = lodepng_strlen(keyword); if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ error = zlib_compress(&compressed, &compressedsize, (const unsigned char*)textstring, textsize, zlibsettings); if(!error) { size_t size = keysize + 2 + compressedsize; error = lodepng_chunk_init(&chunk, out, size, "zTXt"); } if(!error) { lodepng_memcpy(chunk + 8, keyword, keysize); chunk[8 + keysize] = 0; /*null termination char*/ chunk[9 + keysize] = 0; /*compression method: 0*/ lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize); lodepng_chunk_generate_crc(chunk); } lodepng_free(compressed); return error; } static unsigned addChunk_iTXt(ucvector* out, unsigned compress, const char* keyword, const char* langtag, const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) { unsigned error = 0; unsigned char* chunk = 0; unsigned char* compressed = 0; size_t compressedsize = 0; size_t textsize = lodepng_strlen(textstring); size_t keysize = lodepng_strlen(keyword), langsize = lodepng_strlen(langtag), transsize = lodepng_strlen(transkey); if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ if(compress) { error = zlib_compress(&compressed, &compressedsize, (const unsigned char*)textstring, textsize, zlibsettings); } if(!error) { size_t size = keysize + 3 + langsize + 1 + transsize + 1 + (compress ? compressedsize : textsize); error = lodepng_chunk_init(&chunk, out, size, "iTXt"); } if(!error) { size_t pos = 8; lodepng_memcpy(chunk + pos, keyword, keysize); pos += keysize; chunk[pos++] = 0; /*null termination char*/ chunk[pos++] = (compress ? 1 : 0); /*compression flag*/ chunk[pos++] = 0; /*compression method: 0*/ lodepng_memcpy(chunk + pos, langtag, langsize); pos += langsize; chunk[pos++] = 0; /*null termination char*/ lodepng_memcpy(chunk + pos, transkey, transsize); pos += transsize; chunk[pos++] = 0; /*null termination char*/ if(compress) { lodepng_memcpy(chunk + pos, compressed, compressedsize); } else { lodepng_memcpy(chunk + pos, textstring, textsize); } lodepng_chunk_generate_crc(chunk); } lodepng_free(compressed); return error; } static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) { unsigned char* chunk = 0; if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) { CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 2, "bKGD")); chunk[8] = (unsigned char)(info->background_r >> 8); chunk[9] = (unsigned char)(info->background_r & 255); } else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) { CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 6, "bKGD")); chunk[8] = (unsigned char)(info->background_r >> 8); chunk[9] = (unsigned char)(info->background_r & 255); chunk[10] = (unsigned char)(info->background_g >> 8); chunk[11] = (unsigned char)(info->background_g & 255); chunk[12] = (unsigned char)(info->background_b >> 8); chunk[13] = (unsigned char)(info->background_b & 255); } else if(info->color.colortype == LCT_PALETTE) { CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 1, "bKGD")); chunk[8] = (unsigned char)(info->background_r & 255); /*palette index*/ } if(chunk) lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) { unsigned char* chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 7, "tIME")); chunk[8] = (unsigned char)(time->year >> 8); chunk[9] = (unsigned char)(time->year & 255); chunk[10] = (unsigned char)time->month; chunk[11] = (unsigned char)time->day; chunk[12] = (unsigned char)time->hour; chunk[13] = (unsigned char)time->minute; chunk[14] = (unsigned char)time->second; lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) { unsigned char* chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 9, "pHYs")); lodepng_set32bitInt(chunk + 8, info->phys_x); lodepng_set32bitInt(chunk + 12, info->phys_y); chunk[16] = info->phys_unit; lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_gAMA(ucvector* out, const LodePNGInfo* info) { unsigned char* chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 4, "gAMA")); lodepng_set32bitInt(chunk + 8, info->gama_gamma); lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_cHRM(ucvector* out, const LodePNGInfo* info) { unsigned char* chunk; CERROR_TRY_RETURN(lodepng_chunk_init(&chunk, out, 32, "cHRM")); lodepng_set32bitInt(chunk + 8, info->chrm_white_x); lodepng_set32bitInt(chunk + 12, info->chrm_white_y); lodepng_set32bitInt(chunk + 16, info->chrm_red_x); lodepng_set32bitInt(chunk + 20, info->chrm_red_y); lodepng_set32bitInt(chunk + 24, info->chrm_green_x); lodepng_set32bitInt(chunk + 28, info->chrm_green_y); lodepng_set32bitInt(chunk + 32, info->chrm_blue_x); lodepng_set32bitInt(chunk + 36, info->chrm_blue_y); lodepng_chunk_generate_crc(chunk); return 0; } static unsigned addChunk_sRGB(ucvector* out, const LodePNGInfo* info) { unsigned char data = info->srgb_intent; return lodepng_chunk_createv(out, 1, "sRGB", &data); } static unsigned addChunk_iCCP(ucvector* out, const LodePNGInfo* info, LodePNGCompressSettings* zlibsettings) { unsigned error = 0; unsigned char* chunk = 0; unsigned char* compressed = 0; size_t compressedsize = 0; size_t keysize = lodepng_strlen(info->iccp_name); if(keysize < 1 || keysize > 79) return 89; /*error: invalid keyword size*/ error = zlib_compress(&compressed, &compressedsize, info->iccp_profile, info->iccp_profile_size, zlibsettings); if(!error) { size_t size = keysize + 2 + compressedsize; error = lodepng_chunk_init(&chunk, out, size, "iCCP"); } if(!error) { lodepng_memcpy(chunk + 8, info->iccp_name, keysize); chunk[8 + keysize] = 0; /*null termination char*/ chunk[9 + keysize] = 0; /*compression method: 0*/ lodepng_memcpy(chunk + 10 + keysize, compressed, compressedsize); lodepng_chunk_generate_crc(chunk); } lodepng_free(compressed); return error; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, size_t length, size_t bytewidth, unsigned char filterType) { size_t i; switch(filterType) { case 0: /*None*/ for(i = 0; i != length; ++i) out[i] = scanline[i]; break; case 1: /*Sub*/ for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; break; case 2: /*Up*/ if(prevline) { for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; } else { for(i = 0; i != length; ++i) out[i] = scanline[i]; } break; case 3: /*Average*/ if(prevline) { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); } else { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); } break; case 4: /*Paeth*/ if(prevline) { /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); for(i = bytewidth; i < length; ++i) { out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); } } else { for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); } break; default: return; /*invalid filter type given*/ } } /* integer binary logarithm, max return value is 31 */ static size_t ilog2(size_t i) { size_t result = 0; if(i >= 65536) { result += 16; i >>= 16; } if(i >= 256) { result += 8; i >>= 8; } if(i >= 16) { result += 4; i >>= 4; } if(i >= 4) { result += 2; i >>= 2; } if(i >= 2) { result += 1; /*i >>= 1;*/ } return result; } /* integer approximation for i * log2(i), helper function for LFS_ENTROPY */ static size_t ilog2i(size_t i) { size_t l; if(i == 0) return 0; l = ilog2(i); /* approximate i*log2(i): l is integer logarithm, ((i - (1u << l)) << 1u) linearly approximates the missing fractional part multiplied by i */ return i * l + ((i - (1u << l)) << 1u); } static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, const LodePNGColorMode* color, const LodePNGEncoderSettings* settings) { /* For PNG filter method 0 out must be a buffer with as size: h + (w * h * bpp + 7u) / 8u, because there are the scanlines with 1 extra byte per scanline */ unsigned bpp = lodepng_get_bpp(color); /*the width of a scanline in bytes, not including the filter type*/ size_t linebytes = lodepng_get_raw_size_idat(w, 1, bpp) - 1u; /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ size_t bytewidth = (bpp + 7u) / 8u; const unsigned char* prevline = 0; unsigned x, y; unsigned error = 0; LodePNGFilterStrategy strategy = settings->filter_strategy; /* There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard: * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None). * (The other case) If the image type is Grayscale or RGB (with or without Alpha), and the bit depth is not smaller than 8, then use adaptive filtering heuristic as follows: independently for each row, apply all five filters and select the filter that produces the smallest sum of absolute values per row. This heuristic is used if filter strategy is LFS_MINSUM and filter_palette_zero is true. If filter_palette_zero is true and filter_strategy is not LFS_MINSUM, the above heuristic is followed, but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum heuristic is used. */ if(settings->filter_palette_zero && (color->colortype == LCT_PALETTE || color->bitdepth < 8)) strategy = LFS_ZERO; if(bpp == 0) return 31; /*error: invalid color type*/ if(strategy >= LFS_ZERO && strategy <= LFS_FOUR) { unsigned char type = (unsigned char)strategy; for(y = 0; y != h; ++y) { size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ size_t inindex = linebytes * y; out[outindex] = type; /*filter type byte*/ filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); prevline = &in[inindex]; } } else if(strategy == LFS_MINSUM) { /*adaptive filtering*/ unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; unsigned char type, bestType = 0; for(type = 0; type != 5; ++type) { attempt[type] = (unsigned char*)lodepng_malloc(linebytes); if(!attempt[type]) error = 83; /*alloc fail*/ } if(!error) { for(y = 0; y != h; ++y) { /*try the 5 filter types*/ for(type = 0; type != 5; ++type) { size_t sum = 0; filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); /*calculate the sum of the result*/ if(type == 0) { for(x = 0; x != linebytes; ++x) sum += (unsigned char)(attempt[type][x]); } else { for(x = 0; x != linebytes; ++x) { /*For differences, each byte should be treated as signed, values above 127 are negative (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. This means filtertype 0 is almost never chosen, but that is justified.*/ unsigned char s = attempt[type][x]; sum += s < 128 ? s : (255U - s); } } /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || sum < smallest) { bestType = type; smallest = sum; } } prevline = &in[y * linebytes]; /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } } for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else if(strategy == LFS_ENTROPY) { unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t bestSum = 0; unsigned type, bestType = 0; unsigned count[256]; for(type = 0; type != 5; ++type) { attempt[type] = (unsigned char*)lodepng_malloc(linebytes); if(!attempt[type]) error = 83; /*alloc fail*/ } if(!error) { for(y = 0; y != h; ++y) { /*try the 5 filter types*/ for(type = 0; type != 5; ++type) { size_t sum = 0; filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); lodepng_memset(count, 0, 256 * sizeof(*count)); for(x = 0; x != linebytes; ++x) ++count[attempt[type][x]]; ++count[type]; /*the filter type itself is part of the scanline*/ for(x = 0; x != 256; ++x) { sum += ilog2i(count[x]); } /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || sum > bestSum) { bestType = type; bestSum = sum; } } prevline = &in[y * linebytes]; /*now fill the out values*/ out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } } for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else if(strategy == LFS_PREDEFINED) { for(y = 0; y != h; ++y) { size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ size_t inindex = linebytes * y; unsigned char type = settings->predefined_filters[y]; out[outindex] = type; /*filter type byte*/ filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); prevline = &in[inindex]; } } else if(strategy == LFS_BRUTE_FORCE) { /*brute force filter chooser. deflate the scanline after every filter attempt to see which one deflates best. This is very slow and gives only slightly smaller, sometimes even larger, result*/ size_t size[5]; unsigned char* attempt[5]; /*five filtering attempts, one for each filter type*/ size_t smallest = 0; unsigned type = 0, bestType = 0; unsigned char* dummy; LodePNGCompressSettings zlibsettings; lodepng_memcpy(&zlibsettings, &settings->zlibsettings, sizeof(LodePNGCompressSettings)); /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, to simulate the true case where the tree is the same for the whole image. Sometimes it gives better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare cases better compression. It does make this a bit less slow, so it's worth doing this.*/ zlibsettings.btype = 1; /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG images only, so disable it*/ zlibsettings.custom_zlib = 0; zlibsettings.custom_deflate = 0; for(type = 0; type != 5; ++type) { attempt[type] = (unsigned char*)lodepng_malloc(linebytes); if(!attempt[type]) error = 83; /*alloc fail*/ } if(!error) { for(y = 0; y != h; ++y) /*try the 5 filter types*/ { for(type = 0; type != 5; ++type) { unsigned testsize = (unsigned)linebytes; /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ filterScanline(attempt[type], &in[y * linebytes], prevline, linebytes, bytewidth, type); size[type] = 0; dummy = 0; zlib_compress(&dummy, &size[type], attempt[type], testsize, &zlibsettings); lodepng_free(dummy); /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ if(type == 0 || size[type] < smallest) { bestType = type; smallest = size[type]; } } prevline = &in[y * linebytes]; out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ for(x = 0; x != linebytes; ++x) out[y * (linebytes + 1) + 1 + x] = attempt[bestType][x]; } } for(type = 0; type != 5; ++type) lodepng_free(attempt[type]); } else return 88; /* unknown filter strategy */ return error; } static void addPaddingBits(unsigned char* out, const unsigned char* in, size_t olinebits, size_t ilinebits, unsigned h) { /*The opposite of the removePaddingBits function olinebits must be >= ilinebits*/ unsigned y; size_t diff = olinebits - ilinebits; size_t obp = 0, ibp = 0; /*bit pointers*/ for(y = 0; y != h; ++y) { size_t x; for(x = 0; x < ilinebits; ++x) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/ for(x = 0; x != diff; ++x) setBitOfReversedStream(&obp, out, 0); } } /* in: non-interlaced image with size w*h out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with no padding bits between scanlines, but between reduced images so that each reduced image starts at a byte. bpp: bits per pixel there are no padding bits, not between scanlines, not between reduced images in has the following size in bits: w * h * bpp. out is possibly bigger due to padding bits between reduced images NOTE: comments about padding bits are only relevant if bpp < 8 */ static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned i; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); if(bpp >= 8) { for(i = 0; i != 7; ++i) { unsigned x, y, b; size_t bytewidth = bpp / 8u; for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; for(b = 0; b < bytewidth; ++b) { out[pixeloutstart + b] = in[pixelinstart + b]; } } } } else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ { for(i = 0; i != 7; ++i) { unsigned x, y, b; unsigned ilinebits = bpp * passw[i]; unsigned olinebits = bpp * w; size_t obp, ibp; /*bit pointers (for out and in buffer)*/ for(y = 0; y < passh[i]; ++y) for(x = 0; x < passw[i]; ++x) { ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); for(b = 0; b < bpp; ++b) { unsigned char bit = readBitFromReversedStream(&ibp, in); setBitOfReversedStream(&obp, out, bit); } } } } } /*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. return value is error**/ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, unsigned w, unsigned h, const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) { /* This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: *) if no Adam7: 1) add padding bits (= possible extra bits per scanline if bpp < 8) 2) filter *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter */ unsigned bpp = lodepng_get_bpp(&info_png->color); unsigned error = 0; if(info_png->interlace_method == 0) { *outsize = h + (h * ((w * bpp + 7u) / 8u)); /*image size plus an extra byte per scanline + possible padding bits*/ *out = (unsigned char*)lodepng_malloc(*outsize); if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ if(!error) { /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ if(bpp < 8 && w * bpp != ((w * bpp + 7u) / 8u) * 8u) { unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7u) / 8u)); if(!padded) error = 83; /*alloc fail*/ if(!error) { addPaddingBits(padded, in, ((w * bpp + 7u) / 8u) * 8u, w * bpp, h); error = filter(*out, padded, w, h, &info_png->color, settings); } lodepng_free(padded); } else { /*we can immediately filter into the out buffer, no other steps needed*/ error = filter(*out, in, w, h, &info_png->color, settings); } } } else /*interlace_method is 1 (Adam7)*/ { unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; unsigned char* adam7; Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ *out = (unsigned char*)lodepng_malloc(*outsize); if(!(*out)) error = 83; /*alloc fail*/ adam7 = (unsigned char*)lodepng_malloc(passstart[7]); if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ if(!error) { unsigned i; Adam7_interlace(adam7, in, w, h, bpp); for(i = 0; i != 7; ++i) { if(bpp < 8) { unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); if(!padded) ERROR_BREAK(83); /*alloc fail*/ addPaddingBits(padded, &adam7[passstart[i]], ((passw[i] * bpp + 7u) / 8u) * 8u, passw[i] * bpp, passh[i]); error = filter(&(*out)[filter_passstart[i]], padded, passw[i], passh[i], &info_png->color, settings); lodepng_free(padded); } else { error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], passw[i], passh[i], &info_png->color, settings); } if(error) break; } } lodepng_free(adam7); } return error; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) { unsigned char* inchunk = data; while((size_t)(inchunk - data) < datasize) { CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); out->allocsize = out->size; /*fix the allocsize again*/ inchunk = lodepng_chunk_next(inchunk, data + datasize); } return 0; } static unsigned isGrayICCProfile(const unsigned char* profile, unsigned size) { /* It is a gray profile if bytes 16-19 are "GRAY", rgb profile if bytes 16-19 are "RGB ". We do not perform any full parsing of the ICC profile here, other than check those 4 bytes to grayscale profile. Other than that, validity of the profile is not checked. This is needed only because the PNG specification requires using a non-gray color model if there is an ICC profile with "RGB " (sadly limiting compression opportunities if the input data is grayscale RGB data), and requires using a gray color model if it is "GRAY". */ if(size < 20) return 0; return profile[16] == 'G' && profile[17] == 'R' && profile[18] == 'A' && profile[19] == 'Y'; } static unsigned isRGBICCProfile(const unsigned char* profile, unsigned size) { /* See comment in isGrayICCProfile*/ if(size < 20) return 0; return profile[16] == 'R' && profile[17] == 'G' && profile[18] == 'B' && profile[19] == ' '; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ unsigned lodepng_encode(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGState* state) { unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ size_t datasize = 0; ucvector outv = ucvector_init(NULL, 0); LodePNGInfo info; const LodePNGInfo* info_png = &state->info_png; lodepng_info_init(&info); /*provide some proper output values if error will happen*/ *out = 0; *outsize = 0; state->error = 0; /*check input values validity*/ if((info_png->color.colortype == LCT_PALETTE || state->encoder.force_palette) && (info_png->color.palettesize == 0 || info_png->color.palettesize > 256)) { state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ goto cleanup; } if(state->encoder.zlibsettings.btype > 2) { state->error = 61; /*error: invalid btype*/ goto cleanup; } if(info_png->interlace_method > 1) { state->error = 71; /*error: invalid interlace mode*/ goto cleanup; } state->error = checkColorValidity(info_png->color.colortype, info_png->color.bitdepth); if(state->error) goto cleanup; /*error: invalid color type given*/ state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); if(state->error) goto cleanup; /*error: invalid color type given*/ /* color convert and compute scanline filter types */ lodepng_info_copy(&info, &state->info_png); if(state->encoder.auto_convert) { LodePNGColorStats stats; lodepng_color_stats_init(&stats); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(info_png->iccp_defined && isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) { /*the PNG specification does not allow to use palette with a GRAY ICC profile, even if the palette has only gray colors, so disallow it.*/ stats.allow_palette = 0; } if(info_png->iccp_defined && isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size)) { /*the PNG specification does not allow to use grayscale color with RGB ICC profile, so disallow gray.*/ stats.allow_greyscale = 0; } #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ state->error = lodepng_compute_color_stats(&stats, image, w, h, &state->info_raw); if(state->error) goto cleanup; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(info_png->background_defined) { /*the background chunk's color must be taken into account as well*/ unsigned r = 0, g = 0, b = 0; LodePNGColorMode mode16 = lodepng_color_mode_make(LCT_RGB, 16); lodepng_convert_rgb(&r, &g, &b, info_png->background_r, info_png->background_g, info_png->background_b, &mode16, &info_png->color); state->error = lodepng_color_stats_add(&stats, r, g, b, 65535); if(state->error) goto cleanup; } #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ state->error = auto_choose_color(&info.color, &state->info_raw, &stats); if(state->error) goto cleanup; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*also convert the background chunk*/ if(info_png->background_defined) { if(lodepng_convert_rgb(&info.background_r, &info.background_g, &info.background_b, info_png->background_r, info_png->background_g, info_png->background_b, &info.color, &info_png->color)) { state->error = 104; goto cleanup; } } #endif /* LODEPNG_COMPILE_ANCILLARY_CHUNKS */ } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS if(info_png->iccp_defined) { unsigned gray_icc = isGrayICCProfile(info_png->iccp_profile, info_png->iccp_profile_size); unsigned rgb_icc = isRGBICCProfile(info_png->iccp_profile, info_png->iccp_profile_size); unsigned gray_png = info.color.colortype == LCT_GREY || info.color.colortype == LCT_GREY_ALPHA; if(!gray_icc && !rgb_icc) { state->error = 100; /* Disallowed profile color type for PNG */ goto cleanup; } if(gray_icc != gray_png) { /*Not allowed to use RGB/RGBA/palette with GRAY ICC profile or vice versa, or in case of auto_convert, it wasn't possible to find appropriate model*/ state->error = state->encoder.auto_convert ? 102 : 101; goto cleanup; } } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) { unsigned char* converted; size_t size = ((size_t)w * (size_t)h * (size_t)lodepng_get_bpp(&info.color) + 7u) / 8u; converted = (unsigned char*)lodepng_malloc(size); if(!converted && size) state->error = 83; /*alloc fail*/ if(!state->error) { state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); } if(!state->error) { state->error = preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); } lodepng_free(converted); if(state->error) goto cleanup; } else { state->error = preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); if(state->error) goto cleanup; } /* output all PNG chunks */ { #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS size_t i; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*write signature and chunks*/ state->error = writeSignature(&outv); if(state->error) goto cleanup; /*IHDR*/ state->error = addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); if(state->error) goto cleanup; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*unknown chunks between IHDR and PLTE*/ if(info.unknown_chunks_data[0]) { state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); if(state->error) goto cleanup; } /*color profile chunks must come before PLTE */ if(info.iccp_defined) { state->error = addChunk_iCCP(&outv, &info, &state->encoder.zlibsettings); if(state->error) goto cleanup; } if(info.srgb_defined) { state->error = addChunk_sRGB(&outv, &info); if(state->error) goto cleanup; } if(info.gama_defined) { state->error = addChunk_gAMA(&outv, &info); if(state->error) goto cleanup; } if(info.chrm_defined) { state->error = addChunk_cHRM(&outv, &info); if(state->error) goto cleanup; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*PLTE*/ if(info.color.colortype == LCT_PALETTE) { state->error = addChunk_PLTE(&outv, &info.color); if(state->error) goto cleanup; } if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) { /*force_palette means: write suggested palette for truecolor in PLTE chunk*/ state->error = addChunk_PLTE(&outv, &info.color); if(state->error) goto cleanup; } /*tRNS (this will only add if when necessary) */ state->error = addChunk_tRNS(&outv, &info.color); if(state->error) goto cleanup; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*bKGD (must come between PLTE and the IDAt chunks*/ if(info.background_defined) { state->error = addChunk_bKGD(&outv, &info); if(state->error) goto cleanup; } /*pHYs (must come before the IDAT chunks)*/ if(info.phys_defined) { state->error = addChunk_pHYs(&outv, &info); if(state->error) goto cleanup; } /*unknown chunks between PLTE and IDAT*/ if(info.unknown_chunks_data[1]) { state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); if(state->error) goto cleanup; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*IDAT (multiple IDAT chunks must be consecutive)*/ state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); if(state->error) goto cleanup; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*tIME*/ if(info.time_defined) { state->error = addChunk_tIME(&outv, &info.time); if(state->error) goto cleanup; } /*tEXt and/or zTXt*/ for(i = 0; i != info.text_num; ++i) { if(lodepng_strlen(info.text_keys[i]) > 79) { state->error = 66; /*text chunk too large*/ goto cleanup; } if(lodepng_strlen(info.text_keys[i]) < 1) { state->error = 67; /*text chunk too small*/ goto cleanup; } if(state->encoder.text_compression) { state->error = addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); if(state->error) goto cleanup; } else { state->error = addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); if(state->error) goto cleanup; } } /*LodePNG version id in text chunk*/ if(state->encoder.add_id) { unsigned already_added_id_text = 0; for(i = 0; i != info.text_num; ++i) { const char* k = info.text_keys[i]; /* Could use strcmp, but we're not calling or reimplementing this C library function for this use only */ if(k[0] == 'L' && k[1] == 'o' && k[2] == 'd' && k[3] == 'e' && k[4] == 'P' && k[5] == 'N' && k[6] == 'G' && k[7] == '\0') { already_added_id_text = 1; break; } } if(already_added_id_text == 0) { state->error = addChunk_tEXt(&outv, "LodePNG", LODEPNG_VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ if(state->error) goto cleanup; } } /*iTXt*/ for(i = 0; i != info.itext_num; ++i) { if(lodepng_strlen(info.itext_keys[i]) > 79) { state->error = 66; /*text chunk too large*/ goto cleanup; } if(lodepng_strlen(info.itext_keys[i]) < 1) { state->error = 67; /*text chunk too small*/ goto cleanup; } state->error = addChunk_iTXt( &outv, state->encoder.text_compression, info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], &state->encoder.zlibsettings); if(state->error) goto cleanup; } /*unknown chunks between IDAT and IEND*/ if(info.unknown_chunks_data[2]) { state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); if(state->error) goto cleanup; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ state->error = addChunk_IEND(&outv); if(state->error) goto cleanup; } cleanup: lodepng_info_cleanup(&info); lodepng_free(data); /*instead of cleaning the vector up, give it to the output*/ *out = outv.data; *outsize = outv.size; return state->error; } unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { unsigned error; LodePNGState state; lodepng_state_init(&state); state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; state.info_png.color.colortype = colortype; state.info_png.color.bitdepth = bitdepth; lodepng_encode(out, outsize, image, w, h, &state); error = state.error; lodepng_state_cleanup(&state); return error; } unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); } unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); } #ifdef LODEPNG_COMPILE_DISK unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer; size_t buffersize; unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); if(!error) error = lodepng_save_file(buffer, buffersize, filename); lodepng_free(buffer); return error; } unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); } unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); } #endif /*LODEPNG_COMPILE_DISK*/ void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) { lodepng_compress_settings_init(&settings->zlibsettings); settings->filter_palette_zero = 1; settings->filter_strategy = LFS_MINSUM; settings->auto_convert = 1; settings->force_palette = 0; settings->predefined_filters = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS settings->add_id = 0; settings->text_compression = 1; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ERROR_TEXT /* This returns the description of a numerical error code in English. This is also the documentation of all the error codes. */ const char* lodepng_error_text(unsigned code) { switch(code) { case 0: return "no error, everything went ok"; case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ case 13: return "problem while processing dynamic deflate block"; case 14: return "problem while processing dynamic deflate block"; case 15: return "problem while processing dynamic deflate block"; /*this error could happen if there are only 0 or 1 symbols present in the huffman code:*/ case 16: return "invalid code while processing dynamic deflate block"; case 17: return "end of out buffer memory reached while inflating"; case 18: return "invalid distance code while inflating"; case 19: return "end of out buffer memory reached while inflating"; case 20: return "invalid deflate block BTYPE encountered while decoding"; case 21: return "NLEN is not ones complement of LEN in a deflate block"; /*end of out buffer memory reached while inflating: This can happen if the inflated deflate data is longer than the amount of bytes required to fill up all the pixels of the image, given the color depth and image dimensions. Something that doesn't happen in a normal, well encoded, PNG image.*/ case 22: return "end of out buffer memory reached while inflating"; case 23: return "end of in buffer memory reached while inflating"; case 24: return "invalid FCHECK in zlib header"; case 25: return "invalid compression method in zlib header"; case 26: return "FDICT encountered in zlib header while it's not used for PNG"; case 27: return "PNG file is smaller than a PNG header"; /*Checks the magic file header, the first 8 bytes of the PNG file*/ case 28: return "incorrect PNG signature, it's no PNG or corrupted"; case 29: return "first chunk is not the header chunk"; case 30: return "chunk length too large, chunk broken off at end of file"; case 31: return "illegal PNG color type or bpp"; case 32: return "illegal PNG compression method"; case 33: return "illegal PNG filter method"; case 34: return "illegal PNG interlace method"; case 35: return "chunk length of a chunk is too large or the chunk too small"; case 36: return "illegal PNG filter type encountered"; case 37: return "illegal bit depth for this color type given"; case 38: return "the palette is too small or too big"; /*0, or more than 256 colors*/ case 39: return "tRNS chunk before PLTE or has more entries than palette size"; case 40: return "tRNS chunk has wrong size for grayscale image"; case 41: return "tRNS chunk has wrong size for RGB image"; case 42: return "tRNS chunk appeared while it was not allowed for this color type"; case 43: return "bKGD chunk has wrong size for palette image"; case 44: return "bKGD chunk has wrong size for grayscale image"; case 45: return "bKGD chunk has wrong size for RGB image"; case 48: return "empty input buffer given to decoder. Maybe caused by non-existing file?"; case 49: return "jumped past memory while generating dynamic huffman tree"; case 50: return "jumped past memory while generating dynamic huffman tree"; case 51: return "jumped past memory while inflating huffman block"; case 52: return "jumped past memory while inflating"; case 53: return "size of zlib data too small"; case 54: return "repeat symbol in tree while there was no value symbol yet"; /*jumped past tree while generating huffman tree, this could be when the tree will have more leaves than symbols after generating it out of the given lengths. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ case 55: return "jumped past tree while generating huffman tree"; case 56: return "given output image colortype or bitdepth not supported for color conversion"; case 57: return "invalid CRC encountered (checking CRC can be disabled)"; case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; case 59: return "requested color conversion not supported"; case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; /*LodePNG leaves the choice of RGB to grayscale conversion formula to the user.*/ case 62: return "conversion from color to grayscale not supported"; /*(2^31-1)*/ case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; case 71: return "invalid interlace mode given to encoder (must be 0 or 1)"; case 72: return "while decoding, invalid compression method encountering in zTXt or iTXt chunk (it must be 0)"; case 73: return "invalid tIME chunk size"; case 74: return "invalid pHYs chunk size"; /*length could be wrong, or data chopped off*/ case 75: return "no null termination char found while decoding text chunk"; case 76: return "iTXt chunk too short to contain required bytes"; case 77: return "integer overflow in buffer size"; case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ case 79: return "failed to open file for writing"; case 80: return "tried creating a tree of 0 symbols"; case 81: return "lazy matching at pos 0 is impossible"; case 82: return "color conversion to palette requested while a color isn't in palette, or index out of bounds"; case 83: return "memory allocation failed"; case 84: return "given image too small to contain all pixels to be encoded"; case 86: return "impossible offset in lz77 encoding (internal bug)"; case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; case 89: return "text chunk keyword too short or long: must have size 1-79"; /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ case 90: return "windowsize must be a power of two"; case 91: return "invalid decompressed idat size"; case 92: return "integer overflow due to too many pixels"; case 93: return "zero width or height is invalid"; case 94: return "header chunk must have a size of 13 bytes"; case 95: return "integer overflow with combined idat chunk size"; case 96: return "invalid gAMA chunk size"; case 97: return "invalid cHRM chunk size"; case 98: return "invalid sRGB chunk size"; case 99: return "invalid sRGB rendering intent"; case 100: return "invalid ICC profile color type, the PNG specification only allows RGB or GRAY"; case 101: return "PNG specification does not allow RGB ICC profile on gray color types and vice versa"; case 102: return "not allowed to set grayscale ICC profile with colored pixels by PNG specification"; case 103: return "invalid palette index in bKGD chunk. Maybe it came before PLTE chunk?"; case 104: return "invalid bKGD color while encoding (e.g. palette index out of range)"; case 105: return "integer overflow of bitsize"; case 106: return "PNG file must have PLTE chunk if color type is palette"; case 107: return "color convert from palette mode requested without setting the palette data in it"; case 108: return "tried to add more than 256 values to a palette"; /*this limit can be configured in LodePNGDecompressSettings*/ case 109: return "tried to decompress zlib or deflate data larger than desired max_output_size"; case 110: return "custom zlib or inflate decompression failed"; case 111: return "custom zlib or deflate compression failed"; /*max text size limit can be configured in LodePNGDecoderSettings. This error prevents unreasonable memory consumption when decoding due to impossibly large text sizes.*/ case 112: return "compressed text unreasonably large"; /*max ICC size limit can be configured in LodePNGDecoderSettings. This error prevents unreasonable memory consumption when decoding due to impossibly large ICC profile*/ case 113: return "ICC profile unreasonably large"; /*max size of an in-memory image buffer*/ case 114: return "image data unreasonably large"; } return "unknown error code"; } #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ /* // C++ Wrapper // */ /* ////////////////////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_CPP namespace lodepng { #ifdef LODEPNG_COMPILE_DISK unsigned load_file(std::vector& buffer, const std::string& filename) { long size = lodepng_filesize(filename.c_str()); if(size < 0) return 78; buffer.resize((size_t)size); return size == 0 ? 0 : lodepng_buffer_file(&buffer[0], (size_t)size, filename.c_str()); } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned save_file(const std::vector& buffer, const std::string& filename) { return lodepng_save_file(buffer.empty() ? 0 : &buffer[0], buffer.size(), filename.c_str()); } #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings& settings) { unsigned char* buffer = 0; size_t buffersize = 0; unsigned error = zlib_decompress(&buffer, &buffersize, 0, in, insize, &settings); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned decompress(std::vector& out, const std::vector& in, const LodePNGDecompressSettings& settings) { return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); } #endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER unsigned compress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGCompressSettings& settings) { unsigned char* buffer = 0; size_t buffersize = 0; unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned compress(std::vector& out, const std::vector& in, const LodePNGCompressSettings& settings) { return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); } #endif /* LODEPNG_COMPILE_ENCODER */ #endif /* LODEPNG_COMPILE_ZLIB */ #ifdef LODEPNG_COMPILE_PNG State::State() { lodepng_state_init(this); } State::State(const State& other) { lodepng_state_init(this); lodepng_state_copy(this, &other); } State::~State() { lodepng_state_cleanup(this); } State& State::operator=(const State& other) { lodepng_state_copy(this, &other); return *this; } #ifdef LODEPNG_COMPILE_DECODER unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, size_t insize, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer = 0; unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); if(buffer && !error) { State state; state.info_raw.colortype = colortype; state.info_raw.bitdepth = bitdepth; size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); out.insert(out.end(), &buffer[0], &buffer[buffersize]); } lodepng_free(buffer); return error; } unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) { return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); } unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const unsigned char* in, size_t insize) { unsigned char* buffer = NULL; unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); if(buffer && !error) { size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); out.insert(out.end(), &buffer[0], &buffer[buffersize]); } lodepng_free(buffer); return error; } unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const std::vector& in) { return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); } #ifdef LODEPNG_COMPILE_DISK unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, LodePNGColorType colortype, unsigned bitdepth) { std::vector buffer; /* safe output values in case error happens */ w = h = 0; unsigned error = load_file(buffer, filename); if(error) return error; return decode(out, w, h, buffer, colortype, bitdepth); } #endif /* LODEPNG_COMPILE_DECODER */ #endif /* LODEPNG_COMPILE_DISK */ #ifdef LODEPNG_COMPILE_ENCODER unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { unsigned char* buffer; size_t buffersize; unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, State& state) { unsigned char* buffer; size_t buffersize; unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); if(buffer) { out.insert(out.end(), &buffer[0], &buffer[buffersize]); lodepng_free(buffer); } return error; } unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, State& state) { if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; return encode(out, in.empty() ? 0 : &in[0], w, h, state); } #ifdef LODEPNG_COMPILE_DISK unsigned encode(const std::string& filename, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { std::vector buffer; unsigned error = encode(buffer, in, w, h, colortype, bitdepth); if(!error) error = save_file(buffer, filename); return error; } unsigned encode(const std::string& filename, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_ENCODER */ #endif /* LODEPNG_COMPILE_PNG */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ chafa-1.18.2/lodepng/lodepng.h000066400000000000000000002773051517447374300161330ustar00rootroot00000000000000/* LodePNG version 20220109 Copyright (c) 2005-2022 Lode Vandevenne This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ #ifndef LODEPNG_H #define LODEPNG_H #include /*for size_t*/ extern const char* LODEPNG_VERSION_STRING; /*Hard upper limit on size of an uncompressed in-memory image buffer. The total memory consumption may be higher, e.g. during postProcessScanlines().*/ #define LODEPNG_IMAGE_DATA_SIZE_MAX (0xffffffffU >> 2) /* The following #defines are used to create code sections. They can be disabled to disable code sections, which can give faster compile time and smaller binary. The "NO_COMPILE" defines are designed to be used to pass as defines to the compiler command to disable them without modifying this header, e.g. -DLODEPNG_NO_COMPILE_ZLIB for gcc. In addition to those below, you can also define LODEPNG_NO_COMPILE_CRC to allow implementing a custom lodepng_crc32. */ /*deflate & zlib. If disabled, you must specify alternative zlib functions in the custom_zlib field of the compress and decompress settings*/ #ifndef LODEPNG_NO_COMPILE_ZLIB #define LODEPNG_COMPILE_ZLIB #endif /*png encoder and png decoder*/ #ifndef LODEPNG_NO_COMPILE_PNG #define LODEPNG_COMPILE_PNG #endif /*deflate&zlib decoder and png decoder*/ #ifndef LODEPNG_NO_COMPILE_DECODER #define LODEPNG_COMPILE_DECODER #endif /*deflate&zlib encoder and png encoder*/ #ifndef LODEPNG_NO_COMPILE_ENCODER #define LODEPNG_COMPILE_ENCODER #endif /*the optional built in harddisk file loading and saving functions*/ #ifndef LODEPNG_NO_COMPILE_DISK #define LODEPNG_COMPILE_DISK #endif /*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/ #ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS #define LODEPNG_COMPILE_ANCILLARY_CHUNKS #endif /*ability to convert error numerical codes to English text string*/ #ifndef LODEPNG_NO_COMPILE_ERROR_TEXT #define LODEPNG_COMPILE_ERROR_TEXT #endif /*Compile the default allocators (C's free, malloc and realloc). If you disable this, you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your source files with custom allocators.*/ #ifndef LODEPNG_NO_COMPILE_ALLOCATORS #define LODEPNG_COMPILE_ALLOCATORS #endif /*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/ #ifdef __cplusplus #ifndef LODEPNG_NO_COMPILE_CPP #define LODEPNG_COMPILE_CPP #endif #endif #ifdef LODEPNG_COMPILE_CPP #include #include #endif /*LODEPNG_COMPILE_CPP*/ #ifdef LODEPNG_COMPILE_PNG /*The PNG color types (also used for raw image).*/ typedef enum LodePNGColorType { LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/ LCT_RGB = 2, /*RGB: 8,16 bit*/ LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/ LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/ /*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid byte value from 0 to 255 that could be present in an invalid PNG file header. Do not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use the valid color type names above, or numeric values like 1 or 7 when checking for particular disallowed color type byte values, or cast to integer to print it.*/ LCT_MAX_OCTET_VALUE = 255 } LodePNGColorType; #ifdef LODEPNG_COMPILE_DECODER /* Converts PNG data in memory to raw pixel data. out: Output parameter. Pointer to buffer that will contain the raw pixel data. After decoding, its size is w * h * (bytes per pixel) bytes larger than initially. Bytes per pixel depends on colortype and bitdepth. Must be freed after usage with free(*out). Note: for 16-bit per channel colors, uses big endian format like PNG does. w: Output parameter. Pointer to width of pixel data. h: Output parameter. Pointer to height of pixel data. in: Memory buffer with the PNG file. insize: size of the in buffer. colortype: the desired color type for the raw output image. See explanation on PNG color types. bitdepth: the desired bit depth for the raw output image. See explanation on PNG color types. Return value: LodePNG error code (0 means no error). */ unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize); /*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize); #ifdef LODEPNG_COMPILE_DISK /* Load PNG from disk, from file with given name. Same as the other decode functions, but instead takes a filename as input. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory.*/ unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory.*/ unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename); /*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory.*/ unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename); #endif /*LODEPNG_COMPILE_DISK*/ #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Converts raw pixel data into a PNG image in memory. The colortype and bitdepth of the output PNG image cannot be chosen, they are automatically determined by the colortype, bitdepth and content of the input pixel data. Note: for 16-bit per channel colors, needs big endian format like PNG does. out: Output parameter. Pointer to buffer that will contain the PNG image data. Must be freed after usage with free(*out). outsize: Output parameter. Pointer to the size in bytes of the out buffer. image: The raw pixel data to encode. The size of this buffer should be w * h * (bytes per pixel), bytes per pixel depends on colortype and bitdepth. w: width of the raw pixel data in pixels. h: height of the raw pixel data in pixels. colortype: the color type of the raw input image. See explanation on PNG color types. bitdepth: the bit depth of the raw input image. See explanation on PNG color types. Return value: LodePNG error code (0 means no error). */ unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h); /*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h); #ifdef LODEPNG_COMPILE_DISK /* Converts raw pixel data into a PNG file on disk. Same as the other encode functions, but instead takes a filename as output. NOTE: This overwrites existing files without warning! NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and encode in-memory.*/ unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and encode in-memory.*/ unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h); /*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and encode in-memory.*/ unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h); #endif /*LODEPNG_COMPILE_DISK*/ #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_CPP namespace lodepng { #ifdef LODEPNG_COMPILE_DECODER /*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, size_t insize, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::vector& in, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #ifdef LODEPNG_COMPILE_DISK /* Converts PNG file from disk to raw pixel data in memory. Same as the other decode functions, but instead takes a filename as input. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER /*Same as lodepng_encode_memory, but encodes to an std::vector. colortype is that of the raw input data. The output PNG color type will be auto chosen.*/ unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #ifdef LODEPNG_COMPILE_DISK /* Converts 32-bit RGBA raw pixel data into a PNG file on disk. Same as the other encode functions, but instead takes a filename as output. NOTE: This overwrites existing files without warning! NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory. */ unsigned encode(const std::string& filename, const unsigned char* in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned encode(const std::string& filename, const std::vector& in, unsigned w, unsigned h, LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_ENCODER */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ERROR_TEXT /*Returns an English description of the numerical error code.*/ const char* lodepng_error_text(unsigned code); #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ #ifdef LODEPNG_COMPILE_DECODER /*Settings for zlib decompression*/ typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; struct LodePNGDecompressSettings { /* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */ unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/ /*Maximum decompressed size, beyond this the decoder may (and is encouraged to) stop decoding, return an error, output a data size > max_output_size and all the data up to that point. This is not hard limit nor a guarantee, but can prevent excessive memory usage. This setting is ignored by the PNG decoder, but is used by the deflate/zlib decoder and can be used by custom ones. Set to 0 to impose no limit (the default).*/ size_t max_output_size; /*use custom zlib decoder instead of built in one (default: null). Should return 0 if success, any non-0 if error (numeric value not exposed).*/ unsigned (*custom_zlib)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*); /*use custom deflate decoder instead of built in one (default: null) if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate). Should return 0 if success, any non-0 if error (numeric value not exposed).*/ unsigned (*custom_inflate)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGDecompressSettings*); const void* custom_context; /*optional custom settings for custom functions*/ }; extern const LodePNGDecompressSettings lodepng_default_decompress_settings; void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Settings for zlib compression. Tweaking these settings tweaks the balance between speed and compression ratio. */ typedef struct LodePNGCompressSettings LodePNGCompressSettings; struct LodePNGCompressSettings /*deflate = compress*/ { /*LZ77 related settings*/ unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ unsigned minmatch; /*minimum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ /*use custom zlib encoder instead of built in one (default: null)*/ unsigned (*custom_zlib)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGCompressSettings*); /*use custom deflate encoder instead of built in one (default: null) if custom_zlib is used, custom_deflate is ignored since only the built in zlib function will call custom_deflate*/ unsigned (*custom_deflate)(unsigned char**, size_t*, const unsigned char*, size_t, const LodePNGCompressSettings*); const void* custom_context; /*optional custom settings for custom functions*/ }; extern const LodePNGCompressSettings lodepng_default_compress_settings; void lodepng_compress_settings_init(LodePNGCompressSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_PNG /* Color mode of an image. Contains all information required to decode the pixel bits to RGBA colors. This information is the same as used in the PNG file format, and is used both for PNG and raw image data in LodePNG. */ typedef struct LodePNGColorMode { /*header (IHDR)*/ LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ /* palette (PLTE and tRNS) Dynamically allocated with the colors of the palette, including alpha. This field may not be allocated directly, use lodepng_color_mode_init first, then lodepng_palette_add per color to correctly initialize it (to ensure size of exactly 1024 bytes). The alpha channels must be set as well, set them to 255 for opaque images. When decoding, by default you can ignore this palette, since LodePNG already fills the palette colors in the pixels of the raw RGBA output. The palette is only supported for color type 3. */ unsigned char* palette; /*palette in RGBARGBA... order. Must be either 0, or when allocated must have 1024 bytes*/ size_t palettesize; /*palette size in number of colors (amount of used bytes is 4 * palettesize)*/ /* transparent color key (tRNS) This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. For grayscale PNGs, r, g and b will all 3 be set to the same. When decoding, by default you can ignore this information, since LodePNG sets pixels with this key to transparent already in the raw RGBA output. The color key is only supported for color types 0 and 2. */ unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ unsigned key_r; /*red/grayscale component of color key*/ unsigned key_g; /*green component of color key*/ unsigned key_b; /*blue component of color key*/ } LodePNGColorMode; /*init, cleanup and copy functions to use with this struct*/ void lodepng_color_mode_init(LodePNGColorMode* info); void lodepng_color_mode_cleanup(LodePNGColorMode* info); /*return value is error code (0 means no error)*/ unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source); /* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */ LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth); void lodepng_palette_clear(LodePNGColorMode* info); /*add 1 color to the palette*/ unsigned lodepng_palette_add(LodePNGColorMode* info, unsigned char r, unsigned char g, unsigned char b, unsigned char a); /*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ unsigned lodepng_get_bpp(const LodePNGColorMode* info); /*get the amount of color channels used, based on colortype in the struct. If a palette is used, it counts as 1 channel.*/ unsigned lodepng_get_channels(const LodePNGColorMode* info); /*is it a grayscale type? (only colortype 0 or 4)*/ unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info); /*has it got an alpha channel? (only colortype 2 or 6)*/ unsigned lodepng_is_alpha_type(const LodePNGColorMode* info); /*has it got a palette? (only colortype 3)*/ unsigned lodepng_is_palette_type(const LodePNGColorMode* info); /*only returns true if there is a palette and there is a value in the palette with alpha < 255. Loops through the palette to check this.*/ unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info); /* Check if the given color info indicates the possibility of having non-opaque pixels in the PNG image. Returns true if the image can have translucent or invisible pixels (it still be opaque if it doesn't use such pixels). Returns false if the image can only have opaque pixels. In detail, it returns true only if it's a color type with alpha, or has a palette with non-opaque values, or if "key_defined" is true. */ unsigned lodepng_can_have_alpha(const LodePNGColorMode* info); /*Returns the byte size of a raw image buffer with given width, height and color mode*/ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*The information of a Time chunk in PNG.*/ typedef struct LodePNGTime { unsigned year; /*2 bytes used (0-65535)*/ unsigned month; /*1-12*/ unsigned day; /*1-31*/ unsigned hour; /*0-23*/ unsigned minute; /*0-59*/ unsigned second; /*0-60 (to allow for leap seconds)*/ } LodePNGTime; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*Information about the PNG image, except pixels, width and height.*/ typedef struct LodePNGInfo { /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ unsigned compression_method;/*compression method of the original file. Always 0.*/ unsigned filter_method; /*filter method of the original file*/ unsigned interlace_method; /*interlace method of the original file: 0=none, 1=Adam7*/ LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /* Suggested background color chunk (bKGD) This uses the same color mode and bit depth as the PNG (except no alpha channel), with values truncated to the bit depth in the unsigned integer. For grayscale and palette PNGs, the value is stored in background_r. The values in background_g and background_b are then unused. So when decoding, you may get these in a different color mode than the one you requested for the raw pixels. When encoding with auto_convert, you must use the color model defined in info_png.color for these values. The encoder normally ignores info_png.color when auto_convert is on, but will use it to interpret these values (and convert copies of them to its chosen color model). When encoding, avoid setting this to an expensive color, such as a non-gray value when the image is gray, or the compression will be worse since it will be forced to write the PNG with a more expensive color mode (when auto_convert is on). The decoder does not use this background color to edit the color of pixels. This is a completely optional metadata feature. */ unsigned background_defined; /*is a suggested background color given?*/ unsigned background_r; /*red/gray/palette component of suggested background color*/ unsigned background_g; /*green component of suggested background color*/ unsigned background_b; /*blue component of suggested background color*/ /* Non-international text chunks (tEXt and zTXt) The char** arrays each contain num strings. The actual messages are in text_strings, while text_keys are keywords that give a short description what the actual text represents, e.g. Title, Author, Description, or anything else. All the string fields below including strings, keys, names and language tags are null terminated. The PNG specification uses null characters for the keys, names and tags, and forbids null characters to appear in the main text which is why we can use null termination everywhere here. A keyword is minimum 1 character and maximum 79 characters long (plus the additional null terminator). It's discouraged to use a single line length longer than 79 characters for texts. Don't allocate these text buffers yourself. Use the init/cleanup functions correctly and use lodepng_add_text and lodepng_clear_text. Standard text chunk keywords and strings are encoded using Latin-1. */ size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ char** text_strings; /*the actual text*/ /* International text chunks (iTXt) Similar to the non-international text chunks, but with additional strings "langtags" and "transkeys", and the following text encodings are used: keys: Latin-1, langtags: ASCII, transkeys and strings: UTF-8. keys must be 1-79 characters (plus the additional null terminator), the other strings are any length. */ size_t itext_num; /*the amount of international texts in this PNG*/ char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ char** itext_strings; /*the actual international text - UTF-8 string*/ /*time chunk (tIME)*/ unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ LodePNGTime time; /*phys chunk (pHYs)*/ unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ unsigned phys_x; /*pixels per unit in x direction*/ unsigned phys_y; /*pixels per unit in y direction*/ unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ /* Color profile related chunks: gAMA, cHRM, sRGB, iCPP LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please use these values with a color management library. See the PNG, ICC and sRGB specifications for more information about the meaning of these values. */ /* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */ unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */ unsigned gama_gamma; /* Gamma exponent times 100000 */ /* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */ unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */ unsigned chrm_white_x; /* White Point x times 100000 */ unsigned chrm_white_y; /* White Point y times 100000 */ unsigned chrm_red_x; /* Red x times 100000 */ unsigned chrm_red_y; /* Red y times 100000 */ unsigned chrm_green_x; /* Green x times 100000 */ unsigned chrm_green_y; /* Green y times 100000 */ unsigned chrm_blue_x; /* Blue x times 100000 */ unsigned chrm_blue_y; /* Blue y times 100000 */ /* sRGB chunk: optional. May not appear at the same time as iCCP. If gAMA is also present gAMA must contain value 45455. If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000. */ unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */ unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */ /* iCCP chunk: optional. May not appear at the same time as sRGB. LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color management and conversions. For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile. For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray PNG color types and a "GRAY" profile for gray PNG color types. If you disable auto_convert, you must ensure the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of the pixel data if the pixels could be encoded as grayscale but the ICC profile is RGB. To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so make sure you compute it carefully to avoid the above problems. */ unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */ char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */ /* The ICC profile in iccp_profile_size bytes. Don't allocate this buffer yourself. Use the init/cleanup functions correctly and use lodepng_set_icc and lodepng_clear_icc. */ unsigned char* iccp_profile; unsigned iccp_profile_size; /* The size of iccp_profile in bytes */ /* End of color profile related chunks */ /* unknown chunks: chunks not known by LodePNG, passed on byte for byte. There are 3 buffers, one for each position in the PNG where unknown chunks can appear. Each buffer contains all unknown chunks for that position consecutively. The 3 positions are: 0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND. For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag above in here, since the encoder will blindly follow this and could then encode an invalid PNG file (such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST), or any non-standard PNG chunk. Do not allocate or traverse this data yourself. Use the chunk traversing functions declared later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. */ unsigned char* unknown_chunks_data[3]; size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGInfo; /*init, cleanup and copy functions to use with this struct*/ void lodepng_info_init(LodePNGInfo* info); void lodepng_info_cleanup(LodePNGInfo* info); /*return value is error code (0 means no error)*/ unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ /*replaces if exists*/ unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size); void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /* Converts raw buffer from one color type to another color type, based on LodePNGColorMode structs to describe the input and output color type. See the reference manual at the end of this header file to see which color conversions are supported. return value = LodePNG error code (0 if all went ok, an error if the conversion isn't supported) The out buffer must have size (w * h * bpp + 7) / 8, where bpp is the bits per pixel of the output color type (lodepng_get_bpp). For < 8 bpp images, there should not be padding bits at the end of scanlines. For 16-bit per channel colors, uses big endian format like PNG does. Return value is LodePNG error code */ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, unsigned w, unsigned h); unsigned lodepng_convert_rgb(unsigned* r_out, unsigned* g_out, unsigned* b_out, unsigned r_in, unsigned g_in, unsigned b_in, const LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in); #ifdef LODEPNG_COMPILE_DECODER /* Settings for the decoder. This contains settings for the PNG and the Zlib decoder, but not the Info settings from the Info structs. */ typedef struct LodePNGDecoderSettings { LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ /* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */ unsigned ignore_crc; /*ignore CRC checksums*/ unsigned ignore_critical; /*ignore unknown critical chunks*/ unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/ /* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters in string keys, etc... */ unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ unsigned remember_unknown_chunks; /* maximum size for decompressed text chunks. If a text chunk's text is larger than this, an error is returned, unless reading text chunks is disabled or this limit is set higher or disabled. Set to 0 to allow any size. By default it is a value that prevents unreasonably large strings from hogging memory. */ size_t max_text_size; /* maximum size for compressed ICC chunks. If the ICC profile is larger than this, an error will be returned. Set to 0 to allow any size. By default this is a value that prevents ICC profiles that would be much larger than any legitimate profile could be to hog memory. */ size_t max_icc_size; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGDecoderSettings; void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ typedef enum LodePNGFilterStrategy { /*every filter at zero*/ LFS_ZERO = 0, /*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/ LFS_ONE = 1, LFS_TWO = 2, LFS_THREE = 3, LFS_FOUR = 4, /*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/ LFS_MINSUM, /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending on the image, this is better or worse than minsum.*/ LFS_ENTROPY, /* Brute-force-search PNG filters by compressing each filter for each scanline. Experimental, very slow, and only rarely gives better compression than MINSUM. */ LFS_BRUTE_FORCE, /*use predefined_filters buffer: you specify the filter type for each scanline*/ LFS_PREDEFINED } LodePNGFilterStrategy; /*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...), which helps decide which color model to use for encoding. Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ typedef struct LodePNGColorStats { unsigned colored; /*not grayscale*/ unsigned key; /*image is not opaque and color key is possible instead of full alpha*/ unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/ unsigned short key_g; unsigned short key_b; unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/ unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16 or allow_palette is disabled.*/ unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order, only valid when numcolors is valid*/ unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/ size_t numpixels; /*user settings for computing/using the stats*/ unsigned allow_palette; /*default 1. if 0, disallow choosing palette colortype in auto_choose_color, and don't count numcolors*/ unsigned allow_greyscale; /*default 1. if 0, choose RGB or RGBA even if the image only has gray colors*/ } LodePNGColorStats; void lodepng_color_stats_init(LodePNGColorStats* stats); /*Get a LodePNGColorStats of the image. The stats must already have been inited. Returns error code (e.g. alloc fail) or 0 if ok.*/ unsigned lodepng_compute_color_stats(LodePNGColorStats* stats, const unsigned char* image, unsigned w, unsigned h, const LodePNGColorMode* mode_in); /*Settings for the encoder.*/ typedef struct LodePNGEncoderSettings { LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to completely follow the official PNG heuristic, filter_palette_zero must be true and filter_strategy must be LFS_MINSUM*/ unsigned filter_palette_zero; /*Which filter strategy to use when not using zeroes due to filter_palette_zero. Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ LodePNGFilterStrategy filter_strategy; /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with the same length as the amount of scanlines in the image, and each value must <= 5. You have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ const unsigned char* predefined_filters; /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). If colortype is 3, PLTE is _always_ created.*/ unsigned force_palette; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*add LodePNG identifier and version as a text chunk, for debugging*/ unsigned add_id; /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ unsigned text_compression; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGEncoderSettings; void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) /*The settings, state and information for extended encoding and decoding.*/ typedef struct LodePNGState { #ifdef LODEPNG_COMPILE_DECODER LodePNGDecoderSettings decoder; /*the decoding settings*/ #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER LodePNGEncoderSettings encoder; /*the encoding settings*/ #endif /*LODEPNG_COMPILE_ENCODER*/ LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ unsigned error; } LodePNGState; /*init, cleanup and copy functions to use with this struct*/ void lodepng_state_init(LodePNGState* state); void lodepng_state_cleanup(LodePNGState* state); void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source); #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ #ifdef LODEPNG_COMPILE_DECODER /* Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings and getting much more information about the PNG image and color mode. */ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize); /* Read the PNG header, but not the actual data. This returns only the information that is in the IHDR chunk of the PNG, such as width, height and color type. The information is placed in the info_png field of the LodePNGState. */ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, const unsigned char* in, size_t insize); #endif /*LODEPNG_COMPILE_DECODER*/ /* Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it read in the state. Returns error code on failure. Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const to find the desired chunk type, and if non null use lodepng_inspect_chunk (with chunk_pointer - start_of_file as pos). Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...). Ignores unsupported, unknown, non-metadata or IHDR chunks (without error). Requirements: &in[pos] must point to start of a chunk, must use regular lodepng_inspect first since format of most other chunks depends on IHDR, and if there is a PLTE chunk, that one must be inspected before tRNS or bKGD. */ unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos, const unsigned char* in, size_t insize); #ifdef LODEPNG_COMPILE_ENCODER /*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ unsigned lodepng_encode(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h, LodePNGState* state); #endif /*LODEPNG_COMPILE_ENCODER*/ /* The lodepng_chunk functions are normally not needed, except to traverse the unknown chunks stored in the LodePNGInfo struct, or add new ones to it. It also allows traversing the chunks of an encoded PNG file yourself. The chunk pointer always points to the beginning of the chunk itself, that is the first byte of the 4 length bytes. In the PNG file format, chunks have the following format: -4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer) -4 bytes chunk type (ASCII a-z,A-Z only, see below) -length bytes of data (may be 0 bytes if length was 0) -4 bytes of CRC, computed on chunk name + data The first chunk starts at the 8th byte of the PNG file, the entire rest of the file exists out of concatenated chunks with the above format. PNG standard chunk ASCII naming conventions: -First byte: uppercase = critical, lowercase = ancillary -Second byte: uppercase = public, lowercase = private -Third byte: must be uppercase -Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy */ /* Gets the length of the data of the chunk. Total chunk length has 12 bytes more. There must be at least 4 bytes to read from. If the result value is too large, it may be corrupt data. */ unsigned lodepng_chunk_length(const unsigned char* chunk); /*puts the 4-byte type in null terminated string*/ void lodepng_chunk_type(char type[5], const unsigned char* chunk); /*check if the type is the given type*/ unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type); /*0: it's one of the critical chunk types, 1: it's an ancillary chunk (see PNG standard)*/ unsigned char lodepng_chunk_ancillary(const unsigned char* chunk); /*0: public, 1: private (see PNG standard)*/ unsigned char lodepng_chunk_private(const unsigned char* chunk); /*0: the chunk is unsafe to copy, 1: the chunk is safe to copy (see PNG standard)*/ unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk); /*get pointer to the data of the chunk, where the input points to the header of the chunk*/ unsigned char* lodepng_chunk_data(unsigned char* chunk); const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk); #ifndef LODEPNG_NO_COMPILE_CRC /*returns 0 if the crc is correct, 1 if it's incorrect (0 for OK as usual!)*/ unsigned lodepng_chunk_check_crc(const unsigned char* chunk); #endif /*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/ void lodepng_chunk_generate_crc(unsigned char* chunk); /* Iterate to next chunks, allows iterating through all chunks of the PNG file. Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call, or the 8th byte of a PNG file which always has the first chunk), or alternatively may point to the first byte of the PNG file (which is not a chunk but the magic header, the function will then skip over it and return the first real chunk). Will output pointer to the start of the next chunk, or at or beyond end of the file if there is no more chunk after this or possibly if the chunk is corrupt. Start this process at the 8th byte of the PNG file. In a non-corrupt PNG file, the last chunk should have name "IEND". */ unsigned char* lodepng_chunk_next(unsigned char* chunk, unsigned char* end); const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk, const unsigned char* end); /*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/ unsigned char* lodepng_chunk_find(unsigned char* chunk, unsigned char* end, const char type[5]); const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]); /* Appends chunk to the data in out. The given chunk should already have its chunk header. The out variable and outsize are updated to reflect the new reallocated buffer. Returns error code (0 if it went ok) */ unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk); /* Appends new chunk to out. The chunk to append is given by giving its length, type and data separately. The type is a 4-letter string. The out variable and outsize are updated to reflect the new reallocated buffer. Returne error code (0 if it went ok) */ unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length, const char* type, const unsigned char* data); /*Calculate CRC32 of buffer*/ unsigned lodepng_crc32(const unsigned char* buf, size_t len); #endif /*LODEPNG_COMPILE_PNG*/ #ifdef LODEPNG_COMPILE_ZLIB /* This zlib part can be used independently to zlib compress and decompress a buffer. It cannot be used to create gzip files however, and it only supports the part of zlib that is required for PNG, it does not support dictionaries. */ #ifdef LODEPNG_COMPILE_DECODER /*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ unsigned lodepng_inflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings); /* Decompresses Zlib data. Reallocates the out buffer and appends the data. The data must be according to the zlib specification. Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes. out must be freed by user after usage. */ unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGDecompressSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Compresses data with Zlib. Reallocates the out buffer and appends the data. Zlib adds a small header and trailer around the deflate data. The data is output in the format of the zlib specification. Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes. out must be freed by user after usage. */ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings); /* Find length-limited Huffman code for given frequencies. This function is in the public interface only for tests, it's used internally by lodepng_deflate. */ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, size_t numcodes, unsigned maxbitlen); /*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ unsigned lodepng_deflate(unsigned char** out, size_t* outsize, const unsigned char* in, size_t insize, const LodePNGCompressSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ #ifdef LODEPNG_COMPILE_DISK /* Load a file from disk into buffer. The function allocates the out buffer, and after usage you should free it. out: output parameter, contains pointer to loaded buffer. outsize: output parameter, size of the allocated out buffer filename: the path to the file to load return value: error code (0 means ok) NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory. */ unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename); /* Save a file from buffer to disk. Warning, if it exists, this function overwrites the file without warning! buffer: the buffer to write buffersize: size of the buffer to write filename: the path to the file to save to return value: error code (0 means ok) NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and encode in-memory */ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename); #endif /*LODEPNG_COMPILE_DISK*/ #ifdef LODEPNG_COMPILE_CPP /* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */ namespace lodepng { #ifdef LODEPNG_COMPILE_PNG class State : public LodePNGState { public: State(); State(const State& other); ~State(); State& operator=(const State& other); }; #ifdef LODEPNG_COMPILE_DECODER /* Same as other lodepng::decode, but using a State for more settings and information. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const unsigned char* in, size_t insize); unsigned decode(std::vector& out, unsigned& w, unsigned& h, State& state, const std::vector& in); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER /* Same as other lodepng::encode, but using a State for more settings and information. */ unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, State& state); unsigned encode(std::vector& out, const std::vector& in, unsigned w, unsigned h, State& state); #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DISK /* Load a file from disk into an std::vector. return value: error code (0 means ok) NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and decode in-memory */ unsigned load_file(std::vector& buffer, const std::string& filename); /* Save the binary data in an std::vector to a file on disk. The file is overwritten without warning. NOTE: Wide-character filenames are not supported, you can use an external method to handle such files and encode in-memory */ unsigned save_file(const std::vector& buffer, const std::string& filename); #endif /* LODEPNG_COMPILE_DISK */ #endif /* LODEPNG_COMPILE_PNG */ #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER /* Zlib-decompress an unsigned char buffer */ unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); /* Zlib-decompress an std::vector */ unsigned decompress(std::vector& out, const std::vector& in, const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); #endif /* LODEPNG_COMPILE_DECODER */ #ifdef LODEPNG_COMPILE_ENCODER /* Zlib-compress an unsigned char buffer */ unsigned compress(std::vector& out, const unsigned char* in, size_t insize, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); /* Zlib-compress an std::vector */ unsigned compress(std::vector& out, const std::vector& in, const LodePNGCompressSettings& settings = lodepng_default_compress_settings); #endif /* LODEPNG_COMPILE_ENCODER */ #endif /* LODEPNG_COMPILE_ZLIB */ } /* namespace lodepng */ #endif /*LODEPNG_COMPILE_CPP*/ /* TODO: [.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often [.] check compatibility with various compilers - done but needs to be redone for every newer version [X] converting color to 16-bit per channel types [X] support color profile chunk types (but never let them touch RGB values by default) [ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST) [ ] make sure encoder generates no chunks with size > (2^31)-1 [ ] partial decoding (stream processing) [X] let the "isFullyOpaque" function check color keys and transparent palettes too [X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl" [ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58) [ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ... [ ] error messages with line numbers (and version) [ ] errors in state instead of as return code? [ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk [ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes [ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ... [ ] allow user to give data (void*) to custom allocator [X] provide alternatives for C library functions not present on some platforms (memcpy, ...) */ #endif /*LODEPNG_H inclusion guard*/ /* LodePNG Documentation --------------------- 0. table of contents -------------------- 1. about 1.1. supported features 1.2. features not supported 2. C and C++ version 3. security 4. decoding 5. encoding 6. color conversions 6.1. PNG color types 6.2. color conversions 6.3. padding bits 6.4. A note about 16-bits per channel and endianness 7. error values 8. chunks and PNG editing 9. compiler support 10. examples 10.1. decoder C++ example 10.2. decoder C example 11. state settings reference 12. changes 13. contact information 1. about -------- PNG is a file format to store raster images losslessly with good compression, supporting different color types and alpha channel. LodePNG is a PNG codec according to the Portable Network Graphics (PNG) Specification (Second Edition) - W3C Recommendation 10 November 2003. The specifications used are: *) Portable Network Graphics (PNG) Specification (Second Edition): http://www.w3.org/TR/2003/REC-PNG-20031110 *) RFC 1950 ZLIB Compressed Data Format version 3.3: http://www.gzip.org/zlib/rfc-zlib.html *) RFC 1951 DEFLATE Compressed Data Format Specification ver 1.3: http://www.gzip.org/zlib/rfc-deflate.html The most recent version of LodePNG can currently be found at http://lodev.org/lodepng/ LodePNG works both in C (ISO C90) and C++, with a C++ wrapper that adds extra functionality. LodePNG exists out of two files: -lodepng.h: the header file for both C and C++ -lodepng.c(pp): give it the name lodepng.c or lodepng.cpp (or .cc) depending on your usage If you want to start using LodePNG right away without reading this doc, get the examples from the LodePNG website to see how to use it in code, or check the smaller examples in chapter 13 here. LodePNG is simple but only supports the basic requirements. To achieve simplicity, the following design choices were made: There are no dependencies on any external library. There are functions to decode and encode a PNG with a single function call, and extended versions of these functions taking a LodePNGState struct allowing to specify or get more information. By default the colors of the raw image are always RGB or RGBA, no matter what color type the PNG file uses. To read and write files, there are simple functions to convert the files to/from buffers in memory. This all makes LodePNG suitable for loading textures in games, demos and small programs, ... It's less suitable for full fledged image editors, loading PNGs over network (it requires all the image data to be available before decoding can begin), life-critical systems, ... 1.1. supported features ----------------------- The following features are supported by the decoder: *) decoding of PNGs with any color type, bit depth and interlace mode, to a 24- or 32-bit color raw image, or the same color type as the PNG *) encoding of PNGs, from any raw image to 24- or 32-bit color, or the same color type as the raw image *) Adam7 interlace and deinterlace for any color type *) loading the image from harddisk or decoding it from a buffer from other sources than harddisk *) support for alpha channels, including RGBA color model, translucent palettes and color keying *) zlib decompression (inflate) *) zlib compression (deflate) *) CRC32 and ADLER32 checksums *) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only, plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system. *) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks. *) the following chunks are supported by both encoder and decoder: IHDR: header information PLTE: color palette IDAT: pixel data IEND: the final chunk tRNS: transparency for palettized images tEXt: textual information zTXt: compressed textual information iTXt: international textual information bKGD: suggested background color pHYs: physical dimensions tIME: modification time cHRM: RGB chromaticities gAMA: RGB gamma correction iCCP: ICC color profile sRGB: rendering intent 1.2. features not supported --------------------------- The following features are _not_ supported: *) some features needed to make a conformant PNG-Editor might be still missing. *) partial loading/stream processing. All data must be available and is processed in one call. *) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG: sBIT hIST sPLT 2. C and C++ version -------------------- The C version uses buffers allocated with alloc that you need to free() yourself. You need to use init and cleanup functions for each struct whenever using a struct from the C version to avoid exploits and memory leaks. The C++ version has extra functions with std::vectors in the interface and the lodepng::State class which is a LodePNGState with constructor and destructor. These files work without modification for both C and C++ compilers because all the additional C++ code is in "#ifdef __cplusplus" blocks that make C-compilers ignore it, and the C code is made to compile both with strict ISO C90 and C++. To use the C++ version, you need to rename the source file to lodepng.cpp (instead of lodepng.c), and compile it with a C++ compiler. To use the C version, you need to rename the source file to lodepng.c (instead of lodepng.cpp), and compile it with a C compiler. 3. Security ----------- Even if carefully designed, it's always possible that LodePNG contains possible exploits. If you discover one, please let me know, and it will be fixed. When using LodePNG, care has to be taken with the C version of LodePNG, as well as the C-style structs when working with C++. The following conventions are used for all C-style structs: -if a struct has a corresponding init function, always call the init function when making a new one -if a struct has a corresponding cleanup function, call it before the struct disappears to avoid memory leaks -if a struct has a corresponding copy function, use the copy function instead of "=". The destination must also be inited already. 4. Decoding ----------- Decoding converts a PNG compressed image to a raw pixel buffer. Most documentation on using the decoder is at its declarations in the header above. For C, simple decoding can be done with functions such as lodepng_decode32, and more advanced decoding can be done with the struct LodePNGState and lodepng_decode. For C++, all decoding can be done with the various lodepng::decode functions, and lodepng::State can be used for advanced features. When using the LodePNGState, it uses the following fields for decoding: *) LodePNGInfo info_png: it stores extra information about the PNG (the input) in here *) LodePNGColorMode info_raw: here you can say what color mode of the raw image (the output) you want to get *) LodePNGDecoderSettings decoder: you can specify a few extra settings for the decoder to use LodePNGInfo info_png -------------------- After decoding, this contains extra information of the PNG image, except the actual pixels, width and height because these are already gotten directly from the decoder functions. It contains for example the original color type of the PNG image, text comments, suggested background color, etc... More details about the LodePNGInfo struct are at its declaration documentation. LodePNGColorMode info_raw ------------------------- When decoding, here you can specify which color type you want the resulting raw image to be. If this is different from the colortype of the PNG, then the decoder will automatically convert the result. This conversion always works, except if you want it to convert a color PNG to grayscale or to a palette with missing colors. By default, 32-bit color is used for the result. LodePNGDecoderSettings decoder ------------------------------ The settings can be used to ignore the errors created by invalid CRC and Adler32 chunks, and to disable the decoding of tEXt chunks. There's also a setting color_convert, true by default. If false, no conversion is done, the resulting data will be as it was in the PNG (after decompression) and you'll have to puzzle the colors of the pixels together yourself using the color type information in the LodePNGInfo. 5. Encoding ----------- Encoding converts a raw pixel buffer to a PNG compressed image. Most documentation on using the encoder is at its declarations in the header above. For C, simple encoding can be done with functions such as lodepng_encode32, and more advanced decoding can be done with the struct LodePNGState and lodepng_encode. For C++, all encoding can be done with the various lodepng::encode functions, and lodepng::State can be used for advanced features. Like the decoder, the encoder can also give errors. However it gives less errors since the encoder input is trusted, the decoder input (a PNG image that could be forged by anyone) is not trusted. When using the LodePNGState, it uses the following fields for encoding: *) LodePNGInfo info_png: here you specify how you want the PNG (the output) to be. *) LodePNGColorMode info_raw: here you say what color type of the raw image (the input) has *) LodePNGEncoderSettings encoder: you can specify a few settings for the encoder to use LodePNGInfo info_png -------------------- When encoding, you use this the opposite way as when decoding: for encoding, you fill in the values you want the PNG to have before encoding. By default it's not needed to specify a color type for the PNG since it's automatically chosen, but it's possible to choose it yourself given the right settings. The encoder will not always exactly match the LodePNGInfo struct you give, it tries as close as possible. Some things are ignored by the encoder. The encoder uses, for example, the following settings from it when applicable: colortype and bitdepth, text chunks, time chunk, the color key, the palette, the background color, the interlace method, unknown chunks, ... When encoding to a PNG with colortype 3, the encoder will generate a PLTE chunk. If the palette contains any colors for which the alpha channel is not 255 (so there are translucent colors in the palette), it'll add a tRNS chunk. LodePNGColorMode info_raw ------------------------- You specify the color type of the raw image that you give to the input here, including a possible transparent color key and palette you happen to be using in your raw image data. By default, 32-bit color is assumed, meaning your input has to be in RGBA format with 4 bytes (unsigned chars) per pixel. LodePNGEncoderSettings encoder ------------------------------ The following settings are supported (some are in sub-structs): *) auto_convert: when this option is enabled, the encoder will automatically choose the smallest possible color mode (including color key) that can encode the colors of all pixels without information loss. *) btype: the block type for LZ77. 0 = uncompressed, 1 = fixed huffman tree, 2 = dynamic huffman tree (best compression). Should be 2 for proper compression. *) use_lz77: whether or not to use LZ77 for compressed block types. Should be true for proper compression. *) windowsize: the window size used by the LZ77 encoder (1 - 32768). Has value 2048 by default, but can be set to 32768 for better, but slow, compression. *) force_palette: if colortype is 2 or 6, you can make the encoder write a PLTE chunk if force_palette is true. This can used as suggested palette to convert to by viewers that don't support more than 256 colors (if those still exist) *) add_id: add text chunk "Encoder: LodePNG " to the image. *) text_compression: default 1. If 1, it'll store texts as zTXt instead of tEXt chunks. zTXt chunks use zlib compression on the text. This gives a smaller result on large texts but a larger result on small texts (such as a single program name). It's all tEXt or all zTXt though, there's no separate setting per text yet. 6. color conversions -------------------- An important thing to note about LodePNG, is that the color type of the PNG, and the color type of the raw image, are completely independent. By default, when you decode a PNG, you get the result as a raw image in the color type you want, no matter whether the PNG was encoded with a palette, grayscale or RGBA color. And if you encode an image, by default LodePNG will automatically choose the PNG color type that gives good compression based on the values of colors and amount of colors in the image. It can be configured to let you control it instead as well, though. To be able to do this, LodePNG does conversions from one color mode to another. It can convert from almost any color type to any other color type, except the following conversions: RGB to grayscale is not supported, and converting to a palette when the palette doesn't have a required color is not supported. This is not supported on purpose: this is information loss which requires a color reduction algorithm that is beyond the scope of a PNG encoder (yes, RGB to gray is easy, but there are multiple ways if you want to give some channels more weight). By default, when decoding, you get the raw image in 32-bit RGBA or 24-bit RGB color, no matter what color type the PNG has. And by default when encoding, LodePNG automatically picks the best color model for the output PNG, and expects the input image to be 32-bit RGBA or 24-bit RGB. So, unless you want to control the color format of the images yourself, you can skip this chapter. 6.1. PNG color types -------------------- A PNG image can have many color types, ranging from 1-bit color to 64-bit color, as well as palettized color modes. After the zlib decompression and unfiltering in the PNG image is done, the raw pixel data will have that color type and thus a certain amount of bits per pixel. If you want the output raw image after decoding to have another color type, a conversion is done by LodePNG. The PNG specification gives the following color types: 0: grayscale, bit depths 1, 2, 4, 8, 16 2: RGB, bit depths 8 and 16 3: palette, bit depths 1, 2, 4 and 8 4: grayscale with alpha, bit depths 8 and 16 6: RGBA, bit depths 8 and 16 Bit depth is the amount of bits per pixel per color channel. So the total amount of bits per pixel is: amount of channels * bitdepth. 6.2. color conversions ---------------------- As explained in the sections about the encoder and decoder, you can specify color types and bit depths in info_png and info_raw to change the default behaviour. If, when decoding, you want the raw image to be something else than the default, you need to set the color type and bit depth you want in the LodePNGColorMode, or the parameters colortype and bitdepth of the simple decoding function. If, when encoding, you use another color type than the default in the raw input image, you need to specify its color type and bit depth in the LodePNGColorMode of the raw image, or use the parameters colortype and bitdepth of the simple encoding function. If, when encoding, you don't want LodePNG to choose the output PNG color type but control it yourself, you need to set auto_convert in the encoder settings to false, and specify the color type you want in the LodePNGInfo of the encoder (including palette: it can generate a palette if auto_convert is true, otherwise not). If the input and output color type differ (whether user chosen or auto chosen), LodePNG will do a color conversion, which follows the rules below, and may sometimes result in an error. To avoid some confusion: -the decoder converts from PNG to raw image -the encoder converts from raw image to PNG -the colortype and bitdepth in LodePNGColorMode info_raw, are those of the raw image -the colortype and bitdepth in the color field of LodePNGInfo info_png, are those of the PNG -when encoding, the color type in LodePNGInfo is ignored if auto_convert is enabled, it is automatically generated instead -when decoding, the color type in LodePNGInfo is set by the decoder to that of the original PNG image, but it can be ignored since the raw image has the color type you requested instead -if the color type of the LodePNGColorMode and PNG image aren't the same, a conversion between the color types is done if the color types are supported. If it is not supported, an error is returned. If the types are the same, no conversion is done. -even though some conversions aren't supported, LodePNG supports loading PNGs from any colortype and saving PNGs to any colortype, sometimes it just requires preparing the raw image correctly before encoding. -both encoder and decoder use the same color converter. The function lodepng_convert does the color conversion. It is available in the interface but normally isn't needed since the encoder and decoder already call it. Non supported color conversions: -color to grayscale when non-gray pixels are present: no error is thrown, but the result will look ugly because only the red channel is taken (it assumes all three channels are the same in this case so ignores green and blue). The reason no error is given is to allow converting from three-channel grayscale images to one-channel even if there are numerical imprecisions. -anything to palette when the palette does not have an exact match for a from-color in it: in this case an error is thrown Supported color conversions: -anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA -any gray or gray+alpha, to gray or gray+alpha -anything to a palette, as long as the palette has the requested colors in it -removing alpha channel -higher to smaller bitdepth, and vice versa If you want no color conversion to be done (e.g. for speed or control): -In the encoder, you can make it save a PNG with any color type by giving the raw color mode and LodePNGInfo the same color mode, and setting auto_convert to false. -In the decoder, you can make it store the pixel data in the same color type as the PNG has, by setting the color_convert setting to false. Settings in info_raw are then ignored. 6.3. padding bits ----------------- In the PNG file format, if a less than 8-bit per pixel color type is used and the scanlines have a bit amount that isn't a multiple of 8, then padding bits are used so that each scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output. The raw input image you give to the encoder, and the raw output image you get from the decoder will NOT have these padding bits, e.g. in the case of a 1-bit image with a width of 7 pixels, the first pixel of the second scanline will the 8th bit of the first byte, not the first bit of a new byte. 6.4. A note about 16-bits per channel and endianness ---------------------------------------------------- LodePNG uses unsigned char arrays for 16-bit per channel colors too, just like for any other color format. The 16-bit values are stored in big endian (most significant byte first) in these arrays. This is the opposite order of the little endian used by x86 CPU's. LodePNG always uses big endian because the PNG file format does so internally. Conversions to other formats than PNG uses internally are not supported by LodePNG on purpose, there are myriads of formats, including endianness of 16-bit colors, the order in which you store R, G, B and A, and so on. Supporting and converting to/from all that is outside the scope of LodePNG. This may mean that, depending on your use case, you may want to convert the big endian output of LodePNG to little endian with a for loop. This is certainly not always needed, many applications and libraries support big endian 16-bit colors anyway, but it means you cannot simply cast the unsigned char* buffer to an unsigned short* buffer on x86 CPUs. 7. error values --------------- All functions in LodePNG that return an error code, return 0 if everything went OK, or a non-zero code if there was an error. The meaning of the LodePNG error values can be retrieved with the function lodepng_error_text: given the numerical error code, it returns a description of the error in English as a string. Check the implementation of lodepng_error_text to see the meaning of each code. It is not recommended to use the numerical values to programmatically make different decisions based on error types as the numbers are not guaranteed to stay backwards compatible. They are for human consumption only. Programmatically only 0 or non-0 matter. 8. chunks and PNG editing ------------------------- If you want to add extra chunks to a PNG you encode, or use LodePNG for a PNG editor that should follow the rules about handling of unknown chunks, or if your program is able to read other types of chunks than the ones handled by LodePNG, then that's possible with the chunk functions of LodePNG. A PNG chunk has the following layout: 4 bytes length 4 bytes type name length bytes data 4 bytes CRC 8.1. iterating through chunks ----------------------------- If you have a buffer containing the PNG image data, then the first chunk (the IHDR chunk) starts at byte number 8 of that buffer. The first 8 bytes are the signature of the PNG and are not part of a chunk. But if you start at byte 8 then you have a chunk, and can check the following things of it. NOTE: none of these functions check for memory buffer boundaries. To avoid exploits, always make sure the buffer contains all the data of the chunks. When using lodepng_chunk_next, make sure the returned value is within the allocated memory. unsigned lodepng_chunk_length(const unsigned char* chunk): Get the length of the chunk's data. The total chunk length is this length + 12. void lodepng_chunk_type(char type[5], const unsigned char* chunk): unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type): Get the type of the chunk or compare if it's a certain type unsigned char lodepng_chunk_critical(const unsigned char* chunk): unsigned char lodepng_chunk_private(const unsigned char* chunk): unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk): Check if the chunk is critical in the PNG standard (only IHDR, PLTE, IDAT and IEND are). Check if the chunk is private (public chunks are part of the standard, private ones not). Check if the chunk is safe to copy. If it's not, then, when modifying data in a critical chunk, unsafe to copy chunks of the old image may NOT be saved in the new one if your program doesn't handle that type of unknown chunk. unsigned char* lodepng_chunk_data(unsigned char* chunk): const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk): Get a pointer to the start of the data of the chunk. unsigned lodepng_chunk_check_crc(const unsigned char* chunk): void lodepng_chunk_generate_crc(unsigned char* chunk): Check if the crc is correct or generate a correct one. unsigned char* lodepng_chunk_next(unsigned char* chunk): const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk): Iterate to the next chunk. This works if you have a buffer with consecutive chunks. Note that these functions do no boundary checking of the allocated data whatsoever, so make sure there is enough data available in the buffer to be able to go to the next chunk. unsigned lodepng_chunk_append(unsigned char** out, size_t* outsize, const unsigned char* chunk): unsigned lodepng_chunk_create(unsigned char** out, size_t* outsize, unsigned length, const char* type, const unsigned char* data): These functions are used to create new chunks that are appended to the data in *out that has length *outsize. The append function appends an existing chunk to the new data. The create function creates a new chunk with the given parameters and appends it. Type is the 4-letter name of the chunk. 8.2. chunks in info_png ----------------------- The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3 buffers (each with size) to contain 3 types of unknown chunks: the ones that come before the PLTE chunk, the ones that come between the PLTE and the IDAT chunks, and the ones that come after the IDAT chunks. It's necessary to make the distinction between these 3 cases because the PNG standard forces to keep the ordering of unknown chunks compared to the critical chunks, but does not force any other ordering rules. info_png.unknown_chunks_data[0] is the chunks before PLTE info_png.unknown_chunks_data[1] is the chunks after PLTE, before IDAT info_png.unknown_chunks_data[2] is the chunks after IDAT The chunks in these 3 buffers can be iterated through and read by using the same way described in the previous subchapter. When using the decoder to decode a PNG, you can make it store all unknown chunks if you set the option settings.remember_unknown_chunks to 1. By default, this option is off (0). The encoder will always encode unknown chunks that are stored in the info_png. If you need it to add a particular chunk that isn't known by LodePNG, you can use lodepng_chunk_append or lodepng_chunk_create to the chunk data in info_png.unknown_chunks_data[x]. Chunks that are known by LodePNG should not be added in that way. E.g. to make LodePNG add a bKGD chunk, set background_defined to true and add the correct parameters there instead. 9. compiler support ------------------- No libraries other than the current standard C library are needed to compile LodePNG. For the C++ version, only the standard C++ library is needed on top. Add the files lodepng.c(pp) and lodepng.h to your project, include lodepng.h where needed, and your program can read/write PNG files. It is compatible with C90 and up, and C++03 and up. If performance is important, use optimization when compiling! For both the encoder and decoder, this makes a large difference. Make sure that LodePNG is compiled with the same compiler of the same version and with the same settings as the rest of the program, or the interfaces with std::vectors and std::strings in C++ can be incompatible. CHAR_BITS must be 8 or higher, because LodePNG uses unsigned chars for octets. *) gcc and g++ LodePNG is developed in gcc so this compiler is natively supported. It gives no warnings with compiler options "-Wall -Wextra -pedantic -ansi", with gcc and g++ version 4.7.1 on Linux, 32-bit and 64-bit. *) Clang Fully supported and warning-free. *) Mingw The Mingw compiler (a port of gcc for Windows) should be fully supported by LodePNG. *) Visual Studio and Visual C++ Express Edition LodePNG should be warning-free with warning level W4. Two warnings were disabled with pragmas though: warning 4244 about implicit conversions, and warning 4996 where it wants to use a non-standard function fopen_s instead of the standard C fopen. Visual Studio may want "stdafx.h" files to be included in each source file and give an error "unexpected end of file while looking for precompiled header". This is not standard C++ and will not be added to the stock LodePNG. You can disable it for lodepng.cpp only by right clicking it, Properties, C/C++, Precompiled Headers, and set it to Not Using Precompiled Headers there. NOTE: Modern versions of VS should be fully supported, but old versions, e.g. VS6, are not guaranteed to work. *) Compilers on Macintosh LodePNG has been reported to work both with gcc and LLVM for Macintosh, both for C and C++. *) Other Compilers If you encounter problems on any compilers, feel free to let me know and I may try to fix it if the compiler is modern and standards compliant. 10. examples ------------ This decoder example shows the most basic usage of LodePNG. More complex examples can be found on the LodePNG website. NOTE: these examples do not support wide-character filenames, you can use an external method to handle such files and encode or decode in-memory 10.1. decoder C++ example ------------------------- #include "lodepng.h" #include int main(int argc, char *argv[]) { const char* filename = argc > 1 ? argv[1] : "test.png"; //load and decode std::vector image; unsigned width, height; unsigned error = lodepng::decode(image, width, height, filename); //if there's an error, display it if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl; //the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ... } 10.2. decoder C example ----------------------- #include "lodepng.h" int main(int argc, char *argv[]) { unsigned error; unsigned char* image; size_t width, height; const char* filename = argc > 1 ? argv[1] : "test.png"; error = lodepng_decode32_file(&image, &width, &height, filename); if(error) printf("decoder error %u: %s\n", error, lodepng_error_text(error)); / * use image here * / free(image); return 0; } 11. state settings reference ---------------------------- A quick reference of some settings to set on the LodePNGState For decoding: state.decoder.zlibsettings.ignore_adler32: ignore ADLER32 checksums state.decoder.zlibsettings.custom_...: use custom inflate function state.decoder.ignore_crc: ignore CRC checksums state.decoder.ignore_critical: ignore unknown critical chunks state.decoder.ignore_end: ignore missing IEND chunk. May fail if this corruption causes other errors state.decoder.color_convert: convert internal PNG color to chosen one state.decoder.read_text_chunks: whether to read in text metadata chunks state.decoder.remember_unknown_chunks: whether to read in unknown chunks state.info_raw.colortype: desired color type for decoded image state.info_raw.bitdepth: desired bit depth for decoded image state.info_raw....: more color settings, see struct LodePNGColorMode state.info_png....: no settings for decoder but ouput, see struct LodePNGInfo For encoding: state.encoder.zlibsettings.btype: disable compression by setting it to 0 state.encoder.zlibsettings.use_lz77: use LZ77 in compression state.encoder.zlibsettings.windowsize: tweak LZ77 windowsize state.encoder.zlibsettings.minmatch: tweak min LZ77 length to match state.encoder.zlibsettings.nicematch: tweak LZ77 match where to stop searching state.encoder.zlibsettings.lazymatching: try one more LZ77 matching state.encoder.zlibsettings.custom_...: use custom deflate function state.encoder.auto_convert: choose optimal PNG color type, if 0 uses info_png state.encoder.filter_palette_zero: PNG filter strategy for palette state.encoder.filter_strategy: PNG filter strategy to encode with state.encoder.force_palette: add palette even if not encoding to one state.encoder.add_id: add LodePNG identifier and version as a text chunk state.encoder.text_compression: use compressed text chunks for metadata state.info_raw.colortype: color type of raw input image you provide state.info_raw.bitdepth: bit depth of raw input image you provide state.info_raw: more color settings, see struct LodePNGColorMode state.info_png.color.colortype: desired color type if auto_convert is false state.info_png.color.bitdepth: desired bit depth if auto_convert is false state.info_png.color....: more color settings, see struct LodePNGColorMode state.info_png....: more PNG related settings, see struct LodePNGInfo 12. changes ----------- The version number of LodePNG is the date of the change given in the format yyyymmdd. Some changes aren't backwards compatible. Those are indicated with a (!) symbol. Not all changes are listed here, the commit history in github lists more: https://github.com/lvandeve/lodepng *) 09 jan 2022: minor decoder speed improvements. *) 27 jun 2021: added warnings that file reading/writing functions don't support wide-character filenames (support for this is not planned, opening files is not the core part of PNG decoding/decoding and is platform dependent). *) 17 okt 2020: prevent decoding too large text/icc chunks by default. *) 06 mar 2020: simplified some of the dynamic memory allocations. *) 12 jan 2020: (!) added 'end' argument to lodepng_chunk_next to allow correct overflow checks. *) 14 aug 2019: around 25% faster decoding thanks to huffman lookup tables. *) 15 jun 2019: (!) auto_choose_color API changed (for bugfix: don't use palette if gray ICC profile) and non-ICC LodePNGColorProfile renamed to LodePNGColorStats. *) 30 dec 2018: code style changes only: removed newlines before opening braces. *) 10 sep 2018: added way to inspect metadata chunks without full decoding. *) 19 aug 2018: (!) fixed color mode bKGD is encoded with and made it use palette index in case of palette. *) 10 aug 2018: (!) added support for gAMA, cHRM, sRGB and iCCP chunks. This change is backwards compatible unless you relied on unknown_chunks for those. *) 11 jun 2018: less restrictive check for pixel size integer overflow *) 14 jan 2018: allow optionally ignoring a few more recoverable errors *) 17 sep 2017: fix memory leak for some encoder input error cases *) 27 nov 2016: grey+alpha auto color model detection bugfix *) 18 apr 2016: Changed qsort to custom stable sort (for platforms w/o qsort). *) 09 apr 2016: Fixed colorkey usage detection, and better file loading (within the limits of pure C90). *) 08 dec 2015: Made load_file function return error if file can't be opened. *) 24 okt 2015: Bugfix with decoding to palette output. *) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding. *) 24 aug 2014: Moved to github *) 23 aug 2014: Reduced needless memory usage of decoder. *) 28 jun 2014: Removed fix_png setting, always support palette OOB for simplicity. Made ColorProfile public. *) 09 jun 2014: Faster encoder by fixing hash bug and more zeros optimization. *) 22 dec 2013: Power of two windowsize required for optimization. *) 15 apr 2013: Fixed bug with LAC_ALPHA and color key. *) 25 mar 2013: Added an optional feature to ignore some PNG errors (fix_png). *) 11 mar 2013: (!) Bugfix with custom free. Changed from "my" to "lodepng_" prefix for the custom allocators and made it possible with a new #define to use custom ones in your project without needing to change lodepng's code. *) 28 jan 2013: Bugfix with color key. *) 27 okt 2012: Tweaks in text chunk keyword length error handling. *) 8 okt 2012: (!) Added new filter strategy (entropy) and new auto color mode. (no palette). Better deflate tree encoding. New compression tweak settings. Faster color conversions while decoding. Some internal cleanups. *) 23 sep 2012: Reduced warnings in Visual Studio a little bit. *) 1 sep 2012: (!) Removed #define's for giving custom (de)compression functions and made it work with function pointers instead. *) 23 jun 2012: Added more filter strategies. Made it easier to use custom alloc and free functions and toggle #defines from compiler flags. Small fixes. *) 6 may 2012: (!) Made plugging in custom zlib/deflate functions more flexible. *) 22 apr 2012: (!) Made interface more consistent, renaming a lot. Removed redundant C++ codec classes. Reduced amount of structs. Everything changed, but it is cleaner now imho and functionality remains the same. Also fixed several bugs and shrunk the implementation code. Made new samples. *) 6 nov 2011: (!) By default, the encoder now automatically chooses the best PNG color model and bit depth, based on the amount and type of colors of the raw image. For this, autoLeaveOutAlphaChannel replaced by auto_choose_color. *) 9 okt 2011: simpler hash chain implementation for the encoder. *) 8 sep 2011: lz77 encoder lazy matching instead of greedy matching. *) 23 aug 2011: tweaked the zlib compression parameters after benchmarking. A bug with the PNG filtertype heuristic was fixed, so that it chooses much better ones (it's quite significant). A setting to do an experimental, slow, brute force search for PNG filter types is added. *) 17 aug 2011: (!) changed some C zlib related function names. *) 16 aug 2011: made the code less wide (max 120 characters per line). *) 17 apr 2011: code cleanup. Bugfixes. Convert low to 16-bit per sample colors. *) 21 feb 2011: fixed compiling for C90. Fixed compiling with sections disabled. *) 11 dec 2010: encoding is made faster, based on suggestion by Peter Eastman to optimize long sequences of zeros. *) 13 nov 2010: added LodePNG_InfoColor_hasPaletteAlpha and LodePNG_InfoColor_canHaveAlpha functions for convenience. *) 7 nov 2010: added LodePNG_error_text function to get error code description. *) 30 okt 2010: made decoding slightly faster *) 26 okt 2010: (!) changed some C function and struct names (more consistent). Reorganized the documentation and the declaration order in the header. *) 08 aug 2010: only changed some comments and external samples. *) 05 jul 2010: fixed bug thanks to warnings in the new gcc version. *) 14 mar 2010: fixed bug where too much memory was allocated for char buffers. *) 02 sep 2008: fixed bug where it could create empty tree that linux apps could read by ignoring the problem but windows apps couldn't. *) 06 jun 2008: added more error checks for out of memory cases. *) 26 apr 2008: added a few more checks here and there to ensure more safety. *) 06 mar 2008: crash with encoding of strings fixed *) 02 feb 2008: support for international text chunks added (iTXt) *) 23 jan 2008: small cleanups, and #defines to divide code in sections *) 20 jan 2008: support for unknown chunks allowing using LodePNG for an editor. *) 18 jan 2008: support for tIME and pHYs chunks added to encoder and decoder. *) 17 jan 2008: ability to encode and decode compressed zTXt chunks added Also various fixes, such as in the deflate and the padding bits code. *) 13 jan 2008: Added ability to encode Adam7-interlaced images. Improved filtering code of encoder. *) 07 jan 2008: (!) changed LodePNG to use ISO C90 instead of C++. A C++ wrapper around this provides an interface almost identical to before. Having LodePNG be pure ISO C90 makes it more portable. The C and C++ code are together in these files but it works both for C and C++ compilers. *) 29 dec 2007: (!) changed most integer types to unsigned int + other tweaks *) 30 aug 2007: bug fixed which makes this Borland C++ compatible *) 09 aug 2007: some VS2005 warnings removed again *) 21 jul 2007: deflate code placed in new namespace separate from zlib code *) 08 jun 2007: fixed bug with 2- and 4-bit color, and small interlaced images *) 04 jun 2007: improved support for Visual Studio 2005: crash with accessing invalid std::vector element [0] fixed, and level 3 and 4 warnings removed *) 02 jun 2007: made the encoder add a tag with version by default *) 27 may 2007: zlib and png code separated (but still in the same file), simple encoder/decoder functions added for more simple usage cases *) 19 may 2007: minor fixes, some code cleaning, new error added (error 69), moved some examples from here to lodepng_examples.cpp *) 12 may 2007: palette decoding bug fixed *) 24 apr 2007: changed the license from BSD to the zlib license *) 11 mar 2007: very simple addition: ability to encode bKGD chunks. *) 04 mar 2007: (!) tEXt chunk related fixes, and support for encoding palettized PNG images. Plus little interface change with palette and texts. *) 03 mar 2007: Made it encode dynamic Huffman shorter with repeat codes. Fixed a bug where the end code of a block had length 0 in the Huffman tree. *) 26 feb 2007: Huffman compression with dynamic trees (BTYPE 2) now implemented and supported by the encoder, resulting in smaller PNGs at the output. *) 27 jan 2007: Made the Adler-32 test faster so that a timewaste is gone. *) 24 jan 2007: gave encoder an error interface. Added color conversion from any greyscale type to 8-bit greyscale with or without alpha. *) 21 jan 2007: (!) Totally changed the interface. It allows more color types to convert to and is more uniform. See the manual for how it works now. *) 07 jan 2007: Some cleanup & fixes, and a few changes over the last days: encode/decode custom tEXt chunks, separate classes for zlib & deflate, and at last made the decoder give errors for incorrect Adler32 or Crc. *) 01 jan 2007: Fixed bug with encoding PNGs with less than 8 bits per channel. *) 29 dec 2006: Added support for encoding images without alpha channel, and cleaned out code as well as making certain parts faster. *) 28 dec 2006: Added "Settings" to the encoder. *) 26 dec 2006: The encoder now does LZ77 encoding and produces much smaller files now. Removed some code duplication in the decoder. Fixed little bug in an example. *) 09 dec 2006: (!) Placed output parameters of public functions as first parameter. Fixed a bug of the decoder with 16-bit per color. *) 15 okt 2006: Changed documentation structure *) 09 okt 2006: Encoder class added. It encodes a valid PNG image from the given image buffer, however for now it's not compressed. *) 08 sep 2006: (!) Changed to interface with a Decoder class *) 30 jul 2006: (!) LodePNG_InfoPng , width and height are now retrieved in different way. Renamed decodePNG to decodePNGGeneric. *) 29 jul 2006: (!) Changed the interface: image info is now returned as a struct of type LodePNG::LodePNG_Info, instead of a vector, which was a bit clumsy. *) 28 jul 2006: Cleaned the code and added new error checks. Corrected terminology "deflate" into "inflate". *) 23 jun 2006: Added SDL example in the documentation in the header, this example allows easy debugging by displaying the PNG and its transparency. *) 22 jun 2006: (!) Changed way to obtain error value. Added loadFile function for convenience. Made decodePNG32 faster. *) 21 jun 2006: (!) Changed type of info vector to unsigned. Changed position of palette in info vector. Fixed an important bug that happened on PNGs with an uncompressed block. *) 16 jun 2006: Internally changed unsigned into unsigned where needed, and performed some optimizations. *) 07 jun 2006: (!) Renamed functions to decodePNG and placed them in LodePNG namespace. Changed the order of the parameters. Rewrote the documentation in the header. Renamed files to lodepng.cpp and lodepng.h *) 22 apr 2006: Optimized and improved some code *) 07 sep 2005: (!) Changed to std::vector interface *) 12 aug 2005: Initial release (C++, decoder only) 13. contact information ----------------------- Feel free to contact me with suggestions, problems, comments, ... concerning LodePNG. If you encounter a PNG image that doesn't work properly with this decoder, feel free to send it and I'll use it to find and fix the problem. My email address is (puzzle the account and domain together with an @ symbol): Domain: gmail dot com. Account: lode dot vandevenne. Copyright (c) 2005-2022 Lode Vandevenne */ chafa-1.18.2/tests/000077500000000000000000000000001517447374300140265ustar00rootroot00000000000000chafa-1.18.2/tests/.gitignore000066400000000000000000000000531517447374300160140ustar00rootroot00000000000000/*.log /*.trs /canvas-test /term-info-test chafa-1.18.2/tests/Makefile.am000066400000000000000000000024311517447374300160620ustar00rootroot00000000000000SUBDIRS = data AM_CFLAGS = $(CHAFA_CFLAGS) $(GLIB_CFLAGS) LDADD = $(GLIB_LIBS) $(top_builddir)/chafa/libchafa.la ## --- Test driver --- # Our custom test driver is based on Automake's, with the addition that # it will print logs of failed tests to the console. This simplifies log # perusal in build systems. Requires Automake 1.12+. LOG_DRIVER = $(top_srcdir)/tests/test-driver.sh ## --- Backend tests --- noinst_PROGRAMS = \ canvas-test \ term-info-test canvas_test_SOURCES = \ canvas-test.c term_info_test_SOURCES = \ term-info-test.c ## --- Frontend tests --- if WANT_TOOLS TOOL_CHECKS = \ chafa-tool-bad-test.sh \ chafa-tool-closed-test.sh \ chafa-tool-cmode-test.sh \ chafa-tool-format-test.sh \ chafa-tool-grid-test.sh \ chafa-tool-loader-test.sh \ chafa-tool-options-test.sh \ chafa-tool-pipe-test.sh \ chafa-tool-retval-test.sh else TOOL_CHECKS = endif TESTS = \ canvas-test \ term-info-test \ $(TOOL_CHECKS) AM_TESTS_ENVIRONMENT = \ export top_builddir=$(top_builddir) \ export top_srcdir=$(top_srcdir) \ ; ## --- General --- ## Include $(top_builddir)/chafa to get generated chafaconfig.h. AM_CPPFLAGS = \ -I$(top_srcdir)/chafa \ -I$(top_builddir)/chafa EXTRA_DIST = \ $(TOOL_CHECKS) \ chafa-tool-gallery.sh \ chafa-tool-test-common.sh \ test-driver.sh chafa-1.18.2/tests/canvas-test.c000066400000000000000000000204251517447374300164250ustar00rootroot00000000000000#include "config.h" #include #include static void dump_char_buf (const gunichar *char_buf, gint width, gint height) { gint x, y; gchar *row, *p; row = g_malloc (width * 6 + 1); for (y = 0; y < height; y++) { p = row; for (x = 0; x < width; x++) { gint len; len = g_unichar_to_utf8 (char_buf [(y * width) + x], p); g_assert (len > 0); p += len; } *(p++) = '\n'; fwrite (row, sizeof (gchar), p - row, stdout); } g_free (row); } static gunichar * extract_char_buf (ChafaCanvas *canvas, gint width, gint height) { gunichar *char_buf; gint x, y; char_buf = g_malloc (width * height * sizeof (gunichar)); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { char_buf [(y * width) + x] = chafa_canvas_get_char_at (canvas, x, y); } } return char_buf; } static gboolean validate_char_buf (gunichar *char_buf, gint width, gint height, gunichar expected_char) { gint x, y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { if (char_buf [(y * width) + x] != expected_char) return FALSE; } } return TRUE; } static gboolean test_color_char (ChafaCanvas *canvas, ChafaPixelType pixel_type, const guint8 *pixel, gunichar expected_char) { gint width, height; gunichar *char_buf; gboolean result; chafa_canvas_config_get_geometry (chafa_canvas_peek_config (canvas), &width, &height); g_assert (width > 0); g_assert (height > 0); chafa_canvas_draw_all_pixels (canvas, pixel_type, pixel, 1, 1, 4); char_buf = extract_char_buf (canvas, width, height); result = validate_char_buf (char_buf, width, height, expected_char); if (!result) { g_print ("Unexpected canvas buffer (%dx%d, want '%c', ptype %d):\n", width, height, (gchar) expected_char, pixel_type); dump_char_buf (char_buf, width, height); } g_free (char_buf); return result; } static void symbols_fgbg_test_bw_canvas (ChafaCanvas *canvas, gchar black_char, gchar white_char) { const guint8 black_pixel_rgba8 [4] = { 0x00, 0x00, 0x00, 0xff }; const guint8 black_pixel_argb8 [4] = { 0xff, 0x00, 0x00, 0x00 }; const guint8 white_pixel [4] = { 0xff, 0xff, 0xff, 0xff }; gboolean result = TRUE; result &= test_color_char (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, black_pixel_rgba8, black_char); result &= test_color_char (canvas, CHAFA_PIXEL_ARGB8_UNASSOCIATED, black_pixel_argb8, black_char); result &= test_color_char (canvas, CHAFA_PIXEL_RGBA8_PREMULTIPLIED, black_pixel_rgba8, black_char); result &= test_color_char (canvas, CHAFA_PIXEL_ARGB8_PREMULTIPLIED, black_pixel_argb8, black_char); result &= test_color_char (canvas, CHAFA_PIXEL_RGB8, black_pixel_rgba8, black_char); result &= test_color_char (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, white_pixel, white_char); result &= test_color_char (canvas, CHAFA_PIXEL_RGBA8_PREMULTIPLIED, white_pixel, white_char); result &= test_color_char (canvas, CHAFA_PIXEL_BGR8, white_pixel, white_char); g_assert (result == TRUE); } static void symbols_fgbg_test_bw_params (ChafaCanvasMode canvas_mode, gboolean fg_only, gint width, gint height, const gchar *selectors, gchar black_char, gchar white_char, gfloat work_factor) { ChafaSymbolMap *symbol_map; ChafaCanvasConfig *config; ChafaCanvas *canvas, *canvas2; symbol_map = chafa_symbol_map_new (); chafa_symbol_map_apply_selectors (symbol_map, selectors, NULL); config = chafa_canvas_config_new (); chafa_canvas_config_set_canvas_mode (config, canvas_mode); chafa_canvas_config_set_symbol_map (config, symbol_map); chafa_canvas_config_set_geometry (config, width, height); chafa_canvas_config_set_fg_only_enabled (config, fg_only); chafa_canvas_config_set_work_factor (config, work_factor); canvas = chafa_canvas_new (config); symbols_fgbg_test_bw_canvas (canvas, black_char, white_char); canvas2 = chafa_canvas_new_similar (canvas); chafa_canvas_unref (canvas); symbols_fgbg_test_bw_canvas (canvas2, black_char, white_char); chafa_canvas_unref (canvas2); chafa_canvas_config_unref (config); chafa_symbol_map_unref (symbol_map); } static void symbols_fgbg_test (void) { symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG_BGFG, TRUE, 10, 10, "[ a]", ' ', 'a', 0.5f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG_BGFG, TRUE, 17, 17, "[ .]", ' ', '.', 0.2f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG_BGFG, TRUE, 1, 1, "[.Q]", '.', 'Q', 0.8f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG, FALSE, 10, 10, "[ ']", ' ', '\'', 1.0f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG, TRUE, 23, 23, "[ .]", ' ', '.', 0.05f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG, FALSE, 3, 3, "[ /]", ' ', '/', 0.2f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG_BGFG, TRUE, 41, 41, "[ .Q]", ' ', 'Q', 0.5f); symbols_fgbg_test_bw_params (CHAFA_CANVAS_MODE_FGBG_BGFG, TRUE, 100, 100, "[ a]", ' ', 'a', 0.2f); } /* Colors must round-trip to specified FG/BG colors in FG/BG modes */ static void colors_fgbg_test (void) { const guint32 fg_rgb = 0xff0000; /* Red */ const guint32 bg_rgb = 0x0000ff; /* Blue */ const guint8 src_pixels [4] = { 0x80, 0x80, 0x80, 0xff }; /* Gray */ ChafaCanvasMode modes [] = { CHAFA_CANVAS_MODE_FGBG, CHAFA_CANVAS_MODE_FGBG_BGFG }; guint i; for (i = 0; i < G_N_ELEMENTS (modes); i++) { ChafaCanvasConfig *config = chafa_canvas_config_new (); ChafaCanvas *canvas; gint x, y; chafa_canvas_config_set_canvas_mode (config, modes [i]); chafa_canvas_config_set_geometry (config, 4, 4); chafa_canvas_config_set_fg_color (config, fg_rgb); chafa_canvas_config_set_bg_color (config, bg_rgb); canvas = chafa_canvas_new (config); chafa_canvas_draw_all_pixels (canvas, CHAFA_PIXEL_RGBA8_UNASSOCIATED, src_pixels, 1, 1, 4); for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { gint fg = -2, bg = -2; chafa_canvas_get_colors_at (canvas, x, y, &fg, &bg); g_assert_true (fg == -1 || fg == (gint) fg_rgb || fg == (gint) bg_rgb); g_assert_true (bg == -1 || bg == (gint) fg_rgb || bg == (gint) bg_rgb); } } chafa_canvas_unref (canvas); chafa_canvas_config_unref (config); } } int main (int argc, char *argv []) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/canvas/symbols/fgbg", symbols_fgbg_test); g_test_add_func ("/canvas/colors/fgbg", colors_fgbg_test); return g_test_run (); } chafa-1.18.2/tests/chafa-tool-bad-test.sh000077500000000000000000000004221517447374300201010ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" for format in $formats; do for size in $sizes; do run_cmd_all_bad_files "$tool -f $format -c 16 --dither fs -s $size --threads 12 -d 0 --speed max" || exit $? done done chafa-1.18.2/tests/chafa-tool-closed-test.sh000077500000000000000000000011531517447374300206260ustar00rootroot00000000000000#!/bin/sh # Run with closed stdin/stdout/stderr and look for hangs. [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" run_cmd_noredir () { cmd="$1 ${top_srcdir}/tests/data/good/taxic.jpg" echo "$cmd" >&2 sh -c "$cmd" || exit $? } run_cmd_noredir "$timeout_cmd 20 $tool -f symbol -c full -s 200 <&- >/dev/null" || exit $? run_cmd_noredir "$timeout_cmd 20 $tool -f symbol -c full -s 200 >&- " || exit $? run_cmd_noredir "$timeout_cmd 20 $tool -f symbol -c full -s 200 <&- >&- " || exit $? run_cmd_noredir "$timeout_cmd 20 $tool -f symbol -c full -s 200 <&- >&- 2>&-" || exit $? chafa-1.18.2/tests/chafa-tool-cmode-test.sh000077500000000000000000000004721517447374300204470ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" for cmode in $cmodes; do for size in $sizes; do for n_threads in $thread_counts; do run_cmd "$tool -f symbol -c $cmode -s $size --threads $n_threads --animate no" || exit $? done done done chafa-1.18.2/tests/chafa-tool-format-test.sh000077500000000000000000000005161517447374300206470ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" for format in $formats; do for size in $sizes; do for n_threads in $thread_counts; do run_cmd_all_safe_files "$tool -f $format -c full -s $size --threads $n_threads -d 0 --speed max" || exit $? done done done chafa-1.18.2/tests/chafa-tool-gallery.sh000077500000000000000000000062571517447374300200510ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" tempdir="${top_builddir}/tests/.temp" xvfb=$(which Xvfb) [ "x${xvfb}" = "x" ] && echo "Missing Xvfb" && exit 1 gterm_name=xfce4-terminal gterm=$(which ${gterm_name}) [ "x${gterm}" = "x" ] && echo "Missing ${gterm_name}" && exit 1 montage=$(which montage) [ "x${montage}" = "x" ] && echo "Missing montage" && exit 1 # Terminal parameters font='xos4 Terminus 8' geometry=60x40 screen_size=1280x1024 # Chafa parameter lists color_modes="tc 240 16 8 2 none" color_spaces="rgb din99d" color_extractors="average median" dither_types="none ordered diffusion" symbol_selectors="+0 all wide" work_factors="1 5 9" # Input filename. Must be in data/good/. file="taxic.jpg" function gen_screenshot { FNAME="$1" echo -- Running -e "bash -c \"${tool} -s ${geometry} -w ${5} -c ${2} --symbols ${3} --color-space ${4} \ ${top_srcdir}/tests/data/good/${FNAME} ; sleep 0.5 ; import -window chafa out/out-${2}-${3}-${5}-${4}.png -trim\"" HOME="${tempdir}" XDG_CONFIG_HOME="${HOME}/.config" DISPLAY=:99 ${gterm} \ -T chafa \ --disable-server \ --geometry ${geometry}+0+0 \ --font "$font" \ --hide-menubar \ --hide-toolbar \ --hide-borders \ --hide-scrollbar \ -e "bash -c \"${tool} -s ${geometry} -w ${5} -c ${2} --symbols ${3} --color-space ${4} \ ${top_srcdir}/tests/data/good/${FNAME}; sleep 0.5 ; import -window chafa ${tempdir}/out/${2}-${3}-${5}-${4}.png -trim >/dev/null 2>&1\"" >/dev/null 2>&1 } trap "" EXIT SIGQUIT SIGSTOP SIGTERM # Make sure we don't blow away any old .temp dir rm -Rf "${tempdir}/.config" rm -Rf "${tempdir}/out" rmdir "${tempdir}" mkdir -p "${tempdir}/out" mkdir -p ${tempdir}/.config/xfce4/terminal cat >${tempdir}/.config/xfce4/terminal/terminalrc </dev/null 2>&1 & XVFB_PID=$! sleep 2 for cmode in ${color_modes}; do for symbols in ${symbol_selectors}; do for cspace in ${color_spaces}; do for work in ${work_factors}; do gen_screenshot "$file" "$cmode" "$symbols" "$cspace" "$work" done done done done kill ${XVFB_PID} rm -f "${top_builddir}/tests/chafa-tool-gallery.png" ${montage} -stroke white -background grey20 -geometry +4+4 -tile 6 -label '%f' \ "${tempdir}/out/*.png" \ "${top_builddir}/tests/chafa-tool-gallery.png" chafa-1.18.2/tests/chafa-tool-grid-test.sh000077500000000000000000000005331517447374300203030ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" grid_sizes="1 4 x3 5x" for format in $formats; do for size in $sizes; do for grid_size in $grid_sizes; do run_cmd_all_safe_files "$tool -f $format -c full -s $size --grid $grid_size --threads 3" || exit $? done done done chafa-1.18.2/tests/chafa-tool-loader-test.sh000077500000000000000000000005371517447374300206300ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" extensions="$(get_supported_loaders)" for ext in $extensions; do [ "x${ext}" = "ximagemagick" ] && continue [ "x${ext}" = "xcoregraphics" ] && continue run_cmd_single_file "$tool -f sixel --threads 12 --animate no" "good/pixel.$ext" || exit $? done chafa-1.18.2/tests/chafa-tool-options-test.sh000077500000000000000000000015121517447374300210470ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" color_spaces="rgb din99d" color_extractors="average median" dither_types="none ordered diffusion" symbol_selectors="none all wide 0..1ffff" for format in $formats; do for color_space in $color_spaces; do for color_extractor in $color_extractors; do for dither_type in $dither_types; do for main_symbols in $symbol_selectors; do for fill_symbols in $symbol_selectors; do run_cmd "$tool -f $format -c 240 -s 53 --threads 12 --animate no --color-space $color_space \ --color-extractor $color_extractor --dither $dither_type --symbols $main_symbols --fill $fill_symbols" || exit $? done done done done done done chafa-1.18.2/tests/chafa-tool-pipe-test.sh000077500000000000000000000002511517447374300203100ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" run_cmd "$tool -f symbol -c full -s 63 --threads 12 --animate no < " || exit $? chafa-1.18.2/tests/chafa-tool-retval-test.sh000077500000000000000000000013731517447374300206560ustar00rootroot00000000000000#!/bin/sh [ "x${srcdir}" = "x" ] && srcdir="." . "${srcdir}/chafa-tool-test-common.sh" # One file ok run_cmd_single_file "$tool --animate no" "good/pixel.png" [ $? -eq 0 ] || exit 1 # Multiple files ok run_cmd_multiple_files "$tool --animate no" "good/pixel.png" "good/pixel.gif" [ $? -eq 0 ] || exit 1 # Some files failed run_cmd_multiple_files "$tool --animate no" "good/pixel.png" "missing.foo" [ $? -eq 1 ] || exit 1 # All files failed run_cmd_multiple_files "$tool --animate no" "missing1.foo" "missing2.foo" [ $? -eq 2 ] || exit 1 # --help run_cmd_multiple_files "$tool --help" [ $? -eq 0 ] || exit 1 # --version run_cmd_multiple_files "$tool --version" [ $? -eq 0 ] || exit 1 # No args run_cmd_multiple_files "$tool" [ $? -eq 2 ] || exit 1 exit 0 chafa-1.18.2/tests/chafa-tool-test-common.sh000077500000000000000000000046421517447374300206530ustar00rootroot00000000000000#!/bin/sh run_cmd () { cmd="$1 ${top_srcdir}/tests/data/good/card-32c-noalpha.png >/dev/null" echo "$cmd" >&2 sh -c "$cmd" || exit $? } run_cmd_single_file () { file="$2" cmd="$1 ${top_srcdir}/tests/data/$file >/dev/null" echo "$cmd" >&2 sh -c "$cmd" || exit $? } run_cmd_multiple_files () { cmd="$1"; shift flist= for fname in $*; do flist="$flist ${top_srcdir}/tests/data/$1"; shift done cmd="$cmd $flist >/dev/null" echo "$cmd" >&2 sh -c "$cmd" } run_cmd_all_safe_files () { # Only run on files for which we're guaranteed to have loaders. # '$dir/*.{gif,png,xwd}' is a Bash-ism, so we can't use it. dir="${top_srcdir}/tests/data/good" cmd="$1 $dir/*.gif $dir/*.png $dir/*.xwd >/dev/null" echo "$cmd" >&2 sh -c "$cmd" || exit $? } run_cmd_all_bad_files () { # Since this only fails on crashes, it's fine to run it on absolutely # everything (including unsupported formats, build files etc). cmd="$1 ${top_srcdir}/tests/data/bad/* >/dev/null" echo "$cmd" >&2 sh -c "$cmd" result=$? # For corrupt files, an exit value of 1 or 2 is a fine result, # but other values are trouble (e.g. terminated by signal). if test $result -gt 2; then exit $result; fi } get_supported_loaders () { sh -c "$tool --version" \ | grep '^Loaders: ' \ | sed 's/[^:]*: *\(.*\)/\1/' \ | tr [:upper:] [:lower:] } [ "x${top_srcdir}" = "x" ] && top_srcdir="${srcdir}/.." [ "x${top_builddir}" = "x" ] && top_builddir=".." # Passing "long" as the first argument will run a much longer test # cycle with more permutations. long="no" [ $# -ge 1 ] && [ "x$1" = "xlong" ] && long="yes" tool="${top_builddir}/tools/chafa/chafa" timeout_cmd="$(which timeout)" [ "x${timeout_cmd}" = "x" ] && timeout_cmd="$(which gtimeout)" [ "x${timeout_cmd}" = "x" ] && timeout_cmd="timeout" # Foreground mode: allow access to tty. Not necessary currently. # timeout_cmd="${timeout_cmd} -f" if [ "x$long" = "xyes" ]; then formats="symbol sixel kitty iterm" cmodes="none 2 8 16/8 16 240 256 full" sizes="$(seq 1 100)" thread_counts="$(seq 1 32) 61" else # The 13x13 size is specifically required to trigger the normalization # overflow (see commit 60d7718f9d8fa591d3d69079fe583913c58c19d9). formats="symbol sixel kitty iterm" cmodes="none 2 16/8 16 256 full" sizes="1 3 13x13 133" thread_counts="1 2 3 12 32 61" fi chafa-1.18.2/tests/data/000077500000000000000000000000001517447374300147375ustar00rootroot00000000000000chafa-1.18.2/tests/data/Makefile.am000066400000000000000000000000231517447374300167660ustar00rootroot00000000000000SUBDIRS = bad good chafa-1.18.2/tests/data/bad/000077500000000000000000000000001517447374300154655ustar00rootroot00000000000000chafa-1.18.2/tests/data/bad/Makefile.am000066400000000000000000000005511517447374300175220ustar00rootroot00000000000000EXTRA_DIST = \ libnsgif-lzw-oob.gif \ libnsgif-uninitialized-frame-fields.gif \ lodepng-adam7-mystery-over-read.png \ lodepng-zero-length-literal.png \ lodepng-zlib-big-alloc.png \ no-frame-data.gif \ pixops-normalize-signed-overflow.gif \ smolscale-unaligned-1.xwd \ smolscale-unaligned-2.xwd \ smolscale-unaligned-3.xwd \ smolscale-unaligned-4.xwd chafa-1.18.2/tests/data/bad/libavif-inf-frame-duration.avif000066400000000000000000000364001517447374300234400ustar00rootroot00000000000000 ftypavisavismsf1miafMA1Bmeta2hdlrpictGPAC pict Handlerpitmiloc@ :(iinfinfeav01ImagetiprpUipcoispeŸŸpaspav1C� ¼ôóÿó€pixiipmaƒ„ímoovlmvhdÚ²]9Ú²]9èô@iodsOÿÿÿþÿdtrak\tkhdÚ²]9ô@ŸŸ$edtselstôÜmdia mdhdÚ²]9ÿÿUÄ+hdlrpictGPAC avifs‰minfvmhd$dinfdref url Istbl½stsd­av01ŸŸHHÿÿav1C� ¼ôóÿó€paspccst| fielbtrt :º º sttsýÿstssstsc(stsz : L Ù3stcoU8ämdat ¼ôóÿó€2ª€ø¡m5¬8*bvÔÿÿÿùPïqD’I$•~wqwI$’IWqD”eÕ˜åž3@´Ï½hRáµ_ÿÿÕ ›Üë݉©…ª´¥©Z«JZ€ ´¥ª´Ðé7n£2äãnïMíì J5ÇÜ'B~@ hSˆ@™©›Õ 0õª8çx»ßuÛâá›é” °a�=S‚´lZúË2¾³Ê£>äg§‘Ÿtp$]sÄ÷Øs½KñJ¦5¸(ÌãñÓ!2¿D2t'20°{/®6ÆE�‰âÿ¤Yi` ÜÕüáCK$—¬Š Î44oùø'£á¿ê^�Ik%!´LcæÞ¥hÖ0ÒEæ=g&oé.–„)踇ÀÕ¯UQ ã°ŒÀSÜ"{pø„]½[ ¬#‡VøHr3XdxÈB¢ã;JÓÉn¼y&’Å>®�JEù©r� Û`&7ûµ»è Êzƒ�dç©ê$f�@)çÔÞ#g¶õ¾�KÀû«Õ¼LÑÁ%]·™V®ÃÖÞI1¨SUÂü=°àB¯BmWùîÅ &‚q/ääH”.¦c ͤnèë˜Yæ È^úlè×C¸—Öæ´ÏˆÏ N4» £õrò¶F®4r»ç›E`®êŽ· ^ŽŸ/g…/40• ætâß¿Uð'(·‚¾L.cÊnpìoéßð¨D8A­q- ¢„8C„Ð-ÐÊ(Bçߌbù¸ÍnÔV|W*³âo ã[�n5Á7‘Í<BQ‚Ǫ@J0YAdl²†²’ž;µ‹ö0U^ßdCÓ pî�ßÒG#�í]"¾±OTÛc@‚'ÕÄMÜÊÈËøCüìÜìôxæ«G–U«Rµ+j&åb†âv&åZÈ…º#ñ";Ÿk"奊|oÐI“²„Ÿ¯.'oÿáüuÐ /üTtàÉ¿QÅi `6�Ñsÿè5 )Es¥Ü ºi-¡.»üÝ>@æÿÀfmá–7MŒ_-~¯þ’Göøœz‡v·kÑA;kv·kv½Ld6·kÑBl+VºÁßáZ >•sØà Q-n³–¥aÜs ú¡T2¢>µb“£™“h*Y–¿ |:)O'¹ý{ŽŒ#æQm«‰(jK�ûS±æ|¹ßs¹–ô¤H›ËØ�é~6çèŒa$*V·˜™ÕßÒÄf/gÜýû­&ÒÑ®êñ±­&Òm-1³*ÒŽ®hf¤á¼x!ò‚iEÁ~Ç«—‘�\ãÇ—3J])©C/†Ò(c€Ûãêá“ö|;Â,ø'xq·„Elü°<ü�h v�ëÆBLÝ#ÇdùD¦½÷ü·êk5ùâ¯fxNÑïòã¨Üë.•'Å(‹`p@55øyÎÓë4+¦]ºpøËðNÉoæÈ×&%UœÖƪ/ô8ºõi;ÌLø—ÈpÈí’^ô޹øÒ:oúS·B�þÁ¿{û4W-“‚NxÜù— ü-ˆw-³C�UJb÷•9‡"©Ì;:œÃ³­[«›—Þ3$$11r&Ozíúìi«Ê(¶Ú Îï÷súŒ®£FŠkì–—Üõ”Ý�1M…Ö"±›ÖONe¤.ÜÕ=ð-‚áJg ù‰�©Õ…ƒºÈxØ.Z E*ú…0È”nG¥¡ÍEVFp?îäm™áuŽø­§$»ø6™2 ×rÂqXEY`cþâþ;@¡oíÉÄR® ~zAˆˆ.îWQ|wye'ª‘è§wþ¤ÙF¨uȦ_9 ŽíC &ñ|€¥ùn³‘�hË©T?˜¡å¡ úHуœx1~ÒÁm‰|ùjÅEVÌ©m—ÒÃÞYŠ$SEÏØ›†j²µeLÓ z!‡xì¹ÁŒz].ÒésÊ¼ÒæLÃ8—6€ŒœW‚MIi|HoÓ&íÐÊwªgß´ý@Ýå7··—E-:;â&á€N/ýC�ˆÑw•‚6ùSÑ aù0`¸£àÿgSø'ÃB¶eO.âæ6ÐéU`znn‚ÏÑ­�…«ŸçkˆÌh�ÃïýQ° ¼ôóÿó€2ª€ø¡m5¬8*bvÔÿÿÿùPïqD’I$•qwqwI$’IWqD”eÕ˜åž3@´Ï½hRáµ_ÿÿÕ ›Üë݉©…ª´¥©Z«JZ€ ´¥ª´Ðé7n£2äãnïMíì J5ÇÜ'B~@ hSˆ@™©›Õ 0õª8çx»ßuÛâá›é” °a�=S‚´lZúË2¾³Ê£>äg§‘Ÿtp$]sÄ÷Øs½KñJ¦5¸(ÌãñÓ!2¿D2t'20°{/®6ÆE�‰âÿ¤Yi` ÜÕüáCK$—¬Š Î44oùø'£á¿ê^�Ik%!´LcæÞ¥hÖ0ÒEæ=g&oé.–„)踇ÀÕ¯UQ ã°ŒÀSÜ"{pø„]½[ ¬#‡zzzzzzzzzzzVøHr3XdxÈB¢ã;JÓÉn¼y&’Å>®�JEù©r� Û`&7ûµ»è Êzƒ�dç©ê$f�@)çÔÞ#g¶õ¾�KÀû«Õ¼LÑÁ%]·™V®ÃÖÞI1¨SUÂü=°àB¯BmWùîÅ &‚q/ääH”.¦c ͤnèë˜Yæ È^úlè×C¸—Öæ´ÏˆÏ N4» £õrò¶F®4r»ç›E`®êŽ· ^ŽŸ/g…/40• ætâß¿Uð'(·‚¾L.cÊnpìoéßð¨D8A q- ¢„8C„Ð-ÐÊ(Bçߌbù¸ÍnÔV|W*³âo ã[�n5Á7‘Í<BQ‚Ǫ@J0YAdl²†²’ž;µ‹ö0U^ßdCÓ pî�ßÒG#�í]"¾±OTÛc@‚'ÕÄMÜÊÈËøCüìÜìôxæ«G–U«Rµ+j&åb†âv&åZÈ…º#ñ";Ÿk"奊|oÐI“²„Ÿ¯.'oÿáüuÐ /üTtàÉ¿QÅi `6�Ñsÿè5 )Es¥Ü ºi-¡.»üÝ>@æÿÀfmá–7MŒ_-~¯þ’Göøœz‡v·kÑA;kv·kv½Ld6·kÑBl+VºÁßáZ >•sØà Q-n³–¥aÜs ú¡T2¢>µb“£™“h*Y–¿ |:)O'¹ý{ŽŒ#æQm«‰(jK�ûS±æ|¹ßs¹–ô¤H›ËØ�é~6çèŒa$*V·˜™ÕßÒÄf/gÜýû­&ÒÑ®êñ±­&Òm-1³*ÒŽ®hf¤á¼x!ò‚iEÁ~Ç«—‘�\ãÇ—3J])©C/†Ò(c€Ûãêá“ö|;Â,ø'xq·„Elü°<ü�h v�ëÆBLÝ#ÇdùD¦½÷ü·êk5ùâ¯fxNÑïòã¨Üë.•'Å(‹`p@55øyÎÓë4+¦]ºpøËðNÉoæÈ×&%UœÖƪ/ô8ºõi;ÌLø—ÈpÈí’^ô޹øÒ:oúS·B�þÁ¿{û4W-“‚NxÜù— ü-ˆw-³C�UJb÷•9‡"©Ì;:œÃ³­[«›—Þ3$$11r&Ozíúìi«Ê(¶Ú Îï÷súŒ®£FŠkì–—Üõ”Ý�1Md"±›ÖONe¤.ÜÕ=ð-‚áJg ù‰�©Õ…ƒºÈxØ.Z E*ú…0È”nG¥¡ÍEVFp?îäm™áuŽø­§$»ø6™2 ×rÂqXEY`cþâþ;@¡oíÉÄR® ~zAˆˆ.îWQ|wye'ª‘è§wþ¤ÙF¨uȦ_9 ŽíC &ñ|€¥ùn³‘�hË©T?˜¡å¡ úHуœx1~ÒÁm‰|ùjÅEVÌ©m—ÒÃÞYŠ$SEÏØ›†j²µeLÓ z!‡xì¹ÁŒz].ÒésÊ¼ÒæLÃ8—6€ŒœW‚MIi|HoÓ&íÐÊwªgß´ý@Ýå7··—E-:;â&á€N/ýC�ˆÑw•‚6ùSÑ aù0`¸£àÿgSø'ÃB¶eO.âæ6ÐéU`znn‚ÏÑ­�…«ŸçkˆÌh�ÃïýQ°2É0§.G€@ùo2šÒ0z¨Wv)…öÂñ&—x| U¼¯owqkiá8 âE¦iîè°‚µpÕfÊêîÀ¯ØÇÕߤeø­–obƒÎ ÃeMܧ²ž;>x›²ñ'XwV=GJ„I´³qžÐ.2kÄ-4Î809“£­¥K;îQeØn¥[‚ÍéVïøÔy*ÛÉÇõaëXx,a_GŽ‚P!“ÉߣÀqÊ¡k±l×hÖì|*Ô%ç«Ô�Çr=`Á; tdñÔ&(@ø�CFƒÓæÝÊÛúÁBµn ;`If§b5OêL¦¥vå5CSUgQ_ôü4ñ‡“�l-®ÐñõÚ²eI2Ñ™à6Ô¤R0H©&Õ¡ãºQ1+@6з|°„}áÀo2VPµ^Üô_}FY08{þ#Î’Ætt¹ý¥¬2®Þ2£â9#î„¡@ ^„í?ËŠ§¶¹µXaÄ9O™Ä#}FyÜpÐríÌ•mÛ‘çqþ×H b§›ÚSC?ôÕŒ;ÌãnÓ` v–À^¬7¬©¤Ÿm,<Á°›Nêw½.Ð"�¹Í€W:ãŸVZ9‘ÐýnT¬õº¹‚5]‚Añå·ùsü{?æ¸íæn/ÿÍ‘5¯V{7³{O˜õ¯WùG³{7´ù_—wX$Xì÷³`‚™ÕÝ÷ë'‰¦_«hcõ÷Џ4%жš!Üÿf+.üUJñZr}=«ëa™HqÉj)ò–�²íºë‡-ç�ÀÛ-û§º_¦Ïx÷�t†z_¦ˆt÷�x÷Hp†Átê: K¦–/ Ëp§Ö#ɹ¤†ìæÒE•4šµH%ïUGÉPˆ·•e�g£†ÓµîUÔ&ðƒ·  ÷-Ú{ªWo¶ ëÒÉ"¾x!GÀ£Ù¢ÜQƒÓ³�78?†êäV9Z…Ô“#Ÿ,Y‹+Bø1ŒŒÀ ¢§…òDËJsÀYeíJ¨Ð{ðs32Û«áÃÝí•E[œŽyƒ":ÄLÈ_¸g X\c#l�~0i /Ô·Y‘7Q1ÿ“²D¹îlüoÄÃmO… æø¶KÈ´t�3ÝÚ©ŽƒÐD/r>p\žÎ"&èQl¶kãæN+«G8�¼"Ö°ïyÔ�î¡ìe�ÜUIãÊ�Ž­\Ÿ&¨B¦<¿9¢Š@t<Í8ìdî¿cŸ¤A—é`ÜéºZ{c�íöÈ])ƒ›ÖéX”23Å[ ® wÓíôK¶íîWa5x ˆñ' Ó Ë ÞKrì@kEyÀ¡RCuøÍ!)=ä³ §¬�ôê6ŒðExå`ç¼ 5–'\—­5òõn% Ò€}ôƒ›–™ ’<†x{êó9#'ÛF§œ—ÞD‰«ð'ˆ�AËǵzʤwÛö£³…·£þ–%®µ ÓÁ h–WÈûS­ob›Zs‹dÝ…hœßvúJé(u¡ÍÀ)ê¶x®†N,*R!}<„¶  "«ïˆEšCfa.‹ñÑE·¥± <å­"©Eó}&¬O)ªwˆÔï9÷Û+R‚êÁ@ÃRhö5tõIqGFŠ/ˆ¾Á <ðÜ<µ>ñ>_5õô=A¾ÓbîkWàX9>ÿYkL[ûüù¾Ì±kËM7˜d<mP/sê’lÉì#7”¡©ÐD†Þeî´Ÿ}¶é'Œ[«…x¿tŸµùš…øYhîöŒ&qÓ£çù<-±$ NuŸ Kï&y&°K„ÓBÑrc‡”Т…¹½8K !ÏfYtE—¬æB öü­Ô|ˆÑÛ/ÑwÛº·°,*>2�œ×F to�GFß7N›!w(»£)ÂÔ¼ŸK¼y¢™ÿøgþX FâXxB®‰(¯]¨£±d9bË~Ìk-"%T–XO÷¸T¨®ZræÊzµ6ŸlåÂò^úÐn:b–ªœÂmc¿C‹ìvôT ÀøA¼k≴'à„[ÇÀÛÚÞÉ9­ðÛßydTâf¤Ëù³Ÿ6~U’9NØ@ õ¶£žá)¼Ñzà¨LÙk¤ Û)9C‹¨ffwiÕsÚ¹¬½ seÇ0>¤ÿÚ¤/3Ï‹ÊÉ¿e¾—çä<¹Ö dO¾^&\w0 tbQcx³õl£mã-_”•X«sÿ¥ßø™_BÜËte?¼oAïîÜ'2Þdø·%uͲÄeUKâ+”kï…¡D°« Æx]ôö èe7”>•8cbõ§±`jé2¾õW,‹8£Öݶh²DMo2VPµ^Üô_}FY08{þ#ß’Ætt¹ý¥¬Ú‚ÃxJCS#�½=ö7Àw ñ0€vÒ„Æj3V’Óz/[Å‘%Ò©¶u�¶þ`ù}xȯÆÇqÅ'êµ’ô=³3ìv¶¦ô`…V�lÿ9Űdge 3»™w~˜¹ÇþÚ¼ü–²–ãf…SÑù'oée�‹d¦•nÝöãë¯ÅIÜždÓ‰úA2G‡UN3Á×C:¤ ð‰E‰?Pؼ"Éîgs[š¥àÓÁÁùI1ï£ìà^4šnø�ÙÞÚüòúrn}CH$eéî§ã –�©Òy¶ö>þt1e‡Ð2\7I;tcëÕk ½À’ÒuB¸>NÚµ¿CÕÑ îäè ÇÙK=Îò�{61 ©í?|§’ò›²m‚Ç©Z¬»ðZ¥#@T{‰)¼y Þ¶¬áùMtÙÈ$©gÃLƒÉç2Æ0ûØ?pGØÌÀ —C-»>Þx뜫Î-Åv;é)}Ò}é{„¶7ë.ª•™d…Ç¿ÎS„))F[nƒq;PN‘¿Ã ò9o%  ge¤õð}iQéD‚‹y3Ž!4Nø’ zÞSå9d1¿ÞeÓŠ"ãÈWA 'ïS§¡Ã0´ÜtªøQV¸Íx¾2…±XG™3ÔUý áÑ~ìÒ¤ªÚ·FàfDš¸íŒz›;9 „oQ�U}¼dG� igjÑ¢¯‚‹pag[¼Õ'U7�Œ1sò“¡N¦§Âè�Ÿ¿Ëý Y³Á1ž×]TÀ&gŽ”å»s_i”Ò‘Sú=ó»(Ë$Niˆ9o�"¸LŽï«Ñ†Íf{a;à½Á!avçhù`PÕˆAÄÉéJ‹¦9.´_mºô’Ôý}Ý 8ýoe_„Æ*õ!ùÜÂÑjäwúáM'an¶ŸŒâáòµ��ñtE?³CEYÍ*üþ< üµ¤‚}‘' /C�dj�`¶ñrþȧ�«Hå��Bi2ðf,dGU­_}|“bèN‰™½sM&ÈW…*€Å�©ˆ+!õè”v%$ê/�‹älã^¥—¾ÀMÁˆ~ŠûØæfä/0¬ �±k”Dè’¶¿Mt¥U¹¹.Š´?< œ–à‚\gcÌ‘ÁºÅ<5iènþ!r+9iº)Ý< ÎNǨª\Xóš·]”Ëò—^¥e–¼�åÃ.×L–ƒt`‹eJ–›K¯=ûZ mùu:ÝeË1º�n¬0Þ%X0‰­¤6}iŒƒCët˜×/ ÉÂE¸rú?!lGRE®»®Ðóð–Ï~UÕå,jc ¸ <ʼÊÀ¹·Ó‚äè V-ê+İ‘E!˜š‚÷ò dvÞ.|íÖ©c,×*�1ص:–)jïO,˜,¦Lþ1??cŠ_&fƒ†8*¨Wþ�—^§¡Ã0´ÜtªøQV¸Íx¾2…±XG™3ÔUý áÑ~®9·Õ 2Ö0ˆ.~€ø%Œ¡;zï™×·T²ãb FFÄ. …diP#†Ò�«õ¯Ìû2¼þqÞTe¸þ›SAQ²©S °û®8œ´fD; Çá1Ñ…bÞ-RU¤$éb ţߡÒ�åß‹xr”‘ 9ýgºÁK42Ä‚Ë3dIÝÂìªßïÆô¬Î’AªT˜,¾±úÝ7 7ˆ– ¡†ó¶zqbîAÞî‚ÐßÚÖªtQ`ì­È=Ű¿�9ÀRð¬æPâY²¬ñC~ׯ2AWæÎ:QYÈæ‰N¥\�Õæ8ŠèÙÒÞʯ¸¬¨L<ùe‰T)"¯ëóÆù4õƒ³©¥âOãQÓäÛ&"ý¯¬NìÝnŸŒÕ IËk½^c? ƒñE%Ž#'ª‰p““ ó«Kg™ófz„?ò4Ž,¥‚ÛñâI®’üû;fÆx¶}æŠÂ�(üü¥V†w¬àœXœ±ñP0vå7jÐ-þÖT{̔ٸ™:“ðEñÓ!Ý—]ãÇG)Zj1D`Ž*¯†¤ŒÇuCü?õêàô'õ�Üñeá.+‘ã éÝ*ÿì�‹KúiÊl‚û‹mß–vôÍU/œz¯9-“Üð®;~ÀQ�°Ë5ô夿Òþ`Åþ 4óò=R-ŰҀUìÝ{´n”ŽP�Ù^,b° Ã¥¾�¹Ûé@ÿo¡¾’÷M3)2B Ä�aa×^`Ù4Ì}Hg®c(S;"2yEâB ·s²ô‰»2ª"`#lRrÑ!*Ûk¦£ˆ5AR”ˆ»9g»?ÿQ”Ž@¦.&ýÊ®3BíØàð&SÝ03ÉÔµ·/Á4܆=Çõ,÷�ï6²P2ÌÑâ xò»[Рʨ¤Iõž�ðžiöl�fˆ)hT"ÊQK‡S5hDZìVjV”¼ôF ß;“!¸ ×£…`~C“òCÒŸ"9O® 4K�B$%³� Õ…Æâó0IJÈhˆƒÖÌ¥ýÓ‰o˜÷î™Ø5.¬�GÇÂr¼zIÀ�°P:¸©ÔúCô*`�ðJš†QÈ€«¦yC àñÔ+BË�6\T%#"Í‹z <ëîè Ù¼K¡±ÎÁî-Kó~¡í'qFâ¶XýºÃ;'ÅÁ©µøu;»éxí`¨ �o—>¿A‘3zÌŸ¿Ôä¤ÕWnªVÑW’‘êYŸâ¶sh¦ÏVÒÎWü“õ8áGéî ÷”ÖêîÇ.�£PW¿D ]$jŠB)@æ}F!'Ĺ›Ÿ]b˜OX7ö;…9ô°d +°\¾úųÁ°ŒÕG˜~Qp<"kƒî¿V¡GZ¬R‰€f = ùÆ8Ñ#,qø é8Kiî× ò«/Å2ïrÝ·òj•4Íy^9ìpɱ¯°I6™/\ÞòyçêxEñ…X›0ö½ãY©ŒâL� ±dZ�õ3—/�l‡Ã«î-d­s ¾ "î”±e‚d‡rÖÞÞWª'~ 7àšNè’.mæ}¥167ýhgŽf*T“d;QOg¬OúcÈ¿ÿöÎÊÈ«‚¬*±¬ ȫڰ*¬+µ«²´ˆÌv—×aq×zðZñƒ1üXîx÷Wý$–Å××6+ÍÆ ÃÍTŒS¥3ŠœôתÀViÐûó9š�îO�¦_›ý§Š²ÝÛ0¯m �õˆ9…îã/®i÷5Uw žtª+6Ò‹SÂÔ7ã¢ÊÚ{õÄÛîqA”T \Â�l„k‡:wíÐå š4àäÅû5°¼gþ‘¸â6VQ¯– :-9…¥ïÇü­†'Ü[š*#¨ '�™.j­å9þa�d…è2I!hc¢<·‰ [”þ�z«?�Vü0ÜFTäâã§E4« w#éYAô8®ÏÇt/Ö6§O|—“ÔîIQ�~~wC¸ÿNG”Yòkm›Evà›¼—é ¼“•<ÆÕ9÷àkÆ­iVM1ÍÓÞ}v‚ëæâãÈÛˆ+¹»GEž�ì¯έ1žJø˜]”€ënõÓ^HUûÚ«&5ÕXßó Xr”®K/ïm‹]• å[Œ’v~ͧG%:7fןás¾ Å••ëW7…ŠEY˜ÂÍ5G!kcg Hü /Uyšóõµ*ŽéS pG[!^³(¬ ¢ä8å»IØ¡c”A°£¤ÛøîûÞïWŠ·!õº‰øMï³M7ù‹Çù¦lGôSnt®1†¡C1_meÂ?V˜ŒðãoGЗwBÎÍ+:ÍlÛ/gž'®ŠµdZø·šÛ˜]ʨvÀ$ší3ÃaT}§Ì®f nY¢,­©xêíÔ`& Éá‰Ã£Ydòo læ%¨U¼XÌÒ°×nzω &VV®'"A­WòqnÀö>y­&a+Qƒï¹xœ1X“²™–VÜ{·7¢ñ¹Å½%ó Chü{ºmΪ.¦ßßâèçóŒ,d§½8²’YðÇÔ=`­äËê·*{–î7ð­›ÁÑå}ô²x…9äTÖ½ZkœßèÝû4'H©¶Aפ™ufLà@Â"¼J"ýå5L‚¨$Äæ>¸‹á²h;1³KP… Ôjá`øZŠ yÁTd“SÇhŠhçñµU)#ŸƒÎŒAb¼“[�Ü…ÈÔ¶Ö×›à«c Ç÷­›JdŸµxuèÍeo¥ßH÷°º?ÙËÛeÃ&ºÈ¢|¦ž™3ÃM€÷(uyãòs²Ð_¬°ÍP®é8K½67ö„Sá–¶B8ÉmH‰Ï=ÿN–¬‘¥ŽÜàn»j[äˆ�¸ÿ§#îS�W=äëVm8'2r”åY7�Mr™¢ÃÞte&3ãyqj£áz#®ÖùN[¦¡wGH»#À2°0E.~€ø ]ç;»Ó̽ÉôDÌQÊ!îÃê«”7‚þ3þj0¥¨,QYl=éÄ‚—£¯&YæïoªR‹Aœµ{™É�›Cx«ÈmšA´ø"h‰Î0E…p øë�Òê×ýUªÚíàn“ ‰Ô±Ìã{r�¤©’ïmšMö9o…ZÛFa@µý.¸;ÿþ‘X,˜waþ»¯¨a\ʘ\Yt…åcÙæÓöiM¼.¯é—!¡©*_Œ\dõ\Á¶N¤?�¢_£´—³:È%%îqàXAëž§Yw-]$öÒЃh¸}›Ìdñ Ú‹¾—ÚMkMú f FZ%Ui²µòçF­Ìa¢:‘RôÙÕ\¬Éz¦W¸û*L°Y�Eø|�ÁZÁ…’«F‡šsÞ‡¯*û.�ò`ÿÚiñ� ;ÿVÍõè¸BJý´({$ŠÔxéÀTöR²0ˆ‡%w >IÀ4àµvˆ8FHÐ^~ÿSBÝ/çÏöDÖ%ôÖvÇ–°ž†à}&·5Ž�~>–A¾AÿU�ßG ›š�tª<‚Ù³`j­‘Â;(ò ±\‰‡Õ‹€´‹‚ªZI¼ ST7²¹¤YRÓþ‡ÍÁj|hçlñ©'KÞÛ{3‚£R:=ƒR©Ã{T±¯¬­Ã’:Köb]ñœƒUèX˜Œbšj)c£=þ V ÈÐåDó3:IçÔœ�f€6—Ãó�@àÌż-)MÞ¦ÓLO#M©«ìmȾ4««ù|¢¯4Å\Òrt"/´ çYÆýW&.�RµØnMŸ¤öUÄ©¦[«ƒ^1þEÂ�Ie`R¥õS3 r<ùÇE`­-Æ*ñXh ÝÖo‚þUZètC(Ø/ÜJlî“ôq>o#jÙ 2¥ ps‚Ø©¡Ql•×4uã8~zG”& ]S¿)I fyÏéd¡Wˆ­ZM_¼`ÊHÝn§á(Û—l4!W«ÐZò„CÞçõ�7HË·ÚÀ�æÁ$­ôK GNÄÅç‹¿C‚8-ݵ–\ EF…nú´äõ}Ç–«ÐˆŒ�$üþ¾¢VXø¡ ¡bÖÿ*/öp9)¢‰¬¦*/CÑ„ùÝÀ]ï*·ìJÚÈ NÇ`ÄFÙm¨H‚8BÜ@éŒT.èS!Oé—ÙŶåï‰rUMœ˜‹EÜ¡aCßú);$hb0t_!O–®¨vC3÷eRã˜ðr ªêoTÚ\ÖrÛŽ5Vß^˜-1'cа^7Æ:WðÇí†!ïêˆ�«¥ƒ,’tt£Æ[œ™ ^ËTyòÕœŸ‹|-W’0øa&ñ..`Èÿ/'‰ðÉç-›¿U”žœ®8 !zöÑTÚj–èzëW9·ñ¦ùøH·v9Ö4mÌ_¿{8ô»™ºä’�9æz„¯Ô1Ü+Ý7"¹oĪ¢þû3¯1ÎãQË¢„¹‹¯Þ›:áh‹Íi~Øódltòó-ù•ˆ=Ÿ)j®“®v·’aB5¥±­_§a±ÓÒêq(”û²Îô½ÂJGe¢#;­±Õ—=EÍ S{[KóRíƒ{`Xä¯öÝ‹l(@Õ~˜Ô«U µd`аÅs÷‰\ð2�Ìîs+‰s4E©nÃëÖ<š‡,¨ãÍÌAT¨ˆ´ÓB}àS9é• (E:\ºþœ£¬Žºÿ=õQœx�È¢1¼Åå ?CÚzNk�æAÊ#›gcƒBj{xÐö^Åô2køc��¼›’˜Þ~·áÄèaM¦Æ¨›ôÄA¤÷Ü`‰¿äAY9•óC!�ê4€w£ÒD·È¯3É¢›C±k6²K›l!¨¾ºbêüÓÄœzº²œ�œ‘®ö ¯ÒÒûi±¾ã¼·AKŽá ±mp×ÝÕ³˜b6÷£µàÛŠ3wÖð·ü5Òg¾uT𿈮fb�…@’FÓá7¸õ¡JVÁŸâ;/&f#¬�œä,˜f_"´z¬Ñå“8©ôRìí³Œ¿Èšìì<]Ï¡RÄe°4çÒ r0óò¾û@øsbÇÇìƒaBÂ{ᚊë±`Á�[¡¶¨¹úÃ×›™s•Î"|¢å¸ ¨1ʬŠˆTsYk§ô)}KQX©ÿknr£E{°Å&Á2Á}äÙ�Á,ÂÀí©�ËA}Hüq´tÎ…6ÖåB¨ŒsV�àœþ¦äÕJ€â››«o˜_;>‡_Ѧ+/õONIJÖH§Þ�ª;³Â‚•´ñ´kyúý5(•iIØ™¨;!= ×Q!ù±=åzW’ƒ[J¥�žŠ­(+Ië7D›vôj5}„Nÿôûš™ØYÞYñb™E�˜=�fÞØ÷ñ̯þì¦B®I¼ˆ�5¬ ÒF³t•¾RÞn£N¾àv gHà`&“°K2~ª8YûðÇ(Ä*óNbÅO<ÑÀ’¯N#n%$A$©œÕà�΢äaž�B†lQÏÄe¿¬4,4vm¬,�'�Ó&j’o—ñãÐ}iiÿÿÿüÇï| –Áÿ>o4È|kQ­aä�s׋]“Ñ3žÀTØÜ]2¯!K´Åã”±®F½�n©!pYn;7Ö{MÂèî¯ßÖ·Äòš-‘( h,¹+*°Àé?�Øi§bÿ䌵¹Ïþ€ÝEO­¿èìO޵ CúQ© ÌÐYdSÛchafa-1.18.2/tests/data/bad/libnsgif-lzw-oob.gif000066400000000000000000000015301517447374300213370ustar00rootroot00000000000000GIF87a ÷ÿ€€€€€€€ÌfÌÌf™ÌffÌf3ÌfÌ3ÿÌ3ÌÌ3™Ì3fÌ33Ì3ÌÿÌÌÌ™ÌfÌ3Ì™ÿÿ™ÿÌ™ÿ™™ÿf™ÿ3™ÿ™Ìÿ™Ì̙̤™Ìf™Ì3¹Ì™™ÿ™™Ì™™™™™f™™3™™™fÿ™fÌ™f™™ff™f3™f™3ÿ™3Ì™3™™3f™33™3™ÿ™Ì™™™f™3™@fÿÿfÿÌffÿ€€ÀÀÀÀÜÀ¦ÊðÿÿÌÿÿ™ÿÿfÿÿ3ÿÌÿÿÌÌÿÌ™ÿÌfÿÌ3ÿÌÿ™ÿÿ™Ìÿ™™ÿ™fÿ™3ÿ™ÿfÿÿfÌÿf™ÿffÿf3ÿfÿ3ÿÿ3Ìÿ3™ÿ3fÿ33ÿ3ÿÌÿ™ÿfÿ3ÌÿÿÌÿÌÌÿ™Ì£fÌÿfÌÿ3ÌÿÌÌÿÌÌÌîÌ™ÌÌfÌÌ3ÌÌÌ™ÿÌ™ÌÌ™™Ì™fÌ™3Ì™Ìÿ™fÿffÿ3fÿfÌÿfÌÌfÌ™fÌffÌ3fÌf®ÿf™Ìf™™f™ff™3f™ffÿffÌff™fffff3fff3ÿf3Ìf3™f3ff33f3fÿfÌf™fff3fì2ÿÿ3ÿÌ3ÿ™3ÿf3ÿ33ÿ3Ìÿ3ÌÌ3Ì™3Ìf3Ì33Ì3™ÿ3™Ì3™™3™f3™33™3fÿ3fÌ3f™3ff3f33f33ÿ33Ì33™33f333333ÿ3Ì3™3f333ÿÝÿ™ÿfÿ3 ÌÌ™ÌfÌ3Ì™ÿ™Ì™™™f™3™fÿfÌf™ffff 3ÿ3Ì3™3fB33Ì™f3Ý»ªˆwUD"Ý»ªˆwUd° Á&<Èd"‹‰PNG  ó IHDRQXø{˜aGþŒèòçQ‹ÿÿÿÿÿÿÿÿ!ù, q D"ÝÝÝUUUwwwwwwDDD"""wUf¹scLj9ÎÌ(ñ&J�chafa-1.18.2/tests/data/bad/libnsgif-uninitialized-frame-fields.gif000066400000000000000000000001071517447374300251510ustar00rootroot00000000000000GIF89aÝ€;;;;;;;;;;;;;;;ÿÿâ!þCrea�ed wth GMS,ÿD;chafa-1.18.2/tests/data/bad/lodepng-adam7-mystery-over-read.png000066400000000000000000000011051517447374300242030ustar00rootroot00000000000000‰PNG  IHDRçpcHgAMA±� üa…iCCPICC profile(‘}‘=HÃ@Å_SkE* qÈP�,ˆŠˆ“V¡B­ÐªƒÉ¥B“†$ÅÅQp-8ø±XupqÖÕÁU?@�œ]¤Äÿ%…±÷ãݽÇÝ;@¨™fµ�šn›ÉxLLgVÄà+Ú@¦Ñ'3˘•¤Zޝ{øøzåY­Ïý9ºÔ¬ÅŸH<à Ó&^'žÜ´ ÎûÄaV�Uâsâ“.HüÈuÅã7Îy—ž6SÉ9â0±˜ob¥‰YÁÔˆ'ˆ#ª¦S¾�öXå¼ÅY+–Yýžü…¡¬¾¼Äušƒˆc‹� BA(ÂF”V� IÚ�µð¸~‰\ ¹6ÀÈ1�4È®ü~wkåÆÇ¼¤P ¼8ÎÇÜjÇù>vœÚ à®ô†¿T¦>I¯4´Èн \\74e¸ÜúŸ Ù”]ÉOSÈå€÷3ú¦ Ð{ t®z½Õ÷qú¤¨«Ä pp ç){­Å»;š{û÷L½¿znrªº (£bKGEùC» pHYs.#.#x¥?vtIMEæ!ü¿õtEXtCommentCreated with GIMPW� IDAT×cø/ü&~�îIEND®B`‚chafa-1.18.2/tests/data/bad/lodepng-zero-length-literal.png000066400000000000000000000001671517447374300235150ustar00rootroot00000000000000‰PNG  IHDRãÿÿÿÿäãpcHgAMA±�úú iCCPICC profdle(‘ÿÿP,"�•“Vÿ™&63 ýz½Õ÷qúÿ¨«Äòchafa-1.18.2/tests/data/bad/lodepng-zlib-big-alloc.png000066400000000000000000000005411517447374300224100ustar00rootroot00000000000000‰PNG  IHDR000000000000(IDATx^ °fÖÿÿF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000IEND0000chafa-1.18.2/tests/data/bad/no-frame-data.gif000066400000000000000000000000161517447374300205640ustar00rootroot00000000000000GIF89aè‰ÿú¯è¤;chafa-1.18.2/tests/data/bad/pixops-normalize-signed-overflow.gif000066400000000000000000000001401517447374300245770ustar00rootroot00000000000000GIF89aíNreat,YâúßÿŒreatGIF89a)âF!þ&CbWWWWWWWWWWWWWWKWWWWWWWWWWWMP,F!þchafa-1.18.2/tests/data/bad/smolscale-unaligned-1.xwd000066400000000000000000000005651517447374300223030ustar00rootroot00000000000000gþÿA  ÿÿÿÿÿôÿð@@‰QNG çpcHgAMV±� ÿV±� ÿ…iCC;ICC prÃ@Å`SkEd H<Ãø±XupqÖÕÁU?@�œ]¤Àÿü�¡¬¾¼Äušƒˆc;@¨™fµ�šn›ÉxLLgVÏà+Ú@¦Ñ'3˘•¤ZŽøøzåY­Ïý9ºÔ¬ÅŸ¼¼¼¼¼¼¼¼…iCCPICC Uýsâ“.HüÈuÅã7ª¦S¶�öXå¯ÅY–Yýž>…±÷ãݽÇÝ‹� BA(ÂF”V� IÚ�µð¸~‰\ ¹6ÀÈ1�4ȼ¼…iCCPICC Uýs⮀wkåchafa-1.18.2/tests/data/bad/smolscale-unaligned-2.xwd000066400000000000000000000012651517447374300223020ustar00rootroot00000000000000   ÿÿûûûˆD™L™™, òDˆÌDDDDˆD̈ˆD®ˆˆÌÌÌD̈ÌÌÝÝU™L™™“ÝÝÝIÝ“Ÿîî"""fªîfffUªOUªªžîîîOÿUÿªÿÿ333w»ÿwww]»Uÿ»»]»»ªÿÿDDDˆDÝ“ÝÝÝÝÝDDÌDˆDˆDDˆˆDˆÌDÌDÌDD̈DÌÌDUUUL™IÝUUUUULL™IIÝL™L™LL™™OîOîOÏîžUÿª]]»»UªÿUÿUÿUˆˆˆÌˆDˆDDˆDˆˆD̈!fdUÖ¡@„ˆˆÌ̈ˆD™L™™“Ý™L™™L™™™““Ý“ÝUªžOIF89aÿDžîOžîžžîîªÿÿ»»]»»ªÿ»]»]]»]»ªUÿ»»»»]»»»ªªÿªÿGIF89aHHHHHHHHHHH€€,9ÁÄÂA(î2ðÙ+EÌÌÌÌDÌÌdÌÌÌÌÌD̈ݓÝÝÝIÝIIøI“ÝIÝݓݓIÝ““Ý“ÝÝÝÝÝIÝ“ÝÝ݈̼ùóèÓ«_ÏÌD̈ÌÌªªªªªªªªªªªªªªîîîîÿÿ#Uÿªÿchafa-1.18.2/tests/data/bad/smolscale-unaligned-3.xwd000066400000000000000000000011711517447374300222770ustar00rootroot00000000000000   ™ÿÿûûûø‡D™L™™, òDˆÌDDDDˆD̈ˆD®ˆˆÌÌÌD̈ÌÌÝÝU™L™™“ÝÝÝIÝ“Ÿîî""fªîfffUªOîªc‹� BAîîîOÿUÿªÿÿì33w»ÿwww]»Uÿ»»]»»ÿÿDDDˆDÝ“ÝÝÝÝÝDDÌDˆDˆ&DˆˆDˆÌDÌDÌDD̈DÌÌD™LL™™OîOîOÏîžUÿº]]»»UªÿUÿUÿUˆˆˆÌˆDˆDDˆDˆˆD̈!fdUÖ¡@„ˆˆÌ̈ˆD™L™™“Ý™L™™L™™™““Ý“ÝUŸžOªªIF89aÿDžîOžîžžî]»»ªÿ»]»]]»]»ªUÿ»»»»]»»»ªªÿªÿGIF89aHHHHHHHHHHH€€,9ÁÄÂA(î2ðÙ+UUÌÌDÌÌdÌÌÌÌÌD̈ݓÝÝÝIÝIIøI“ÝIÝݓݓIÝ““̈ÌÌªªªªªªªªªªªªªªîîîîÿÿ#Uÿªÿchafa-1.18.2/tests/data/bad/smolscale-unaligned-4.xwd000066400000000000000000000012651517447374300223040ustar00rootroot00000000000000Ý“  ÿÿûûûˆD™L™™, òDˆÌDDDDˆD̈ˆD®ˆˆÌÌÌD̈ÌÌÝÝU™L™™“ÝÝÝI Ÿîî"""fªîfffUªOUªªžîîîOÿUÿªÿÿ333w»ÿwww]»Uÿ»»]»»ªÿÿDDDˆDÝ“ÝÝÝÝÝDDÌDˆDˆDDˆˆDˆÌDÌDÌDD̈DÌÌDUUUL™IÝUUUUULL™IIÝL™L™LL™™OîOîOÏîžUÿª]]»»UªÿUÿUÿUˆˆˆÌˆDˆDDˆDˆˆD̈!fdUÖ¡@„ˆˆÌ̈ˆD™L™™“Ý™L™™L™™™““Ý“ÝUªžOIF89aÿDžîOžîžžîîªÿÿ»»]»»ªÿ»]»]]»]»ªUÿ»»»»]»»»ªªÿªÿGIF89aHHHHHHHHHHH€€,9ÁÄÂA(î2ðÙ+EÌÌÌÌDÌÌdÌÌÌÌÌD̈ݓÝÝÝIÝIIøI“ÝIÝݓݓIÝ““Ý“ÝÝÝÝÝIÝ“ÝÝ݈̼ùóèÓ«_ÏÌD̈ÌÌªªªªªªªªªªªªªªîîîîÿÿ#Uÿªÿchafa-1.18.2/tests/data/good/000077500000000000000000000000001517447374300156675ustar00rootroot00000000000000chafa-1.18.2/tests/data/good/Makefile.am000066400000000000000000000006041517447374300177230ustar00rootroot00000000000000EXTRA_DIST = \ anim-local-cmaps.gif \ anim.gif \ card-32c-alpha.png \ card-32c-noalpha.png \ card-full-alpha.png \ card-full-noalpha.png \ noise-32x32-indexed.png \ noise-32x32.gif \ noise-32x32.png \ noise-32x32.xwd \ pixel.avif \ pixel.gif \ pixel.heif \ pixel.jpeg \ pixel.jxl \ pixel.png \ pixel.qoi \ pixel.svg \ pixel.tiff \ pixel.webp \ pixel.xwd \ taxic.jpg chafa-1.18.2/tests/data/good/anim-local-cmaps.gif000066400000000000000000000070501517447374300214750ustar00rootroot00000000000000GIF89a ÷þÈŸ¹“~ÿJKÿX®†ÞÏÿÿœ‰àÿÿ&žÿnIÅz³ÇõÔÏýhÿ‰ÿ»ÿÓÿåÿÿ­7×B{ÿƒº©•ÿUÒÔuº©ÿ´ñ.¼äßþöÿæµ–·»ÿöÿÿíÁðÿõþáöÿÿÿ–ùÿÿ,6nuwލ³µ¶ºÎÑÖ×ÙNÿ[ÿry4ÿu„‹Œ’”yu™œ¦ª¬­�¸rÿ¾|öÀÂÅÇÉ–¾‹ÿÑ‘ÿÞšÿãéÅžÁ±ôõ¿ñÂüTÿ>ÿ@ÿAÙÜ÷qÕÿÞêçÙÿ�ãÿÿ¥ÿ·ÿ¹VnÿÀÿÅðÿòÿÿÔj@ ÿèÿîÿøgjUýz£I|jÿlÿoêƒvÈ´XŽ@šœÿMÿQ¢ÿUž^ÿ¨­²ÿPðµ¹nÿÀÿtš~ÿ¥‚Æ¿Ÿ–´ÿS°ÿuEÚ‡ÆÓÿŒÝŠ©°ÒááiÅ­íî1ÎÎðàÊôùíŽù­Ü«‘ìÜø±ÿ»ÑÆ'äÅzæÿ½ýÀÿ¹ÿ½ÿ¾ÕÍÿÎÿÓžáÿöÿÿvñÿ¿�cÿfÿÿ¾×gÿ6vÿœæñ°êþÿëïçÿéÿÅÿÙÿëÿìÿ�ýÿ“ýÿ§ÿÿªþ&/<YQi ^‚t’¼Ï8ßA±Q&´T8�RT!ÿ NETSCAPE2.0!þCreated with GIMP!ù2ÿ, ‡&<‚Ÿ¼ÏßY’±-56ÿ=R?‚AÈILøMÄRkU’XhZ_‰bMgªh)lyÓ{o•�ƒÌ‰nŽ”‘›££¥”¥Á¦T¨F®¡¯±ø·†¹ÁÌÄǯΈØÿÚåó‰ûþÈÿ‚ÿ×ÿþ޶/`º‰XМitXñQ ^ eŠ O­ Ñâ x �{¤ÿÿê˜ü&´'……+÷+K3hî5u7:Ø88�=sÔ@ÂAGéGÍL#ÿL+ O¶QQRTTT“TŒTÞVýY…¹ZT[«[‘w[¡\k]½^nc¾~d[ðfzhD"hëdjkômnoÉp½îq”qZËr*tBêvvmv«¶x]‘y§{J�}>€=ƒ€†�χO؈¹ŠŠÛаžŠô¡�½�R�*��c�z“‡“«Å—Gï—ZˆšWœDœ“ž™ž¶Ÿû ¡È£µÿ¥…¥ªÒ§€k¨«©ˆÆ©àªÿg«­T¯A€°sx²¨ô³Ê³Êk¶£¶ì¶ÉQ·z··ÃĹ¹‘¹¡Mº›»K»¹¾S¾ª”¿­ÀâÀ�Á&’ÁJIÃÊÃÃÍÈÄtÄÅ£¼ÈÚËœcÌtÍ,ÏвÐbÑ®ÛÓ(Ô�ÕÅÕ8Õg�Õ˜Õæ×kÜ…þÝÝ>Ý‹�ßS0ßêsáfâ8â‹\ã\å~éãéºëÙuì±íÃðTòòŒôû÷|÷Àù5úâû,ûÕEü‡þþþÿÃÿ¨ÿOÿs|  (Ô·ßz8»¤À"3B­s�îÈ|2ð�±È�žr/šXÐÇÊ�a-@½˜&ë D]`ä]ªlMä‰H �^°¶¬°9€À—d?¨e+‚ ¥FŒKq¢#ž …ÐdŸ5"dà€RwÖÌ(å š(äÊ0à‰W¸úø� � Wƒjè²äèuèÌŒQý°5‘ÀLX-H,8@€2Òî¹ø$lE‡4V:¸‚@°-•¶0zñÄ /¢ð™È—K»à½¡Ñ Œ�Ò„@ É |!Ë—Ë6 ß P¤…“2d²œsDA+2aÿ^ó Þ1N°á³ŒW�b—Æ¥·×4p‰'¨qmÜ#$ˆb«´€@']Ìp \ Ç.¸3H@ À 7´¡4P@Àq PðKdJ2tÀ¡»d .°Db€ ”ò)„@#6°!MìðBÄà0Ë%…P°K9ðÔ“ $ø  æì@=zܰ‚ ®@"Å}ì€�d|C ܈W†3–  Ó˜bˆ&^\B ï` Ç%Òè`ꩨ¦ªêª¬¶êê«°Æÿ*무Öjë­¸æªë©x�Œ¤, 0”0W$P˜$àÆ”¸,ò�'³$B3%ü�DÀ@‚»p‰taä#ÃÚ|øƒ:2HGØñÅA7ÐÀ†…)€€A(E"|²AsP±‡ؤ0eä!M-ø¡ÁE pI>6(ðŽ1øp± <¨rËYkŒ’H‡ €Œ7ÒDÜMè( Ä7Í4TÂ&u¸BÅ\2àD,F€ã&{43¤°‹$HƒJ2@¿$S@P4r —´ÀNò°Á$æ@ƺ¶Î%¶Ä¡6Ì¡ˆ ï €—5¡Šq@]ÀM{Tx +Š<²E;€9xËB<—€2Æ »ì#HJYŽ0 0Ñœ�Î âð@A˜Ë0Àö„C>J5q !zäð�2lâ VP²„"z À´0qF@!ù2ÿ, ÿY ¸¡Å ¤u €%0.Ðx¡„„@,þ`áhÏ“NÃ>U� nºŒ-KÔ €E!,l °M˜ˆ­¢HÓ $Tk²@6ÐÇ ¥F`P‘"Ü£®´…²¥ÄÏœg�XH¸@4³²Eó€&�@"Ø5 É22ä—p2 L¸°áÈ+^̸±ãÇ�#KžL¹²åÅX"’ŒË eÆl“äF²-(”8ñàµ2:LaQ‹…8Ò$�aFi‹½n9``I‡jà0U1kbbA©J²kßν»÷ïà˯O¾¼ùóèÓ«_Ͼ½û÷ðãËŸ^´ LL•£�,_à‚ˆ  À¼ÂB)�ä6�c!ÇH³Ñ4XЂÀ.}ø€4<äA@ 8p@â †7Y�r„€ƒ3,ð’Š0tÑŒ!V¼Ñ�'Oà ¸À7ÔK,´"M$œ<ÅÂdЊ4(•‰ ªDÁ‚°ƒ +HÇ$W@€Œ# !ù2ÿ, …žŸÿJKX®{ÿƒº†Þ©•©ÿ´ñºÏÿßþäööÿþÈÿÿí&.¼IÅnz³~ÿ‰à“­7·»ÿÁðÿÇõÔÏÔu×Báöÿæµ–õþùÿÿýhÿÿ‰ÿ»ÿÓÿåÿÿÿUÒÿœÿÿÿÿ–ÿÿÿ‚ÀšpX³Œh“‚È&D.À`Õl1$Re^X�Ô%¢Îèò�Vרg÷.‡£êt·Ïæ·Õ0' r%)/&r��Ž��’“•‘n“”™š—›jšž¢œ–¥˜ �§Ÿe2 r3r ³n ! LA!ù2ÿ,…JKX®†ÞÏÿþÈ8úÄ~ÿ‰à‹ß¯“©ËŸµÁ—Ç�šÞ�míò^Hòaù@ú9û1%û5'þþÿÿÿ@@ÿKKÿhhÿ„„ÿŒŒÿ��ÿœÿ¯¯ÿ°°ÿ½½ÿÄÄÿÐÐÿßßÿììÿððÿóóÿûûÿÿÿÿÿ�ÀŒpH,‰¦£r™1ŸÄtÚ™B7Ö§&ËÜr•Øï±*6JËE'¹&¦ÚBO ž)ÍÛÕ}=jíË(~m$~_ +†h'†‡V ��P ”_˜™�\ £šV £¤ŸP$©ª‹L#‚°±ƒJ%z~!”)”- ,”A;chafa-1.18.2/tests/data/good/anim.gif000066400000000000000000000046171517447374300173120ustar00rootroot00000000000000GIF89a ÷þÈ�gªKÿÿÿÿÿÿzæ~ÿÿœ†ÞJÏÿõþÿÿÿ«Ÿj¹ÿååÑz³ü‡Ôu©•©ÿIÅÕÅ޶ßþÿêÿÿÿô¿ñÿ·ýÿ§ÿUÒ÷qæµ–·»ÿ.¼Áðÿ´ñáöÿ{ÿòÿMþÞ�mÿ@@ÿuEÿððÿŒŒµÁ—ÿ¯¯ÿÄÄòaÿÐЋ߯ÿßßÇ�šþþ±Ž¹Ä£Ýû¼Ãv�’tQ&šÿÚ×vÈÅž[¡Å­Výkô™ãgyuVnÿÓÎ<3hîl»KŠ©°Ð²ÿ½N–¾žáÿ¨éºÿÅ Ñâ1ÎÎíŽçÙ©ˆÆYßÏÏZ‚@œ“·z x 5+÷�z8”‘¨«¯O¶òŒ_‰ÈÚ'……·†Iǯå~ðTy§ŠŠÛ¥ÁGÍšW§€kivm5uq”ž¶±ø>¦TmnfzМ¹¡M³Êk×k³Ê¶ì¨FTÞQtBêÅ£¼ÃÍÈ¡ÈY…¹ÎˆûÕE¹‘Õg�Õæp½îì±ÿ‚ëÙu“«ÅÃÊx]‘ã\®¡²¨ôÜ…þªÿgßês—ZˆÑ®Û¶ÉQhëdŠô¡¥ªÒ‡OØËœc—GïÝ‹�·¾ª”Õ˜c¾~qZ˘ü£µÿÅ¢ø±²gÿ6ÕÍÝjÿ¿zÿÿª¹nÿìÜÿ�ÑÙÿU„n£IáiTÿëÿlÿÿÎòÿ­ù­š~ÿÿëðÿÿPðÙܰêþÿ¿�ÿ¾×ÅÿÙŸ–Õÿìÿ�ïçÿœæñÞêàÊãÿ!ÿ NETSCAPE2.0!þCreated with GIMP!ù2ÿ, ÿ‘�‚‡Ð:G $0!§�ÙÚäH � E2(ÂéÑ„-‹ú Ð�…+…ö,2ÃK@Fˆ4U à$F¥ }QiÂh:¥a¡3'€ %P T L¥Nª‘dÄ×'”Ê0Ù(ÃPwŠÐá`M?ŸN5b!À“£ÞÖ¡+Yž kŒHh¢ìO0G˜�„‚4§Qú(j‚Ê ŸBC@ fU;¯6iYfjL&@c¸€ˆ ‚º,â '€M,‘ZÊe"‡ ¹EG ;˜äñ3Ç£¡pÍh"†—#Ià™‚ì�!C˜tE’0§¨©@—OEÿ8DFJ#X<ñ�5 Š€_çSàs&ÖFF ¿¿ÿÿ(à€h†ÇxñE\ʼn(%JTÌPÇaÄtÐÊ+¡0„&Rˆ!G!sCE#bl€ˆž ±É#K EB,aA+Bh€�H$ñÉž ÜÈJ\ò ¥r|DRG'°ƒyL@R`a&´H°È$‰ÀAŠe$AćTPIC|€34d@X`J` Ôr*†AA!²€÷ÄBtXf4¹ì¡‡HÃ` †*ꨤ–jꩨ¦ªêª¬¶êê«°Æÿ*무†Ú�uøÁP0Hu@™"ÒÄPòÁÉ”�¢ª ’É€BÁˆQ‡ÑM2CµÄÒ!lQ†^�Š Yà JBì(%A.h1Àz‘…Hr†[ÃØAH³p!ˆ%s0ƒBÄ0Ówò!œuJx$A.½Ø�ð(8""G¨ÒÐ ·4�ÀÆ •8qÄ#�dÑGJøáæCØQ s@’Çd(‘_A�…ÐòÇ! ðŒˆH qǯ­Ù"@)V€zà1H 8‚%–2�yÈòG  ÆÂFÌK ×îâ€{ ±m¤‚„R0IÄ\a‡qX ËIô±xyd2oÌ TU\2Š RÄ-TPHà1A}‹âÆ!ù2ÿ, ÿEA^� Œ " ™!<œ€`ƃ6"LQΛ¸pÓŒP å�ˆw$زOI€1J  ¡€ ÒÎpÃEFŠ#`yà$À“Pˆó›¥P¤aAŸ6 øQ»òÀD�/ÚD< ^€#eªAÈ·%À’&x _=!#P\÷­Ý9t L¸°áÈ+^̸±ãÇ�#KžL¹²åŬT˜ ¼i¢ÍKCÆ™*:PpÀ½FaNÄ–ÒEÀC–HH¨âvÄ…Tx!ÇZµh ¦§%Zسkßν»÷ïàË«O¾¼ùóèÓ«_Ͼ½û÷ðãËïDM’%6R `æš%$TÀ€,Ð@Eˆ��6oPMÛ\°l„@nàÏpAý€À�À Dã@Ü qÀ�£Ž$dÓÍDX3�1ŒàÎSDÀB+`Ï5H1‚6@€�4O‰ D°AJIÓÆ=³m€�-p@Â%ˆ�BàÅD]!ù2ÿ, �@ƒphyNŒÈ~J¨€¤ÐlJQ)�¥Ê d&�‡†Kt˜Ïäá�6¬Ím÷;þvÐçíú}½g§G*.q/qŽ���Ž‘’”�m’“˜™–ši™�¡›•¤—Ÿœ¦žd  …m q,+²i"-$LA!ù2ÿ,Ž€‚ƒ„…†„=‡Š‹:Œ�„8�“6“�5–™š›™˜œ†•Ÿ…’¢„Ž¥ƒ‰¨‚7«8®;±¨57´¥:¸Ÿ¶»¨³¿¢°»¼šÛÜØ—;ááÝ‹5:·æâÅ‹8;·»  Ï3ü2<1@ ÌS&Á€< ;chafa-1.18.2/tests/data/good/card-32c-alpha.png000066400000000000000000000441301517447374300207600ustar00rootroot00000000000000‰PNG  IHDRL;g_õcPLTEf50(ó33/¯ýp+‡ÿ”ÿûNPMufknm}€D•ƒ-Ÿk|ü€†Ñ¿‡/”�“èt殚 §œDË|Ÿ¤{ÔŽÇi¹¡«©ªîöôÍÍÏîêçåçÿÿÿo�âÂtRNS@æØftIMEæ" 7×è] IDATxÚíÝ ƒ›¨Þ°ñf=OŸudÚYÚiZÎañûÊÔd’LEP@/v;3‰ŠFå—?/ê—F™Ö'ùͽl2»^=‰´ÔY9+õå7»ŸD"Eé‹Ye5|¯“8#¶| Ü2_ì/å™´iµV!IëÖ„å ÂsP60 Ü»#ÂsØÆ®ÔìÊô;"BœSs>†î1±EJz%å>¯ IvÕ³s¢ËAYeØFØO˜ƒ ÎaØ"$‡ð’ƒv¥ Þ•jæúEwJ„œSv„Èæœ’Æ„Oßá¾OzL|Wf[àç ÏÁx¼Óƒs>ðQv¥H¿+ÃK@hB›ðs*4Ù¶2ƒ‘ଜ‹‰.9ˆt% ü[D˜ôØ]iÒc\†D„2”�ª*LŒÑëïÊÙ˜D9ð’«„æW 0ù8+“ŭЉÞÄ�Ï#$ Þ™ìJU>&"‚Ë›8§VÆ$ÁÖ‚IÖ»LÀL¼0“¢1`²)—ÁLÀ$ƒoˆLÀäjW‚ÉÚLæa"˜€I4L ‘ɦ01æjôé¤áÓ `"ÀLh3)“þ² Ý]åÓ'3¤GWtõé4÷é 6žžÈd¯m&`²‰ÈD ‚„^­ÛÁ3¸&`&;¤#äYð‹éX“]a"Àd˜t%»¿°Ö1²ˆ!�L‘Ã%½ý¦ 00)“®4«¡1dí»ìœM!20)“S0bÒÝÆlh¯U`&`RÚ�§ûGuÑH6÷|¤€ ˜€Iêïªá̹CŠºmB0“Ì0éîjr¿5óç LÀL2´Ö7�s ôkQ &`’>21ÅAò9BQ`&`’xGt�%(’ R¬(ݘ€ ˜$Ûî¹9y~UèÕ=`&`2ûÌUE$÷QB®î0“¹1ɧÙy&`&kíµIH>šPfy&`&Â’MUn¢�&)1á°åa¢vÉE˜l?2“˜¨Ir¾äXí“¶ÈÛ6‚IA˜¨wD+³Avª'`&`2žC×Û,Ÿ(0¡š&á;Bí2&ù4LˆLÀ$hG ÉÔ(`&`"žHb�dj‡1˜€ ˜ˆ' %riÉSNÀLæ¶-ßIQ½yRÝÙ4&"_Lærá~&2Æ…~0ù&»¨æø^ˆ‰Ë"QéÿüYÖÂdÞ3‹Ád>&LÖÇÄÿ2FyÎÃ’°í�žã®´ò9�&ç²ñ–“W0)“97+‘QÊs”¬Š‰ÏN†˜$i3)“ï�±\y˜Ì»šoS˜„lˆ?&Æïº=0)“_ÛÁdѨä>&Ó‹i"Lž~žõ0鮺óh:0)“€»1Êé5LF?Òj˜tœL®ìl “×ý4Àþ m3)¬šrcWð­Ÿ“‡›“Ÿal`²ÏÞœ¢"“°{D—‹ÉÃ)ëbâ8Q+a¢2éfÐÚ61Q�÷á�>ˆ6gLÎÓÖÆdbǘì52É"$�€Ið£+À$&“80ɹÍ$ÂSpÀ$ &îv&`’1&1î4(§Kò©¨‚ÉU NÀL²Å$ÎÃù¼1ióÅÄM^sœ‰_]LÀ$Ó6“XÏù”Sa(“CJLžs&`’%&ñ\&Ñ.^“{�<0I�‰xT͉ùL-9†±6“9cQ'.âÝœã»i‡>NÀL²ÃDÅ|Ò§&‡Û‰WËÌÚ>q‘Í9þ—Ëh»ô'`&™a¢â>4XTY&`ÒF¸‘@» &íR˜´žä&`’“¥-“%0¹œ€ ˜ä„IlJÀdLÚ{Ï(0ɨ7'¾%‘0‰XÄï,„ÉÔ"cr'80É“(Y“ç·B™´Ì\K<’ÑwímË ˜€I.˜,bI\L¦0›„ÄgâqYQ|Lnƒ0“<0Y†’¸˜Lè66eúˆ¯-Ÿ²&7š€ ˜$Åä´‡©�Éj˜\߆Måð¬a0Ù{d²TXŸ²|g<í˜<\ÍJ˜\u뙀IJLúQ-FIîê&`’:2Y0,‰9ÎLÆšNÀLc²(%ÙaÒ®„I»&&C/±¦ÍLRVsÔ–€É*˜ô�&&2“„ÃéëÄI�ÉÌ�³ó`“ Z»Nö{LÀ$!&˧D˜Ì…?³k8=&Æ€ ˜$ÃDµ`²L:Ph3“˜(o“vLÚÜ0Q`&ëc²xËk2LÂî'0};=W³&¡š€ ˜dlÉê˜\iìµ�Þ«Y“{·90Y“å{qaâqUp&þÙ¬ƒÉ´Çƒ ˜DÃd=KrÃä°&‡T˜Œ>øLÀ$"&ë´¼ÎÀ¤}vwz0™šTuÀL<ÏÓæ‰É§É`²rULÀijŠÓ‚ɶ1™Ý«&`’c/Ž7&O{fÀd•^0�}¶2%`’“yš€ ˜x4—$ÃdìNGmL¦¯&Þ8“¬º†ƒzuÀL2m.yŒÉıd Z[¹áLÀ$Óæ0I‹‰ULÀ$cK>0™q)ïÌ ýVº6ç�=&Þš€ ˜ä7ºä# �òÇUÉNÀL2m.¹ƒÉa%Lvz?“PMÀL&XÒ¶ùcò¸¬Ž–æx˜LYiI˜´F)0“h˜¤ªâ€I˜ø4œ€ ˜Œ[brÁäqù{\ZÇ‹óœrîÿ�¾CÐjd:Ð5˜€IL’Zò“½¦„˜Ln8“"1y[ Õ&M`’&S5“R1‘«`¢ ˜€ÉÄѰ»ÅD–�‰Y%2Ip1ΓAk`’\“''�ˆƒ‰):2ÑJ)¦%»˜P:L”œºÕw“îƒ×‡ŸÓNÉÀCd’&®Sçy¹°?õðÕ<û¤t tY`âY¸ºáá_º½ä™2‰LtX2cŸ<$(’u$6Õ©1i»‡þžSNË,"“Ö{»‡ÈdÆYŸ&á§ÆØW‘h“ì¦ÄXû®­Ím$‰ðqƒ*ðxºï_3òÕá¬L�É«ÃdNêª9þe™¨ ï€Ÿü”©uø×éM-�mH±‚¼ªV6�œS*4`Î!21s#[?~õ£lÚLBMT_¿}Pw"Jíb“JPÈ×J*üxVÍó�gçÔ.ÚL”À¹…®aõô“DZd“CC!/©c¬jî÷èˆ�u Ë5»†¿ß5ü“UœI˜Ô"“²zÙ�&KŽ31Œ3Y“·…#«e<2“†ìTµ`И|:ljiKÀd{˜�5a8=Ãé³L¶ˆÉcMÀL³L6‰É¡0ÁDÄl{“íbRÕ`&㘈¨£×Ád“˜<ŠMÀLªã€Év1¹¯ ˜x?·lØD¶L6‹É]MÀ„Èd1KÀd»˜ÜëÓaœ ˜œRýj0Ù.&w4!2á†Ò‹Y&[ÆäóÐz0“Á’né&[Æä“&`&]ª`&aš€ ˜,f ˜l“C%.ïH&`²˜%`²uLœ&`&ço3Zê®Í`²uL®b0Ù/&ê„Is8€ ˜÷ƒÉÞ1Kô ƒÉn0¹ÐLv_ÍYÎ0Ù&í&`²oLDü1ô`²3LΚ€ÉÎ#“%-“}`rºêLv™,úôM0Ù&'MÀdטÔ0“ðÔ™ì“þQËZ&»Á¤ªíÙ¤ ˜ì“þñ  [&»Á¤»L‡Èd·‘‰QK[&ûÁÄué¨wÙ“ÛLÌ▀Ɏ0±š™ì-`&15¡7g¯m&ª0‰ÛA¬©æì22iš˜€IÜ$˜ì12Y!.“½ar� Lv‡É:–€ÉÞ09&;Ãd%KÀdw˜&{ÂDÈú&`²Ðà5&{ŠLÖ²Lö‡I &`R&ÍLÀdÑ�õ`²LÖ³LöˆÉõëÁd˘¬Õø &{Åätw0)“·ù˜¬h ˜ì“MÀ¤$LꘀÉâš(0Ù>&«Z&{ŤjÔ|LÞÀ¤LTS� ˜¬Ò«ÀdÛ˜ˆu-“Ýbr¨ç]¦&Å`²²%`²_Lf6‚I)˜¬m ˜ì“yc×À¤LꘀIÞš€I˜ˆæ&`²j#,˜l!*0“Ü›MÀ$L„La ˜ì“C#˜l/2õLÀdýf&›Ã$‰%`²sL•“ÍaÒT`&)4¡š³9LÒX&»ÇäPûUtÀ${LÒTrÀL\#,˜l “T–€ ˜xŽ6)Y:&YÞ§LÀäs³‰GÑ4cbü1‘º0LD&¤Ö¨Tg�O³ILÞÂ0y�…‰I™¼…í0cò¯ä€IV)&>Í&6€ *oÁ˜¬WÍñ0™³Ïú…ì5“t•0ß±k=&ÃY>/%m3QÊ]¹21u‘X8&ò-(ٰʨþŠ›±Ím*0!¥ÅÄ]¤#&�®¶º ˆµ$ºí0ÑZ)=9Ùy#`òÇæôö¦Õ›öÛQvõÊýÒÚm÷„­Õ*a%ÇbbÌÓÓ»>­M¼f�…Z6a‰é΃ªVºÿo,™Ö�ãɯ|t‹üùŒ‰Ñ"t?Lf¤pL> ™éÒBç¶Ñ¢:T>Éó$yžjqñMõ¡êAÒ>Iù%¿¼å‚y«Õò«ïV ž'uc™0+¡¬Ã1™•¾t¥Y¿މ£ÏhßõI÷úLšÕZR7bò¢®=O’GyŸ¢Úæ"U~_f�GªóÉ»É%ïÊÿPŠ m†î_í›·TÚL*hî ÐÌN®Pµ&Fdâ·]tÝ·™H¯ ’ŠÐ5Üjé·ÒÛmP­k3Oòè'Ùƒ^{å<ç \(oGÑÔ¬=[™›é[=Çh¹‚<5ûÚ3oŸ´dÞþ‡²ƒjJ›‰�E@r#7b´™Ÿò©ôÌAk2&IMg"º^áåÏ’eòörʳ=À+o_LD“G�¯³9”õôØØ´*¬d‡Ék(&r�®áakËÀ¤¯%gƒ‰Ü&0y™LéÅÄÄÀ¤¤áô+E&Õ:gÉTL`’q5G.xšÈ1ÑûÃD„í±)˜ gS6˜ˆ1iÀL¶�ɤȤ>ˆLÀ$L&q“o`“Ó“íTs| ¼“˜ˆMVsÎÇLÀdO˜0‰ŽIs0É A5§HL>7˜Ü+ð`’±ùÈd‹˜\m0Y“FÀf‰ÉèioŠg"6�Is“}cÒ€ ˜DÁäò`ƒ ˜äƒ‰“Ò0©`&Yb"À¤,Lš˜€ ˜€I8&ׇºTL˜l&å`r{†‚ ˜DÇÄo—®ó“r"“æ&`&`!2©ÀLÀL"`RÀLrÆD€I!˜|âLÀ$3L˜”�I}0É&%`òù`&`&þ˜ÜÁLÀ$;L˜ä�Is00 ÇDÀLJÀD€Iî˜T`&e`"À$oL00“˜Ü—LÀ$GL˜ä‹É£ûô� ˜d‰‰“|#“€ ˜€ ˜øE&ÕLÀ¤ L˜äŠIs00™�‰˜˜€ ˜äЉ“<1iÀLÀLÂ1-0É&9bRÀLŠÃD€I~˜<LÀLÀL<0©`&b"À$7Lž&`&`&Ó1©`&Eb"À$¯Ak ˜€É§Ý]&L²Â¤:€ ˜€ ˜„cÒ€ ˜€ ˜DÀdäŒ0É&ù`RÀL ÆD€I.˜Œ•00“I˜Ô0“¢1`’&£ÅLÀL¶ŠÉ·˜31000™2v¼ôƒ ˜€ ˜LÀ¤0)“NÀ$& ?˜€ ˜€É8& ˜€É0`’“‰� ˜€ ˜€É8& ˜dˆ‰GZ°À†‰(Y2&²ÇdRÑ0“µ0+cò+&õ¡$LD™˜4…b" ÃD™¤ÄdZÉ“}F&`²LL LšC&˜4Kä½,&�K`’&m˜˜˜˜‚#=µp.ŽI³LÞKbÒˆž“Ò0ÆDf„‰^ ©Óc¢Ü8“¦:”SÍi²Ãdr“ ‘É:‘‰Øa5' &F…F&íDK–Ƥiž×.]d„Éôôê‹É’=.Û�Ld�‰ ÆÄÏpLäLL´òIRé(˜tku!Ƽ¤=09žÒËËq4½x�€õëkWÜ^'”ÉWQW‹ñâ“÷Ëëñøúj|Ùݹå…Éׯ¿}Rý5&çïå‹×^»{YLÞ&%'�éËãì‚áŠF„6í_;Lü’q?Â1‰�ŽõK5!½¼¼û¤Iyž’µÄ#ýy­ëéy �Žð0Bç6�Þî&½LMç…GO,7Ç«Ýê¯ÓÓ�öÿ©iz¶v—ü'm²öõ…þû÷ï_ýÒ÷a±Oéâm7‹2&BÉÇdVúröaeLìN ÜmG[òÿ]2½ÿúóçÏÿ'·»þ;%�öíølÿõJîp5âÌÃß#8üý÷ßîßät3ó�ìú÷þ¿Mÿ/yúúײéë›îÊ…1óP–Š‚‰ñ¡¡+Î}5dzz§ÍDÍly=5À.L‰MvKÿ—&ÿMœ~};ZLþN›ö�É__¿£UX×D¤jޝ 6À˜�Ë[’ &ÿMž~ý;=&ÿÙ&}5&‹XURoŽÛa“Ád=LR&�&»Àä-‘´7§ÀAk«X&gL¾æ€É."“¿ÞtãLfab’a¢É•0“˜|ïzˆKN_hdr0“%«9;Âäýý'˜€É1 Ö„›#嘀 ˜$Àä/0Y“Ÿ`&Åä;˜¬‡ÉZ� ˜€ILÞÀdEL~‚ ˜l“@M¸;}†Í¯`&`²qLV«å€ ˜$Á$L0ɱ–&`&›ÆD­˜€ ˜¤Á¤ïÐ9‚ÉÒƒÖÖ LÀL’aòFd²&ÿ‚ ˜l“�±&`’Û5~`&`²uLV¬å€ ˜¤Ãä L–Çd½ÀLÀ$&¡ ˜x`òLÀd˜¼�ɘ¬6úLÀL6�É¿`&›Çd¾&`’c-LÀL¶‹Éª� ˜€I:Lþ“Å1ù &ëcò &ëcòLÀLÀ$e=L²J&`’“¿ÀdYLÞÁLö‚Éw0Yq\·–&`’“70Y“u0“”˜ü&Ëar0Ù&óB0ɰÅLÀL6ŠÉLÀdW˜Ìk‚“Ìîd&`’&o`²&Ç•™€ ˜€Éf1y0Ù&³ê9`2)00Ù&o`² &?ÁLö…Éw0Y“Õ0“Ä˜Ì MÀ$þ00Ù&&ë&`&`²ALŽ`&;ÄdF˜äXË0É“70‰�É;˜€ ˜€ILþ0Ù&�IlL˜€É>1ù&ñ1ù &`²KLÞÀ$*&I0“ô˜x‡&`&`&QB0Åä'˜€ ˜€I0&i0“ 0ñ­ç€IŽ� ˜€I˜¼�I4LŽ`&`&‘0ùLÀd§˜xj’™ “o~˜5™€ ˜”ˆ‰Ä䵨ÈLÀL6™”„ÉO0“Ýbâן&v ƒÉ“#˜€ ˜€ ˜l“·ÛL¶ŒÉLÀLü0ùVLoŽ^“Ÿ`&;Æä몑É뚘ȕ1I˜€É&_Á¤Ld”jŽœ‰‰öÔDéƒÖŒV LŠÀäׯãïô¡ ˜xÏpL¼M0=&Æ3Ù%Â1]kÛ­ÈþHVËÙ&VeWóûÇÓ&‹ß»Q÷%bBÙ´ÿÂ1ñFÁ ‘‰_rKEˆLúœºmK©“abkž/ß^\ú|j½¼T62yžÀdéX=©¨ )&sR_ÍñKÚDªæLJ©.ÌÙ&¿¾½TÕáQª*c,÷'ö˜ü“¥ë9^Å3ã�ÂÌØ8m&×*Ò5™ì“—Ç”8MZólòLrê^¿ÍD„ôæD¹j8ûŽáý`òëW&›ÁDš”½9Yß‚LÖˆLžZb1iÉ5Ù=&oÅ3¼šSÌ µ®š3“Á$wLˆLò M »Ÿ‰^32y0“é×úíìæH`&`²©ÈD‚ÉO0000Y·ž&9ÖrÀLÀdC÷300‰™ü0000ɦšó/˜€ ˜LïÎ!2ɱÉLÀ$L&‡&`ò`X]ÒZ˜€ ˜l“#˜€ ˜€I$Lþ0�F00“(w•“Ì¿&`’&�I &?ÁLÀħÑLÀLÀ$J£ ˜d8ÊLÀ$+Lþ00Y±ž&`&`&KbòLÀL¼MÀLÀL¢Œ4“»ëI;d LÀ„Èd+˜¤n20!20“ bòLÀLÀdµz˜äØþ &`&`&`&`’Éý_ÁL²Ãä+˜€ ˜€ ˜¤Ää&`&ÞÝ9`’cg˜€I^˜Lj4“Û_ÁLÀLÀLÀLr¹Í˜€ ˜l“ÁLÀÄófk`&`&Qî�&9væ€ ˜€É09‚ ˜€ ˜€ ˜€ ˜ä„ÉO0000Y¢;§+�`â‡É;˜€ ˜ø÷ ƒIŽ�9`&ÙaòLÀLÀLÒ`r00‰„ÉO0000Is©_Ldæ˜ü &`&e`"ÀLÀLÀLÀd�˜Œ7š€ ˜€ ˜€ ˜€ ˜€IƘ¼ƒ ˜€ ˜€É¾0ù &`’5&?ÁLÀÄ¿;g�˜<½�ú&'Lþ»&/`&á˜L¤Ž€‰Ù€ÝQdŠÉW0Ù7&ç°ZŠé©iDLTšNµû÷çÏk`úó¿?]V�ÓØ‘w»30crøýûk`ú1žÃÒ§¯‹SñõíûÈnxëÁxPnÜ“9©«æø+“ç«P¢zy¿´Çç±ùhziÛ—  •6M²U¥þ'søöçOU�çQ éöuÕåpÃd$­ëêœííJ'}õû5ìpVÍQ„åp¨¥<¦··ÐÔ[ýüsJ¥F‹g0&Æ…&¾õ£(˜¸Šß£6û~=òeY·:ðÔ/"£I·u`ʈÀmhþ÷CÝšÐ=eLZ†t˜ƒÐ¡ÔZSœƒuyd+Åóâ*Mœ6é×f2³kX¥køas´û1vrZL9`zòµÁ˜´*xG„c¼+• ÆÄ„îˆÚŸSÆŸSc.7â¸BoŽœÙ›ã�É ÷€“�aÒcÒf€É çT#Ô†nŽ´&byL£ÍŠ`²3LŠ8§¶…ÉÃéGÛÒÀLvР׿€ ˜€IŒsª00“˜(00“(˜400¹w4ÀLÀLÀLÀLÀ¤ØX00¹4˜€ ˜€ ˜$À¤000“åÎ)000¡ÍLÀ$#L˜€ ˜€I„sª!2¹´LÀLÀä„É700“0¡LÀLÀLÀ¤`L^ÁLÀLÊÄ䘀 ˜€ ˜€ ˜€ #`ÁLÀL®žè&Ù`b"<ÑLÖÃD€‰&LÖ+C£‘ÉøžŠ™0™vNÕS"“×�t ûFdï ¹1<4Rˆ¶LÔkˆ&«7À~lë‡SÓŸ?ã[;ö@ðJ?¸¼nC;^é¶ Ë¡–­󨶘„åP5­~¾#šöùç¬êða1 Ü¢•aÇÓ툪JN�<™¡š€Ió”ÖÅD‡mì«}nÎèc×]l#¼žÔ~ó°xÙ¶2dyÑ6’ƒÚèóßó’r˜¿vWÊ'»Iö{êÙA‘nGÈ ÍÐFÁ»� IDATíÈÓ® ÙŠ2Ω ÅS5MÏI3G•¦Ñ+b¢ý’~}»h9ºµJ›öy2ÿ¤É/kB?ƒÑfùÏhß×áÃô»Ò$:œ1÷õÈž-žJ¼‰·ÙIˆ˜œVþûIº�ìæ·‹Žm­Ý&û-¢äóE³_©Ù‹»U+Ó*–º])2è¾�C¶@¨.2yü9ϑɓyìŽPa[ø1İ+þä6qN¹âù–VÆäwX;uÔXÝu¼¢¿Bý¶ÖÁ-ÊæP6¨à¦ó|w�î©Ê¶™TnGT‡ä;"‹sª l3ùÀäû÷ホ|_Â�¹i&£½9UÜ;ÞG1¡±,´¹-¸ U1:1"ôæ$ïÖª,&ÁMò¡½9qΩÀÞœ“ï³Óú˜üHV“~lø�glÌq&[´¶Ê95 “ï LJg&ÛÂdùsª0“Íc’ɵ9:È000000000I�‰000“¢Ï)&`&`ᜪÀÄžè&`&`&`&`&`&`&`&]ñ|Û&?ÀLÀ$_LÞ¼1‘ó11Kc¢ÀLÀ¤L˜€ ˜€É}L˜€ ˜€ ˜\·™T`&`ro+%˜øa"ÀLÀäîV™€ ˜€ ‘ ˜€ ˜€ ˜€ ˜€IƘh00ItN5ã˜èÕ1‘;�L*09íÊ-<„+LnNÃØO˜Œ[/�‰0‰�‰Y!7„‰X£š3þ|PžèG5';L¢œSÕh5Gdˆ‰0Q½SR×Ö“~—m[?¯[§Ç¤RÁ9«jsÆ$<¥Fv„+Ÿ1"£}ÓPÍñN10YÃhA¯š)'_ãR_šºnšÓ¢M]¹‰öÏËéõyz=ä~9Ý¥›éÊÈ‹å/§×Ýt·Êª_xx£éÖܽÑô˜¨æê�ná~Ùº›µ:-Û ™�ßès¯yÚœ‹Õõ›RrþYõ©ß’þgå r0&4·]ýé7Ö­ërÅõé5õé£6ývókiËÐÇç�ú±#û�Qßì�n¯ô™ÙoÄ«Üë‹Ýt¸ÞouÝï§î­á ÕnÔy¯Uç<ÎÓ‡Cwµü餩úé•Ë¡:/ßÏú±ü”ૹ’¤²AÀXé ÇdVúÒ•\mìNL.0‰™ôéO+îßÐò#¹šœ}$cÿì¿Ã]Ÿxÿ¦U¾5}dKTk†éVÙaýÂ\O¯OÓ[ÙgÚÞ�îþ¾Dº©µ‹µúIývn£ÝÊä°¼}£�0ìÂý¶Ùs¦Ëν¡úÏbºëuzÃ~wšÚ]v›{?Gc­Ýù§ºÏí^4ý Õ}6ý[㘌}!»vG›¥ìVÖÿ´9Wý*í [mm”¬l}ß¾²TÙ7ìDû†p ÚR¨û7jw+›î »¤èþèÞ¨í�Û^·¬û,Mecp Vm£;¡Dcßìs×ç܇7”tËÊÚnÁ¡©T%,0Â}§(û½e_ŠF »þÓtá¦W—Ókaÿ”nzmÿÖ»aºûvÝtÑh;]Ö¢ù4½ÝÚëÐ6•Z>-®®@Eèn=Hèg0éêGbz n3éî´¦žVÉdWìû–½Ê}Ú¾©]¸?ûÈGŸ±¹œîþRC-äzz"¸?õ9ÿ'Ó0¢o•è9-ÝnnÓcÒyõÆ "'Z}òlØÖ®]¡±OŸ2ë s^ÝEî‡!3Ù½6ÝdÝt‹ë.7·±¢C®nƒ1q¡‹ÅMvŸµÏ¿_Y'—=½m�¶o4öeåjUÚ~6ig¯ÝtG‘k3öE÷†¾œÝe×Ïníк¯Jtö¸åÝ ÷%`g¯úÙÍåìC]ÔºRu0•®¤ÓAVæ`¬¢{Ù¨ZÛò`窇麛.ûÙUe§ÙåÝt;»}·_ÞÚc§ËN&Ó-ße'»Ùûéî¥]»<W­ë±V͈m&>&ÌìÍ‘&NìóµÄƤ ÄÎX\`Ð7�>žnn§77ËË�éõyº9Mî09½¡†7ªSfjpíü†¿¼˜Ý½a#—EýË {‚«9«`²Ú 5 &‰11å`¢ïcÒNǤMŒIÇÁ$LW³«Ï³¯�‰Ð» &`ò“v!LlE£�†I= ó½&Í ˜èÒ0»Â 0) “6L ˜€ ˜€ÉÞ0«`"Á„6“0™ÔfRÍĤj/`—ÁDL¨æh"ÏÇp•Љ“'˜Ô30i§7ÀN¤=�IaOô0)“C[8&˜€ ˜€ ˜¤ÂD€ ˜€‰ÿX0Yh  ˜€ ˜€‰0“O=Ã`âÛÆ8}Ã`&`Bd&`&þ=ÃD&Kuç€ ˜l “jLÞÀLÀLÀd©¾a0“MaRƒÉÅ3ÂýLŒ/ zÀÄ;ÅÀÄe3qmªJ‹‰¸‡‰I:hMGƤé>XUUÃ�‹_î‡é³­Õé­«énÁdILje<Šg„ÈdVúÒ¯ÝãAI LºNZ«Q ˜Ü §�Œ‰1n±F¹k´k¥‡vfÑÅ…U¿Iö…ì¦7ýt»¼Ð]ܨÁdYL„Òf”��ò!2é33ÓQø¨æøU�¢4ÀN_©ªÁdÙksìw™Ã@;FjmÜtet‡…î–7ÆMï̱ÓU?ÝacÜt—˜,ˆIÕxÏ·mô5avl”6�õ™,}¡_;`ÑMï0ÑÆ8LZ3,ßcá0y6L–ÁDøÏ˜ÈµzsÖÆd~çðr˜lëªánº2=§éM·òϘœ°¨OÓ-½9ù`""`b6zÕpÐå9YcrÈs�I{…‰©7‡IU(&µ_ñlKÂD¯�I &KG&g,†é—XÜbò1ý 0Y “Æ+2Ñ`²H£ ˜øTs®#“vBdÒÜL§š³&~M&B'ynŽ)“Ù�&´™,‹ m&k`R˵«9í†ÛLdRLäÞ01`’& ˜ÄĤ0Ù+&~µ0Yªž&`R>&r»˜00Y“ºLDA˜Ì­ç€ ˜�‰o¹Öa’¢š3·sLÀ¤tL*0‰ŒÉÌz˜€Ié˜ÔLâb2³ž&`R:&�Üp› ˜€ ˜ÌäõÇÄ·–&K5š€ ˜ŽI &Ñ1™×h&`R8&¾µ0Y*40)&`&`“ LÀdV=LÀ¤lL¼k9`2e­5˜€ÉÞº†+0Y&`²;L˜,€É¬z˜€Iјø&`²Ô¸50“¢1`² &M&`²+L* &ËTsf4Á‚ ˜”ŒICd²Pd2c¨ ˜€IÁ˜Ì LÀdbhR� ˜ì“L‹Lü›`ÁL ÆdN-L–ªç€‰Û:0)“J€Ér˜x×sÀLÊÅdV-L¦&0“ý`Ҁɒ˜4`&{Á¤`²d5Ç·ž&4À‹É¼Z˜L]³0Ù & ˜,ZÍñ­ç€ ˜”ŠÉÌZ˜,Õ &`R*&3k9`²Ô¸50“B1™˜€ÉRCMÀLJÅD‚ÉÒ˜H0“=`Ò€Éò˜4`&ÛÇdv-L–ªç€ ˜”‰ÉÜæW0Y¬ LÀ¤HLªLÖÀÄçî�`&EbR 0YŸÐLÀ¤HLæ&i0‘³1Ñi1iÀL¶�Éüæ×䘈²0ñh‚0)“ùͯD&‹ÕsÀLJÄD€ÉZ˜0“-cR�Éj˜L &`R &ͯ`²X,˜€Iy˜&`²T,˜€Iy˜Ô`²"&“›`ÁLŠÃ¤ ªå”†‰IŽÉÔQ°`R&Uɘâ`"JÆDxomjL¦>ÃLŠÄ¤Ýsd˜™$Çdjh&`²&UDL&ëb214Y&`r‹IŒjN¥ÀdeL&vè€ ˜†I­C1Ñ´™øn|&`²ÁjŽ2;ÃÄd€‰ªÀL6‡I¥ ÇD–ˆ‰®½0©çc"c¢¢c"N˜˜{˜4�010Q“0¹š> “j"&bê8OLŒ&æ>&êTÜϘˆ Þœ�Ù�&–‚pLt9˜È(˜È@LÌ”Ðä3‚ŬéS11×O¿ÆD>ÇÄ<ÄÄ´FŒbrõàò u‰‰ì7¯òÄÄŒcRß`bcò¡Ã�Ak¦Ÿª®íy†‰éf¿Â¤¹Æ¤¾ÒÁ½”�ÝôN!zLÌyö =¬=r°Ç ³Ÿíé!†¥õ“~z5Ò/lB1‘I`}[|TŒ°�Áœ²üNM\i6ÍŸªAæ ñdºýÓ<î:¶Å½½-îÝì—º˜+Lì©`îG&v[;;löfÀÄ<ˆLÌð†µÂô…ÝTÝüM·ê WíÚ.¦«.ÿÚ˜Óaq9ÝôÓ¯±¸¨æ3Èt8­Ì±&¶tÛ7„9é`êÊbRÕvzez*;µ:aRYª“ÊÍîB�~ö3Øãò¿gOŸ{¯K÷ØÜ;=ªÖþ7`¢êÓKí0‘}laç±/]¨¡ª³-&]5Éa¡;L>ôèí°égïõh(CÜ3“Ú\4"`âm€‰=7}S8&sÖz‘ÎÁHk–=§U‡A­N¥ÔE’ƒwëJÝcáÞí»ˆ.§›ótçF ‰�¬¤åB÷˜¸Ý)«Ê}¹ht?§=(Ý)¢µ»Ô¹’®F|þ¨ú ìß°%QÛ¥íf˜~V7¥®ªªQç7´}ãPÕvuʬqoØeÕ°ˆ›õò�Ö-ãêá6'›ASÙ‰zxaÊî…˱î&ˆº®µ¶/Ütû–ÐWÓµ´¿´[²Ÿ«nºm²Ó­ ݇¬í[îE·2÷­ÓMoìâ�}­êÆfV»©ÒÎng°/Œû×Ô“aª±Eùü†ýÃMµ‘M7»}£_þ<{—»ýרýÑOµËKk‡›ÚX"í±Ë)”0Â4¦Öö/©ú—µi´Ý”î í^voØÂd_J7óðRØ™Lݺé¢{CŸÞ�ÝKÙ¿lZ¡»Þ]e_ZâÜteó²_õF¹éÕÓ1&¦+a¥#&íœi1é ¦WŠ�‰ÿZo7¢�PÏ©\ºûçðWm A5üyz×þ®?þÞ½@*~Òׯô�9ôõ«à4p™ôÓ—Ÿßp_Îæâ+ÏÜýº6w¿£-y.TÜm1"£ýËcÂØÀŠ¡kíkªCœt6ä$Ä­,÷r¿«Q,žMí‚�ðŽÉY�‹>�ë7/ÛãÄå�a>•AŠ‚Ih Š(\„e#îÀ¢aR´™”Ý5lÌäËýB¢–瓪°“ÆÕƒ#y‡“PÄ�IŸÏ¦¢‘©“babÒbb#zs ãL|7Þˆx¡‰·'q0©â`-2 —�<LG&];®Éaœ‰Ù&¢ÃD,‹É¡ LD˜K!©æô£%b`Bd2“¥C“"0©ƒ1iÀ$L´Œƒ wZ›�‰ÇM’ÀLrÇdÆ™ &Ê·<™¤MÀLba¢Á$i¬LÝj&` “Óõ%`’ Ÿ§˜ƒ ˜ä‹‰–`’“´­&`&q09_øZf¬Ø@lêÐLÀ$&Z‚IzL’¶š€ ˜ÄÀĘÂ1‘ÛÀ$ih&`%2ù¸½‘IJLR†&`&Q"%Á$Ld &`R6&71“¤˜$ MÀL"`ryS0IŠIÂV0“˜œï"À$5&éB0“pL®n®&i1Iš€ ˜„c¢Á$#L’…&`&Á˜\?õLc’¬CLÀ$ &Ya’*40 Åäæqt`’“T¡ ˜€I(&7Ê“ä˜$ºxLÀ$“Ûçä‚IrLÝr LÀ$ s˜€I˜¤©è€ ˜b¢À$?L’´Á‚ ˜aò)0“,0©ÁL ÃÄ &b’$40 ÂD�I–˜¤T&`‚‰–`’gd’  LÀd>&æN`&yD& *:`&‘É�ÀL2ÁdýÐLÀ$ 2‘`’/&«‡&`&³11L2Ædõq°`&311¶’£À$cLÖ®è€ ˜Ì�LÌýr&Ù`²rELÀd.&Z‚IÞ˜¬<ØLÀdn5G�Iš€ ˜ÌÃä‘%`’&ë¶Á‚ ˜ÌÃDƒI˜¬zÁ˜€É,L&`’&«†&`&s01Z‚I ˜¬Ù= &`2 &e`²b,˜€É Lž&Y`¢Á$AELÀd&Z�I)˜¬WÑ0ñÇÄ<+q`’&«UtÀLü1ÑLÊÁdµq°`&Þ˜h&%a²VELÀÄó¼¼�Iv˜¬TÑ0ñÅDK0) “•B0OL´“Ò0YgT=˜€‰&f¬´µÁ˜h0‰ŒÉ:ƒMÀL¼01Z‚Iy˜¬š€ ˜xa¢˜ˆÉ*š€ ˜ø`bÆË˜äˆÉ0L&X&yb²B�˜€‰&LŠÅdùÁ&`&Ó1™˜€‰·%Á˜È)˜,¯É60`²&Fo9‘ &rhÀ¤�ÈDm=iOæ€Éœ›#™‚1Ñ“0YºG'LšLJÀÄL+gSç{‚‰y Ód&r&&‘ª9r�ÈdiM6‚‰LÆdZ%GŠ`LdLì'üÒ…_Â+)£Vy®õvº�>6›Å¤Ê“ºÇ¤I�‰èÎ9 L¦bÒ�ð£;Ú~Ç�˜xnƒ-�}dbÜNœ¼»»=މ =êöðô›ólSµÝ)‹Æ&Õ3gÜ�G a‰ýׄ™`á˜ìB­’F&cç¼Nl² ì�6&ÞÛ`LüR·Ë‚1ùmÚÀdºÿ'Ü»·ë+H™Ë/¤|’4˧àÓzâyýô”o€�•ºjŽ¿ᘨcXý®QÍàC<7iJpFI$;º26%ürÕ÷-P2ìjÂ11Þ¡â©kXyT™ÝWºnƒ1‘Mý’šãÐPõ¤¹äT§×ÉÎ!ÓR‚3JM2Kºö=9¥iJ™V• 7V B×°’^ iç6ïÖ㑉 ³ä¥>N´vnÞNvQ‚ÁÄV]<Š˜iEV4¢`âß»šn8}(&/>˜$Ô„ &~%¬m�u &rýAki1yY“.0IÔ`âS¸,&�E£~Û&?ÖÅDtãóÀLÒÔräê˜|ß&¿W�Ld2M(Á{ÇÄ÷Ñ¥c"¶�IªfJðî#%˜l “DÍ&”à½câÛ/B5'L…&”à�cây–‚I˜¸›€ ˜¬?Z L ÀDxk&`’ï“h½9b}LÄÞ0QD&`’wƒ ˜”‚I M(Á{ÆdÆÀÀ¤LhB Þ1&sî™&¥`²¾&”àýb2ëþ‹`R &«wS‚w‹É¼{¹‚I1˜ˆµ5¡ï“y·L“r"±r1%x¯˜Ì|üB L$˜¬‚Iÿ´ 0“<-“’0YYJð>1™ýð0) “u»t(Á;ÄÄ0Ùm5Ç=Ö€ ˜Ä©ã¨Ž0Ù-&KkB ÞMd¢$˜ìºš³øÀzJðN01Jô_P`²cLº§¤‚ ˜„ÞuLv_ÍYXJð.09ÝÁLöŽÉ’÷J¢ïýA˜ì´š3¨² &”à=`¢/¾ Àdט,›P‚w€‰–`&—7$0 `B5L>41`&Á700Y,6¡o-ÁLnü2šP‚7މV`&Ÿü"Ca)ÁÛÆäÆ0“å4¡o“[KÀL–Ó„¼eL>YB×0˜œ‡›0“ù–€ ˜,›P‚·‹‰¾{‰˜€ÉY&`2Ó0“«�b¢Þgš¼ULŒ0yÞò.âÖt(ÁÅäþÓÉÁL–Ó„¼ILÌ}K"`ƒ˷„Iw“i&`âÕ�&31Ñ[Æ$nŸ%x‹˜%—¤ÐjŽ,¹&¯Ó¡o­$˜ÄÂÄl<2‰¨ %x{˜<¶LÀdAM(Á›ÃD?/R`&Ÿ51`&ïCÿèœ2`B›É½N&`2±éõ\¤Ü !_s¦`LÜó–»Ï?=©L0ñÜì›4øGSÝ :œJð¦0ÑêÉ)g Q&ø¬Ì%»B0u³»P™h­´WÊ£šÓºMñÜò«Ôçð|0Ù&Áß ÏO5åœ-\Y`bf”¦“ãÿ²À$|ã„YôqHïÇ9‰œQz™uOG~üt‰4<)Læ}sö%Ɖx;î¦3œî¿<0q[eR—ãÏÙíûecÏ¢—÷ù‰œQzIÇ£êËȃâÑÿk/gÑç§>ýj³‰L<Š×Gd¢=+yÊäÒf"ÄRm&§ª °_L.ý’ýëú¿òÓ?ÿüóŸàôÏ?[ØÒ€‰kExÞ âæ¦BšLri31žm&B °¾½9"“®aï^¨Ï½9ã9{L~n9ÅÁdË{¨Çä8©O#´�1“X¹³q&rLMÀdï˜L²Äõælcœ‰Ykœ‰4;g²#MÀd’%J®™ìlКÔ{ÂDn½¢ó˜DŠKÀd·˜¨©Ÿ|ã¡ ˜Lh/™~N�I‰Ãé[±&�MÀ$JÛëÆ`¹Ðo�Ø¡ÙdËœ€I,KˆL¸jx2'`²3LzJÀL"b²éN0y–½ŠÔ>1á†Ò^~»š€I”*˜€‰'Ûl8“G˜øI&`²ûàLbY&`â©É;˜l¯á%`&þ~“š€É]JfX&`â§Éæª:`Ü‹&`2g©íi&wZKŽr†%`&ÞœlK0 oy0™«É¦ZNÀ$–%`&;×LB;qÀLæøM5œ€Ih'˜€IÀ�ß’&`rÝ‹#ÁLÖÄdKš€ÉÙ’0JÀLfk²NÀ$–%`&;çLN–&`’·#¶Ð«&§¦×às LÀd6&íúˆÁäÔô &`’ iZµ�!'»Çdè>*0“”˜ˆò[NöŽÉéº>&`’“òÇÃî“�K„UŒg1� ˜`Rº&»Æäc š�LÀdÞqW1`;L ï$Þ1&Wc^‘ ˜Ì>ð&&çàäLÊ>O› ˜`"¢aR¹×mxIDATòSÿöŠÉí�W0“¹IGŤ`NvŠÉ§áó`&é0‘W˜|pò&Åôƒ ˜D©æh“B[bwˆÉÝ[Fƒ ˜ä™ ž”¦Éþ0¹�0½9`2ûÀ›E0)O“Ýaòàf`&ézsîcRœ&;ÃäáCq¨æ€Iv˜”v¶}aòøH`&ùaRØøúaòôŽÑ`&bRÖ˜“Ý`òþüŽÑ`&9bRÔû½`2öa0“L19kò&^ˆ&`’&O¦–2 v˜Ly¼˜€I¶˜ôœäß±³yLÞßßǪ8`&9WsŠé'Þ:&gJŽLÀ¤dLòï'Þ8&)0É“aHl¾œl“éê0É“Ì;v6ŒÉ”vW0“’09·ÄfÉÉf1y÷z~0˜€I ˜ôšdÚv²QLÞ½Â0“R0ÉyØÉ61ñ‹JÀä &Þ]Ld®C췈ɤ�%[Åäí-00ñÇD¦ÄDFÀD‡É¹cçL2“$R¬ &`²ÐØ2*;ÃäÝ¿‚ñ”È@Lꘘ1i³ÀD”ˆ‰Ì¯%vS˜¼Ï¶$“jŽÙ[d&s«99r²LÞ'^…³ù6“·r0ÑLfG&ו�w0Yàz¾ã\ ¶Ñf"ŠÂ¤Õašüþ-ëpLŽ©1³1¹û&k^¼,&9D&�Ãä­,L~‡X² Ld&—œ¼ƒI´+ƒÓŽ<Ê“ºÃd¾'o&r%Ld�IP’"Ћ‰ ;j:85qÓv’¾õ¤xLÞ£P"Uð¡â`r ³¤0™�\W31ÑZù%»Ó5Q§æó“Ý”tx¦ Ëáx4&}cl阜( =œ1ÎûÕžCP¹hºo«0KŒñÞ¶,t˜ØdZÏdÂÒŒ5~Þ‚ óÌüt1·alãZ÷U””“²1é%‰t˜Mœ;áÖHföørkÃFÂ1±yD8n.—»[<öazÎÌ8 'u«>­jÞ¶÷;¡ÿI»vJƤ£ä|0pŽçÜÌù„hž•Ó¾žƒYά‰Åùþy=}ycÎûÍ|±‹)å]·Ô*´vÚ…Qa�eÁÛàßÌtÓêb"íˆcÒ¾�R1¹è ¶)ÊYi²èrn‡ ýqÎJßEÌüXZ uhãgŒ‡Lîó°ÞœÓ®TWÙÞÁdæ ’gex“|è95¯Q?zñœÑ›3`2c]*™“(×QDÜÉ<)“;ý73G|*¾ ÒŸS&&+§ü¼"wÿQ>&âú°¥©íˆÉ� pÄŒ«Ó–ˆvÿâBÏ©PL„˜‡‰I‡Iø`øÔÕœ(;âú°%‰NŠÃäî°’8˜A™ò1‘«bPŠ!i˜D�L®8y“òÝ çœJ>V”‹I»cLdL¢ïˆãqíð¤Lž^á¬Ìd8½’‰ ˜$j3YhG¬ÙY\&—=Ár³˜ˆ21 ¸,˜,�Éší'%`2" ‘ ˜€Éó±Ž'¹cò>éžG`&`ò<‡ê;Ycò>“€IúØ¢1{Ád…Á'Ùbò>Y0¹Þ`&O*; ‚’)&”¬wNQÍ“Mcòqï—e@É“é!ÉÆ01`&ËƳå‡Éœ[Cƒ ˜€‰ïF£Ç'Yaòþ>óy`&`âý€ÑØw¢Î“+IŽ)Î)0“arëÉûV0™“€ ˜€IÈŽ8Æ‹P2Àäºø˜îœÚ&LÀd&(Ám²I1y¿qdöó*ÀLÀ$,‡]Æ 1¹ ÄÃ|&`&¡9}݆â�JLncTçm&`²gLlGâÉê˜|ªÚ,qÓ:00ñLú\nÆÉNVe-L®¶ëxÝF"rpLÀL5ÊNBåŸU0y& ˜€ ˜äR͹×(ûY•˜¼_9raÈñÓ9&`&Yøë§Y?‹Q"aòÏ“Hd¼çLÀL2Àäi ¸ëÉ•( `rß‘‘s LÀL²Æä:Jy¿“"aò9ããqú@´4Ïg0?L>Õz®Uù矗�ÉÓöÕ)ç]Ã`&%`òL[äE˜%âø)ùŸSTsÀL’Ïë¾*øú£èÿ–¿'òû¼€-CZ‡^Y&`&`°t?”]¬fª9`&…cb9Êdñ´m00I�Ip 0-˜€ ˜ì"0 Ì¡ä—ÇÁD�‰ŒñpDeÀLfcþyeò�&r˜Äq9u’á˜H0I‚ Ï– »†sÃD€ ˜Œ‰ÚD5Ç5À†ïˆ0 �U7²+i3!2)ºÍ„ÞœH‘ ˜$èÍQ›Á$øÀ+ÚLd#`Á¤Ìj˜Ðf’%&¨1Ê¢0 t)dø°M©ì�WÁ>4‡(ýÓ> Ë!ècä±+U”]™xG˜ð¡dê1#‡&Z+¯¤Ý�K66שs°?tL„Òï¾#·!Æ®Ô[Ø•&ý®œ³#ô€ ‰D"'0!‘Hq0Q쉞ŽÿþL|8þkõcIEND®B`‚chafa-1.18.2/tests/data/good/card-32c-noalpha.png000066400000000000000000000441421517447374300213200ustar00rootroot00000000000000‰PNG  IHDRL;g_õ`PLTE(ó33/¯ýp+‡ÿ”ÿûNPMufknm}€D•ƒ-Ÿk|ü€†Ñ¿‡/”�“èt殚 §œDË|Ÿ¤{ÔŽÇi¹¡«©ªîöôÍÍÏîêçåçÿÿÿãÔGÀtIMEæ#&k…i IDATxÚíÝ c£¨þð}×sÏ}¬t¦ËN'3œ?‹ïÿ]^ &MÚ$Š €~Ù�¶‰ŠFå“jÕ*Óù$¿¹×MæÐ«'‘Ö:+e¢ªßì~‰A¤Êl²¾×Iœ{>n™ÊþRžI›Nk’´îLX*<e³Àm°;"<‡}ìJ�Á®L¿#"ä�Á9µäcè[¤¤WRîóÊ�dW½8!ú”EP†m„ýä�9˜àÆ!Brß!9ˆqWªà]©®_ô§DÈ9aGˆlÎ)iLxñôÝîûdÀÄweö°~Þðì�—Á;=8‡àeWŠô»2¼„æ ´ ?§Bs�]'3Ø ÎÊ¥˜ˆàð‘ƒHW¿E„IO�Ý•&=&ÁeHD(C¨ªrÀĽý®\ŒI”/)±J@háqEðÁ“�³2ùWܦ˜è]ø½&LÀ„6“‚1.«ÐýU>C2cztE×�ÎsŸ/ÌÐaãé‰LŽÚf&»ˆLÔ(HèÕº=<£+`&`r LzBža°˜ž09&L�I_²‡ k#«òÈ9^Ò;lª0“‚1éK³C¶¾ËÎÅ"0“Â19#&ÝmÌÆöZ&`&¥xq¾T�ds/À§A ˜€ ˜¤>ð÷®ÎŒ‘;¤¨ÏM(`&`’&ý=@Mî·fþ¤€ ˜€IFƒÖ†æ‘bn�~+ #`ÁLÒG&¦8H¾F( LÀLïˆþ±%BrEŠ¥ƒ0“d;Â=7g'ϯ ½ºLÀLŸ¹ªè€ä^#JÈÕ=`&`²4&Ùáã4{OÀLÀd«¡v ÉGÊ"OÀLÀDøB²«ÊM4PÀ$%&ܶ"_L–rá~&2Æ…~0ù&‡¨æø^ˆIßÿŸ&݈°&ËžY &Ë1`²=&þw�1Ês–„m‡ôw¥•çÈ�|0¹”�·˜¼‚I ˜,¹Y‰ŒRž³ dSLü{v2Ä$I›I�˜üŒåÊÃdÙÕ|»Â$dCü11~×í�I‘˜üÚ&«F%÷1™_LaòüŽÍ0鯺óh:0)“€»1Êù5L¦/Û “ž“Ù•�=aòzœØ_¡m&…UsBnì*¾õS`òps’`â3Œ LŽÙ›STdv�èr1y8e[L'j#LT&]à ZÛ'&*ð>Ò§ÑåŒÉeÚÖ˜ÌìØ“£F&Y„¤30 ~t˜DÀd'`&9·™Dx ˜DÁdÆÝNÀL2Æ$Æ�å|I¾U0¹IÁ ˜€I¶˜Äy8Ÿ7&]¾˜¸É[Ž3ñ«ë€ ˜dÚfë9Ÿr. e`R¥Ää9'`&Ybï‘Á…aí"áu0¹÷Ès0“ô˜ˆGÕœ˜ÏÔ’óa˜j3Y2uæ"ÞÍ9þ·+�‘vèãàLÀ$;LTÌ'}z`R}žx³Ì’¡í3YМ㉱Œ¶Kq&`’&*îCƒe@•e&]„ të`Ò­…I÷àI`&I1YÛ0Y“ûÁ ˜€IN˜Ä¦LÖÁ¤»÷Œr0“Œzsâ[ “ˆEüÎ2A˜Ì] 2&w‚0“l0Y�’M0y~+”YË,µÄc!}×~n90É“U,‰‹Éüf3‚�ãL<.+Š�ÉçàLÀ$LÖ¡$.&sºMM™?âÄk §§¬€É'MÀL’brÞˆˆÃÔÀd3LnoærxÖ0˜=2Y+,‰‹‰OY¾3žv L®f#LnºuˆLÀ$%&ɨV£$&ž�Áâ ùb]š³&wu0I™¬–Äg&SM'`&‰1Y•’ì0é6¤Û“±—XÓf&)«9jeKÀdL†G™€IÂáô«uâ¤ÇdáÀÙe °I­Ý&û½&`’“õS"L�Â_Ø5œcÀL’a¢:0Ù&=(´™€I L” ‹w‹I· &]n˜(0“í1Y½å5&a÷˜¿�ž«Ù“PMÀL2¶dsL®4öÚNïÕl‚ɽۜ€ ˜¬ŠÉú½8‰0ñ¸*8ÿl¶ÁdÞc‰ÁL¢a²�%¹aRm„I• “Éÿ� ˜DÄd›–טtÏîN&3C“€ª˜€‰çcº<1ù2L6®ê€ ˜xVq:0Ù7&‹{uÀLrìÅñÆäiÏ ˜lÒ«&`â±Ï6¦La²L0�æ’d˜LÝ騋ƒÉüÕÄg’U×pP¯˜€I¦Í%�1™9–ŒAk7œ€ ˜dÚ\&i1ñ¯ê€ ˜dlÉ& .å]x¡ßF׿TÙcâ­ ˜€I~£K>’ð(\5œ¸áLÀ$Óæ’;˜TarÐû™„j&`2Ã’®Ë“Çeu²4ÇÃdÎJK¤3J� ˜DÃ$UL2ÀħáLÀdÚ“ &�ËßãÒ:]œ—”sÿ‡ôUA«‘é@×`&q0IjÉWLŽšb2»áLŠÄäm3LT—4�I˜ÌÕLJÅDn‚‰6`&3GÃY6&f“È$ÁÅ8O­�IrMžœt"&¦èÈD+!¤˜—ìbBé<0QrîVßMz^~N;%K ‘I˜¸N�çåÂþÔãWóâ“Ò5Ðe�‰gáꇇWý^òL™D&:,™©O’ɦ›šÔ˜týCÿÏ©§e‘Iç½Ýcd²à¬Ï“ðScê«H´�IL vSbª}W‡Öæv’Dø¸Ax<Ý÷¯™øêˆpV¦ÆäÕa²$õÕ„2‰LTÐwÀƒO~ÎT‰&üëtŠŠ¶«Ç6¤XA^Ý(›&Î)0癘¥‘‰­ ¿úQ6m&!�&j¨ß>¨» ¥v1‰I-(ä[%~<ëöy‹Ç³sêm&Ê?àÜC×°zúÉãX2�IÕRÈKê«Ûû=:bg]ÃrË®áïÅw ?Å$Bg&MEdRV/»ÓdÍq&†q&cò¶rd"bõ LG&`RØ��º Z“/‡M­m ˜ì“ªz¬ ÃéN¿š%`²GLk&`²š%`²KLªLÀd³íLö‹IÝ€ ˜Lc"¢Ž^“]bò(60Y©Ž&ûÅä¾&`âýܲcÙ0Ù-&w5"“Õ,“ýbr¯O‡q&`rNmô«ýÁd¿˜ÜфȄJ¯f ˜ì“¯CëÁLFKV¸¥˜ì“/š€ ˜ô©©ÀLÂ40YÍ0Ù9&U-®ïH&`²š%`²wLœ&`&—o3Zë®Í`²wLnb09.&êŒI[U`&Á=Ä`rtLÄ}Â`rL®4“ÃWsÖ³LŽ€ÉG» ˜ =˜ “‹&`rðÈdMKÀ䘜¯ú“ƒG&«>}LŽ�ÉY094&M&`žZ"“c2<êb]KÀä0˜Ô�=›”“#b2<teKÀä0˜ô—é™621jmKÀä8˜¸.ã.;`Rb›‰YÝ09&V"“£b¢e&`SzsŽÚf¢j0“¸ÄšjÎ!#“¶­ÀLâ&¡À䈑Éq ˜ “J*09&ÛX&GäL†ÉF–€Éá0©Z&GÂDȦ0Yiðš“#E&[Y&ÇÃ$P0) “¶0Yu`=˜“í,“#br{Çz0Ù3&[5¾‚ÉQ19ßÝLÊÀäm9&Z&ÇÄ$@0) “¦0Y]&ûÇdSKÀ䨘ԭZŽÉ˜”€‰jk0“Ma˜ì±­%`rXLªfÙe:`R &[&ÇÅda#,˜”‚ÉÖ–€É�1Y6v L Á¤©ÀLòÖLŠÀD´˜€É¦�°`²OL„¨ÁLro6“ü12…%`rlLªV 0Ù_d"š LÀdûf&»Ã$‰%`rpLªZ€Éî0ik0“šPÍÙ&i,“ÃcR5~0É“4•0× &{Â$•%`&ž£MÊÄD–ŽI–÷i0ùÚlâQ4MÁ˜L¤. Qƒ ©3*ÕYàÓl“·0L^ab’F&oa;̘ü+9`’UJ†‰O³‰  ‚ÊÆ[0&ÛUsD£}×;&=è3kVkIÓŠÙHˆ¦ñ^‚ILÄ.«9—ã &`r$L ˜DǤ­ÀLòÂDPÍ)“�à &÷ <˜¤ÀDì>2Ù#&WGL¶Ç$‡°Yb2yÚ›"Ç™ˆ]cÒV`rlLZ0“(˜\l0“|0`R&u&`’%&Lʤ­ÀLÀLÂ1¹=Ô¥b"Àd—˜0)“Ïg(˜€ItLüvIu›7˜”™´˜€ ˜€I„Ȥ00‰€IS� ˜äŒ‰“B0ù˜€If˜0)“¦0É&%`òõ`&`&þ˜ÜÁLÀ$;L˜ä�I[� ˜€ ˜„c"*0“0`’;&5˜€I˜0É“LÀLÀ$&÷%0É&ùbòè>}`&Yb"À$ßÈä`&`&~‘I]� ˜„‰“\1i+00“˜ˆy� ˜€I®˜0É“LÀLÀ$ñÐ0“l1`’#&M&`R&LòÃäq`&`&`â�IS� ˜ˆ‰“Ü0y˜€ ˜€ ˜ÌǤ®ÀLŠÄD€I^ƒÖZ0“/»»L˜d…I]� ˜€ ˜„cÒ‚ ˜€ ˜DÀdâŒ0É&ù`ÒT`&c"À$L¦Ê?˜€ ˜€É,Lš LÀ¤hL˜ä�Édñ0“½bò=&ÆÌ LÀLÀL挀�.ý`&`&30iÁLŠÇäƒ0I‡ÉŒÂ&`&`2�I &`²L˜¤Ädf`&`&`2�I &bâ‘V,ð…a"JÆD–Œ‰0™UôÁLÀd+LÄÆ˜üІIS•„‰(“¶PLDa˜"“”˜Ì+ù`rÌÈLŽ‚‰‰�I[e‚I»FÞëbÒº&ÙaÒe�‰Y€‰)82Ñs ç꘴ëä½&&­8) ±cLdF˜è­0‘:=&Ê�3i몜jN›&³›LˆL¶‰LÄ«9Q01*42éfZ²6&mû¼Æp5è"#Læ§W_LÖìqÙod"LT0&®x†c"b¢•O’JGÁ¤_« 1–%í�Ééœ^^N“éÅël^_ûâö:£L¾Š¦^­àˆŸ¼_^O§×WûãûÄÞèÏ-/L¾}û퓚oq0¹|/_½öÚÝëbò6+9 ÌP W4"´™hÿòØcâ—ŒûŽI„tj^êéååÝ'ÍÊóœ¬%éÏkÓÌÏ{\è|„Ç:ŸÓùí~ÒËÜtYxòÄrs¼Ú­þ6?ýó�ýnšŸ­Ý%ÿI›¬}C¡ÿñãÇ7¿ôc\ìKºzÛÍ¢Œ‰P2Â1Y”ª‹cbwZàn;Ù’ÿïšéýן?þ/qr»ësÒyßNÏö?¯äW+.<üw‡ÿþ÷¿îßìôiæ;Ù ïýÿ6ýÉÓ·¿ÖMßÞt_.ŒY†Ê¸TLŒ }qª9žÕ£8m&jaËë¹veJl²[ú`ò¿Äé×÷“Åä¿iÓ10ùëÛc´ 뚈TÍñ5¡ÀØ“Ói}K2ÁäÉÓ¯ÓïoÿM�É€É_ߌɢV•Ô›£Ãv˜Åä_0Ù“Ô�I¯É!0y ÅD$íÍ)pÐÚ&–€É“o9`rˆÈä¯7�Å8“E˜˜d˜„h²E%LÀ$&?úâ‡Ó™œÀLÀdÍjÎ�0yÿ &`²GL‚5áæH9&`& 0ù L6Æä'˜€ÉN1ù&Ûa²U`&`’“70Ù“Ÿ`&{Å$PîNŸaó+˜€ ˜ì“Íj9`&I0 ÓLr¬å€ ˜€É®1Q›&`&i0:tN`²ö µí0“d˜¼™lƒÉ¿`&»Æ$d¬ ˜äv�˜€ ˜ì“ k9`&é0y“õ1Ù.00I…I@h&˜ü09&o`²2&›�~0“Ýcò/˜€Éî1Y® ˜äXË0“ýb²i`&`’“¿ÀduL~‚Éö˜¼‚Éö˜ü00IYÏ“ì†Òƒ ˜¤Åä/0Y“w0“£`òLÖÃDœ¶­å€ ˜¤Åä LÖÃdÛÀLÀ$%&�Éz˜œÀLބɲÐL2l10“�br09&Ëš`Á$³;™€ ˜d�ɘ¬�ÉiãA&`&`²[LÞÁL…É¢z˜Ì LÀLކɘ¬ƒÉO0“caòLVÁdóÀLÀ$1&KB0ɰ/LÀLö‰Éö� ˜€ ˜ì“˜€É1YП&9ÖrÀL2Àä Lbcò&`&`“ÁL‡É_`&`rLL~€I|L~‚ ˜“70‰ŠI’ÀLÀ$=&Þ¡ ˜€ ˜€I”ÐL&1ù &`&`ŒIšÀLÀ$L|ë9`’c`&`’&o` “˜€ ˜€I$Lþ09(&žš$ÁD&Ãä»&§DM&`&%b¢1y-*20“]E&%aòLÀä°˜øõç€I†Ã`rÁä&`&`&{ÀämÃ6“=cr0?L¾Ó›£·Æä'˜€É�1ù¶idòº%&rcLR&`ò�É70)¥š#b¢=5Q: 5£•“"0ùõëô;}h&Å3oÌ€‰ñLv‰pL&×Úõ+²?’ÕrŽ†ÉƒUÙÃÕþþçi“Õïݨ‡1£lÚá˜x£`ÆÈÄ/¹¥"D&CNý6L¥T�É�0±5Ï—ï/.}=µ^^j™¡Ia÷3Ñ[F&ï`&`2ÿZ¿ƒÝ LÀLv™ˆB0ù &`&`&`&ÛÖsÀ$ÇZ˜€ ˜ìè~&`&`&‘"“Ÿ`&`&`&`&ÙTsþ0“ùÝ9D&96™€ ˜äƒÉìÐL «KZË0“Ý`r00‰„É¿`&`âÑh&`&`å®Ò`’Ùã·ÀLrÃä/0 Ää'˜€ ˜ø4š€ ˜€ ˜Di4“ G™€ ˜d…É_`&`&ÖsÀLÀLÀdML~‚ ˜€‰W£ ˜€ ˜€I”‘&`rw=i‡¬� ˜™ì“ÔM&`&D&`&`²CL~€ ˜€ ˜lVÏ“Û_ÁLÀLÀLÀL2¹ÿ+˜€Iv˜|00“”˜œÀLÀÄ»;LrìÌ0É “Y�&`’cû+˜€ ˜€ ˜€ ˜€I.·Y0“ý`ò/˜€ ˜xÞl LÀLÀ$Êý‘À$ÇÎ00Ù&'0000“œ0ù &`&`&`&ktçô%Lü0y0ÿ¾a0ɱ3LÀ$;L~€ ˜€ ˜€ILN`&`&‘0ù &`&`&`&i.õK‚‰Ì“ÁLÀ¤ L˜€ ˜€ ˜€ ˜“éF00000É“w0009&ßÀL²Æä'˜€ ˜øwç“§RŸÀäŒÉÿ¶ÀäLÀ$ã�‰Ô01"û°ŠLB1ù&ÇÆä2VK1?µ­ˆƒ‰B“«¡Íd[Lê@Lþ“-^þ¬„*僂[©é11ÆhûÿÌäæŒQÍé&Ö˜A×ðû¯?2Àd}N~}íÍùöÏÊšüó˜ –|{›(Ÿ¶T‡cÒiÏdÆÈÄìÎ3EˆLž¯Øèöåiz·é%,Mfpz}œ÷ïÏŸ×ÀôçÿþôY=NSGÞíÎÀŒIõû÷·ÀôÏtÿIŸ¾­NÅ··»ámãA¹qSLL–¤¾šã¯PLž¯B‰úyäýÒ�žÇæ“é¥ë^‚2¨jmÚ:d#êZýŸÌáûŸ?u=�G=¦Ï¯ë>‡j “‰üµnêK¶ŸW:냨߯a‡³nO",‡ª‘² Loo¡9¨·æùç”JMÏ`LŒ7 gL|ëGQ0q¿Gm&öýfâ˲étà©3]D&“îšÀ,”�ÛÐþ93¡{ʘ&´ é60¡C)h´ ¦ 8ëòÄVŠçÅUš8m&Ò¯Ída×°4&J×ðÃæh÷cêä´˜T9`zòuÁ˜t*xG„c¼+• ÆÄ„îˆÆŸSÆŸSS.·â´AoŽ\Ø›ã�É÷€“ƒaÒcÒe€ÉçT+ÔŽnŽ´&b}LªÉfE09&EœSûÂd‹áô“mi`&Å„ksÀLÀ$Æ9Õ€ ˜€ ˜€IL˜€ ˜€ILÚ LÀLî 00000)¶LÀLî &`&`& 0iÀLÀLÀLÀd½s LÀLÀLh30É&`&`áœj‰L®-009còLÀLÀ¤Lh€000)“W00“21ù&`&`&`&`ÂX00“›'ú�I6˜˜Oô“í0`⃉“íÊÐdd2½§bD&Læ�SÍœÈäõ ]Ãß¿™ÄûBn ��¢íõ¢Éæ °Ûú!ÄÜôçÏôÖN=¼Á.oºÐǎ׺kÃrhd'Â2yü9/‘É“yìŽPa[ø1ĸ+þävqN¹âù–6ÆäwXš:uÔTÝuº¢¿Aý¶ÑÁ-ÊæP6¨à¦ó|wOî©Ú¶™ÔnGÔUò‘Å9Õ¶™|`òãÇ_G~l�‰៥i&“½9uÜ;ÝG1£±,´¹-¸ Õ1:1"ôæ$ïÖª-&ÁMò¡½9qΩÀÞœ“‹Óö˜ü�¬&&ýØðÏؘãLö0hm“sj&?˜”:ÎLö…ÉúçT &`&»Ç$“kst�%`&`&`&`&`&`&`&`&`’&`&`&`&EŸSLÀLÀ$Â9Uƒ‰'&<ÑLÀLÀLÀLÀLÀLÀLÀLúâùv Lþ0“|1yóÆD.ÇĬ�‰0“r0`&`&÷1Q`&`&`rÛfRƒ ˜€É½­”`⇉0“»[Id&`&D&`&`&`&`&c¢ÁLÀ$Ñ9ÕNc¢7ÇD<2©Áä¼+÷ð®\0Yý¹9-#`¿`2l³>&LÀ$6&fuL„Ü&b‹jÎôóAy¢Õœì0‰rNÕ“Õ‘!&fÄD FÌI}[KL†]òh5¢Ùà[d‘‰ .C&¼# m&³`Å“â*•Ž�‰º„³’5aÀDk¥”ž™ÜŒ1ª9æù:ÔTk” >lá9tm]‡bú´mü¼n�“Z笪Í!“ð”šØrª|ƈLŒöMc5Ç;ÅÀdb “½nçœ|­KCAh›¦mÏ‹¶Mí&Ú?¯§7—é͘ûõt—>MWF^-=½é§»UÖÃÂãm¿æþ�vÀDµ7oô Ë6ý¬õyÙvÌìòÆ�{ÓÊóæ\­nØ”fÜ�ËÏzøHÖ ?kW�ƒ1± ¹í>Ȱ±n]×+nΟ¨mεް›ßH[†>Þ¸|Ô�9ìŒæÓÞé÷Ê�™ýF¼É½¹ÚMÕí~kša?õo�­qÛ .{­¾äq™>º›åÏ'M=L¯]õeùaÖ�åç_ÍÄ•$µ ¦JO8&‹RÕ—\mìÎL.0‰™ é/+ÞÐ²Š‘\MN‹!’±ßá®O|xÓ*ß™!²%ª3ãt«ì¸~an§7çé�2íîNwŽ_"ýÔÆÅZäá ;·Ñner\Þ¾1DváaÛì9ÓgçÞPÃg1ýõ�­:¿a¿„;Mí.ûœû0Gk­ýù§úÏí^´Ã Õ¶Ã[Ó˜L}!»vG›¥ìW6ü´9×Ã*í [mm•¬m}ß¾²TÙ7ìDû†p ÚR¨‡7w+›þ »¤èÿèßhì­Û^·¬û,mmcp Ö•¶Ñ�P¢µo¹ëKîãJºeec· jkU Œpß)ʾpoÙ—¢U®ÿ<]¸éõõôFØ?¥›ÞØ¿…õnœî¾�D?]´ÚN—�h¿LoE¿ö&´M¥‘O‹«+Pº†;†GLúú‘˜Ÿ‚ÛLú;­©§U2ÙFÁÄû¡e¯vŸvhjîÏ!òÑl®§»¿ÔX ¹�>„îO}ÉÿÉtŒZ%†FN Bÿ†›Û ˜tFÞ¼q†È‰Öœ=·µoWhíÁÓçÌúðÂ\Vw•{5f&ûצŸ¬Û~qÝçæ6VôÈ5]0&.t±¸Éþ³ù+ëå²§·-Ðö�Ö¾¬]­JÛÏ&íì�›î(rm&¾èßÐ׳»ì†Ù­ZU‰Þ·¼{á¾ììõ0»¹ž}Ì]÷³‹FתR•©u-�²6•±>ˆþe«m_ÈÊÎÕŒÓu?]³«ÚN³Ë»évvûî°¼µÇN—½L¦_¾ÏNö³ÓÝK»vYW­›©V͈m&>&,ìÍ‘&NìóµÄƤÄ.X\a04�>žn>Oo?-/?¦7—éæ<¹Çäü†ߨϙ©ÑµËò �³ç•�ßhÎoèñ³ÝÏýü†^´µ=uzÈÍaÒCUcÒo»Í_ö[cúú•™“nàµk ÅÝR&͈�›ªíìÂŒvœuégï.³‹qöñ�LžÏîrw³‡‰+ýÆq0”~SuÃËF˜ôÓkݨ¶½™>Ìþ1ÝÍÞ¿ìú¥íìªÏýËìÝ%wK˜{#“©YÊ8“ßs0©c`b"`r�E&×¥{&�&ÝCLÔÝÏÞvW˜ÈqzLºkLÎ+SÃg©ûÎ_×�ÝçÖw;{ß�rÁ¤107³›¡‹CÚÏ6Î>¼ñ`öîáì¢Jww.îCéï>t_öÓ¿êðev}yy5»{ÃF.gІ—WöWs6Ád³AkLcbÊÁDßǤ›�I—“žƒY˜T7³«¯³o�‰Ð‡ &`ò“n%LlE£›‡I3 ó½ &í˜èÒ0™ºÂ 0) “.L ˜€ ˜€ÉÑ0›`"Á„6“0™ÕfR/Ĥî®`×ÁD̨æh"ÏÇp•Љ“'˜4 0éæ7ÀΤ«ŠÆ¤°'ú� ˜”‰IÕŽI &`&`&©0`&`â?LVh&`&`"ÁLÀäKÏ0˜øß¶1Nß0˜€ ˜™€ ˜€‰Ï0‘ÉZÝ9`&»Â¤Þ“7000Y«oLÀdW˜4`² “LÀLsû$ñ[LäsLÌCLLgÄ$&7.°PטÈaójOLÌ4&Í'LÌcL>t¸3hÍ SÕ­=Ï01ýì7˜´·˜47:¸—²×£ŸÞë Ä€‰¹Ì~¥‡µGŽö˜qö‹=C "ĸ´¾`2L¯'ú…M(&2i¬o‹�Š160˜S–ß¡‰+ͦ�ÀâK5ÈÜb!žL·šÇ]Ƕ¸wŸ‹{?ûµ.æ{*˜û‘‰ÝÖÞ›½11"3¾a­0Ca7u?Û¯ºÇ•@»¶«éªÏ¿1fÀÀôX\O7Ãô[,®ª9ÆŒ2Uç•Ù vÄÄ–nû†0gLS[LêÆN¯Í Cm§ÖgLj«C=bR»Ù]¨1ÌÞcbF{\þ÷ìrtéã›{¯GÝÙÿFLTs~©&rˆ-ì<ö¥ 5T}±¥Ç¤¯&9,t�ɇƒ=#6Ãìƒ�eŒ{æ`ÒØã¯ƒ‹FL¼M1±ç¦o ÇdÉZ¯Ò%"˜hͲç´ê1hÔ¹”ºHr r·®ÔîÝ¡‹èzº¹Lwn Á�øÈJZ.ô€‰Û�²®Ý—‹v@sÚƒÒŸ"Z»K�kéjÄÕøG=làð†-‰Ú.m7à ³º)M]×­º¼¡íUÝØ9Ô9³Ö½a—Uã"nÖë7:·Œ«‡Ûœlmm'êñ…ý)û.ǦŸ š¦ÑÚ¾pÓí[BßL×ÒþÒnÉa®¦í·ÉN·6ô²±o¹ýÊÜ ·N7½µ‹·öµjZ›Yã¦J;»�Á¾0î_ÛXLÆ©ÆåËö7ÕF6ýìö�aùËì}îö_k÷Ç0Õ./­njk‰´GÄ.k¤PÂÓšFÛ¿¤^6¦ÕvSú7´{Ù¿a “})ÝÌãKag2M禋þ }~Cö/åð²í„î{w•}i‰sÓ•ÍË~Õå¦×Oǘ˜¾d„•Ž˜tKJ¤Å¤/˜^)&þký¼ÝŒzNíÒÝ?Ç¿[êñÏó»öwóñçyº�³nÎ �§Û¿Z÷¢®‡¿ú?Ýß ¿†¹\ñk>ÍѶmÿÒþîßmÅðûú�vÈÈþ÷eŠûmsök°u¯Üh>—ìî;Eºi�ýag·o ÷–ý9,Ó¸%ì aO~ûÚ·¤;ó]Vî…�b³Sý¤¾Bî^¸¯i1Ìå´ßÎ`ÿsÙ¸¦q-Ý‚jh'Wý ûV?“reÖÔþŸßtS-»öŸrdöÿ†ã›Î9uyócª8¿¸]Ö6N°?Œ{aú7ΓÜÃïñE?¥ŸhÜn™!¹?Ýç¤îN¿$÷¢ÓCéêu—7\ivJ?NýLRL–¤¾ÍÄ7EÁD…%ûí¯üž;|Ïš�_õ§¿ªºþ4WU]¶¾IMýùõçw¾ÎÞL§öË7¯ÛàÔ 2`!Åù�A÷ÆÀJÿBŠ�wÇ…Ä �ŠŸôí+}g}û*8�\'ýôå×7Ü—³¹úÊ3w¿®ÍÝïhKž •w[ŒÈÄhÿò˜°6°bèZûÚºŠ“.†œ…ø,Ë=‚Üïz‹gSû`'<…crÑãªOàöÍëö8qýcœOe�¢`š‚" aÙˆ;°h˜m&ew 3ûr¿�¨åù¤:,EÁ¤uõ ÀÈDÞáäqgÒ׳i…hdî¤X˜˜´˜ÇH„ÞÃ8ß�7"^hâíILê8˜D‹L‚BÅõ#�Õ“Ä‘Iߎkrgb…‰è1ëbR•�‰È“`)$Õœa´D LˆL`²vhR&M0&-˜ä€‰–q0áNk 0ñ¸I˜€IÃ8sÁDù–Çâ#“Ô¡ ˜€I,L4˜$m€•©[MÀL"ar¾¾L’aâós0“|1ÑLRc’¶ÕLÀ$&— _Ël€;h€Mš€ ˜ÄÁDK0I�IÒV0“˜S8&r˜$ MÀL¢D&·÷!2I‰IÊÐLÀ$Jd¢$˜ä€‰lÀLÊÆäê&¦`’“„¡ ˜€IL®ïa &I1IØj&`“ËÝC˜¤Æ$]h&`ŽÉÍÍÕÁ$-&éB0“pL4˜d„I²ÐLÀ$“Û§¾€IbL’uè€ ˜c¢Á$+LR…&`&¡˜|z˜¤Æ$Uh&`ŠÉ§å‚IrL]< &`ˆÉççä‚IrLÝr LÀ$ ó)0“ 0ISÑ0 ÄD�I~˜$iƒ0 ÂäK`&Y`Ò€ ˜†‰1L2Ä$Ih&`„‰“,1I1¨LÀ$-Á$ÏÈ$A,˜€ÉrLÌ�ÀLòˆLTtÀL"“;� ˜d‚Éö¡ ˜€I@d"Á$_L6MÀLcb4˜dŒÉæã`ÁLbbl%G�IƘl]Ñ0Y™˜ûåL²Ád㊘€ÉRL´“¼1Ùx° ˜€ÉÒjŽ“Ü1Ù640Y†É#KÀ$#L¶mƒ0Y†‰“0Ùô‚?0“E˜< LÀ$'L6 MÀL–`b´“0Ù²{LÀd& LÊÀdÃ6X0“˜< L²ÀDƒI‚Š˜€ÉL´“R0Ù®¢&`â�‰yVâÀ$3L6«è€ ˜øc¢%˜”ƒÉfã`ÁL¼1Ñ LJÂd«Š˜€‰/&æyy“ì0Ù¨¢&`⋉–`R&…&`&ž˜h&¥a²Í¨z0?LÌTië‚1Ñ`“m›€ ˜xab´“ò0Ù$40ñÂD+0)“M40ñÁÄL—50É“-*:`&˜Ì°LòÄdƒ0L4˜‹ÉúƒMÀLæc2'0oK‚1‘s0Y_“}`"Àd LŒÞ/&r!&"LfäЂI!‘‰Ú?&z֞̓%7G2c¢ga²v�N˜´-˜”€‰™WÎæÎ÷ó¦ÉLäBL"Usä‘ÉÚšì!˜¬ŒÉ¼JŽÁ˜È4˜ØOXõá—ðJJÇh€Užký¼ ýNŸšÍbRç‹I3`Ò¦ÆD ç’&s1éOøÉm¿áËF L<·Á–Ç!21n'ÎÞÝýÇÄ„u{x†Íy¶©Úî”Uc“ú™3îÇ#ưÄþkÃL° ŠpL!�VI#“©sÞŒ'¶ ÙöGïm0#&~©ßeÁ˜ü6]`2ýÿ3îÝÛ÷$ŠÌŸHV÷ÿ·²­I‘Z¢§B8iÖOÁ§õÌóúé)Þ»(õÕÿÂ1Q§°4>ù]£šÁ‡xiÒSa‘Ô¢"mt'+‘ì<èËØœðËUÜ·P@ɰ« ÇÄx‡Šç®aåQev_éº ÆD¶ÍKHjOcCÕ“æ’s�^';‡L7‰‰“ÍR›Ì’¾}OÎišR¦SAeÃ�ˆÐ5¬¤WCÚ¥ÍÄ»õ8Bd"Ã,yiNs­]š·“�ES˜¨Lv�‰ñé 1�hÊFLü{WÓ §ÅäÅ“„š€ ˜ø•°®;5�˜Èí­¥ÅäeKLú LÀ$Qƒ‰OᲘ�æíP˜ü³-&¢Ÿ&`’¦–#7ÇäÇ¡0ù½id"“i&GÇÄ÷Ñ¥c"ö�Iªf09|d¢¤“}a’¨ÙLŽŽ‰o¿Õœü1Iš€ÉÁ1ñ˜€I´&ŠÈä°˜¨Õ‡›€ÉQ0é¯î“ÃVsÜc` ˜€Iœ:Žê)“Ãb²¶&`r˜ÈDI09t5gõ�õ`rLŒÃ˜“þ)©`&¡w“ÃWsVÖL�Éù&`rtLÖ¼W˜ýA˜´š3ª²¢&`rLôÕ˜“5c09&Z‚ ˜\ß�LÀ$`€ Õ0ùÐÄ€ ˜ßÀLÀdµØLöމ–`&Ÿü:š€ÉÎ1Ñ LÀäË�_e(,˜ì“O–€ ˜¬§ ˜ì“Ï–€ ˜¬§ ˜ì“/–Ð5 &—á&LÀd¹%`&+Æ&`²_LôÝK4ÀL.š0“…–€ ˜Üìõ>Ó`²WLŒ0yÞò.âÖtÀd§˜Ü:9˜€Ézš€É.11÷-‰€ .ß&ýM¦ ˜€‰W?˜,ÄD}:S˜H0)£äZ˜ZÍ‘¥c"×Â$âu:`²CL´’` ³óÈ$¢&Tsö‡ÉcKÀLVÔLv‡‰~^¤ÀL¾jb¨æ€ÉÃûÐ?:§ ˜Ðfr¯SÇ€ ˜Ìlz½)7CÈל)÷¼åþóÏO*L<7ûSü£©nÎ Õœ]a¢Õ“S΢LðY™ &Jö…`îf÷= .2ÑZi¯”G5§s›â¹å7iÈáùÁ˜ÔOOïúdDM)ß&ÕmðwÃóÓEÍ9§& W˜˜¥©ÇdÁø¿,0 Æ8c}ÓûiIšü§ÐS'<Õ1ÒK iÑ!<ùéÓ%Òð¤0Y”ª¡Ä8/aÇÝt�Óý—&n«L@êsxô9ûa¿l\ißwúûå?Áéåï�ï$+ŠÊȃâ1üë®gÑç§>ÿ겉L<Š×Gd¢=+yÊäÒf"ÄZm&窠°_L.ý“ýëö¿òÓßÿŽÉßïaW�Ð>ÆL`åÁÆ™È 05“£c2Ë×›³�q&f«q&Ò`œÉ�4“Y–(¹Idr°AkR ¹÷ŠÎß`).“Ãb¢æ~ò�‡&`2£½dþ9&%§ïÄF˜ì<6“(m¯;k€åB¿`Çf“=s&±,!2áªáÙœ€ÉÁ0(0‰ˆÉ®;uÀäyXrò*RÇÄ„J{øýj&Qª8`&>œì³áLaâ' ˜€Éáƒ0‰e ˜€‰§&ï`²L¼†—€ ˜øø]j&w)Y` ˜€‰Ÿ&»«ê€Ip/˜€É’¥ö§ ˜Üi-9É–€ ˜xs²/MÀ$¼åLÀd©&»j9“X–€ ˜\0 íÄ0Y~àwÕp&¡�8`&~Oš€Ém/Ž0Ù“=i&KÂ(0Y¬ÉN8“X–€ ˜œ09[b ˜€ILÜŽØC¯˜œ›^ƒÏ)0“Řt{è#“sÓ+˜€I*L¤éÔ†œ“±Gø¤ÀLRb"Êo99:&çëú˜€IZLÊ{pL>.V1žÅ&`€Iéš“��jBj0“eÇ]Åh€í1)¼“øÀ˜ÜŒyD&ƒ[Ÿ©’IDAT`²øÀ›X˜\‚“w0)wøUÅ0ɹšSL?ñÞ1¹Pr’`&%c’?ñÎ1™I ˜€Iþ˜ŒCbóådߘÌP˜€Iþ˜dÞ±³cLæ´»‚ ˜”„É¥%6KNv‹Éû»×óƒÁLJÀdÐ$Ó¶“�bòî–€ ˜”‚IÎÃNö‰‰_T&טh0ñþøÛb"sb¿GLf ,Ù+&oo��‰?&2%&2&²8L.;ï`’™$‘bU0“•FÀ–QÙÙ&ïþœxgDŒ§DbÒDÀÄlˆI—&¢DLd~-±»Âä}±%™TsÌÑ"0YZÍÉ‘“ý`ò>ó*œÝ·™¼•ƒ‰6`²82¹­ì¼ƒÉ ×ó�–R°�6Q&�Óä÷oÙ„crJ�‰XŒÉÕ Øw0ÙòÒàu1É!2i&oeaò;Ä’}`"0¹æäL¢]œväQ˜4=&Ë=yë1‘a"L‚’�–XLTØQÓÁ9¨%˜ˆOm'é[OŠÇä= %RŸ*&§0KÚ“ÅÉpµ­•_²;=Pu`¾<ÙmPAI‡ç`º°N'cÒ7Æ–ŽÉ™’ÐÃ㌰_Íá9•‹¶ÿ¶ ³ÄïaËB�‰M¦óL&,-Xã×-˜1ÏÂOs¦6®s_EI9)“A’H‡ÙÄÉaµn‹d€ê³ s ÇÄæḹ\înñÔ‡83Ó$<œÔ¯ú¼ªeÛ>ì„á#$íÚ)“ž’ËÁ À}<žKs0—¢{xVÎûzfm<³fçûçõüå�¹ì7SÙÅ”ò®[jZ;íè°Æ²àmðofúÔêb"íˆSÒ¾�R1¹ê ¶)ÊYi²èsn‡ ýqÎJßEÌòXZ uhãgŒ‡Lîó°Þœó®T7ÙÞÁdá ’gex“|è9µ¬Q?zñ\Л3b²`]*™“(×QDÜÉ<)“;ý7 G|)¾ ÒŸS&&§ü¼"wÿQ>&âö°¥©íˆÉ� pÄ‚«ÓÖˆvÿâBÏ©PL„X†‰I‡Iø`øÔÕœ(;âö°%‰NŠÃäî°’8˜A™ò1‘›bPŠ!i˜D�Ln8y“òÝ çœJ>V”‹Iw`LdL¢ïˆÓiëð¤Lž^á¬Ìd8½’‰ ˜$j3YiGlÙY\&×=Ár·˜ˆ21 ¸,˜¬�É–í'%`2! ‘ ˜€Éó±�'¹cò>ëžG`&`ò<‡ ê;Ycò>“€IúØ¢1GÁdƒÁ'Ùbò>[0¹Ý`&O*;+‚’)&W”lwNQÍ“]còqï—u@É“ù!ÉÎ01`&ëƳå‡É’[Cƒ ˜€‰ïF£Ç'Yaòþ¾ðy`&`âý€ÑØw¢Î“IN)Î)0“aòÙ“÷½`²8&0“�qŠ¡d€Ém'ð)Ý9µL ˜€ÉBP‚Ûd“bòþÉ‘ÅÏ«0“°"t'ÄäŠs {𠘀 ˜„æ`ômŠ7*I0ù�£r8§h3“#cbs8ÉO6ÇäKÕf�›Ö� ˜€‰gÒ—ðiœìlU¶Âäf»N·m$"—ÁLÀäQ£ì,TþÞ“g’€ ˜€I.Õœ{�²_UI�Éû�#W†œ¾œS`&`’å�¿}šõ³%&?‰D¦{~ÁLÀ$Lž–€»žÜˆ²&÷™8§ÀLÀ$kLn£”÷;)&_3>�æDKó|00ñÃäK­çV•¿ÿ~‰˜F»REÙ•‰w„ ßJ¦Þ r8c¢µòJÚø°dcs�:ûñC·ÁDÈ!ýŽÐá;"|bìJ½‡]iÒïÊ%;B�˜�H$Rp‰Å> ‘HáéôÿålBX˪gIEND®B`‚chafa-1.18.2/tests/data/good/card-full-alpha.png000066400000000000000000001133321517447374300213340ustar00rootroot00000000000000‰PNG  IHDRL;P�MtIMEæ(©S¨ IDATxÚìÝ}p]ç}øßU‘‘Mw":$}oÁi)ÒªHÈ¢€Ô+�@–›™ÈŽÆ’å‰,;ö8©[oß,gÒÄIíVÝ8�ÒxãÄÉÚVÚfœ4®ÇId¹Mz›™ñhùR)Ú%E ‰Wâ |aØu)kµöð\\\¼ß—óòùÌ`€î=Ï9÷œçùÞßóœÊGþc¯ï½uw ïŽZ-ò¦>VÏåóÆñ‚}€~¥6ɦ¯}õ¡¨Œ~öÑ×wþ³›§íb`¹ "U*ß=÷Ý×kýµéˆ˜¶c¼ú”ñ‘ÚžJDT*ÓÓÓ¯GÄt}¬>}äÈá\Wšlݶ=úkµ¨õ×âØ±'#"âÔÉ¥;h·nÛƒƒ»¢>V�±z½”í�´…v˜q÷=ï�ˆ™Ò²²j>G”ùuá\é\é\¹ð¹Ò9¹2ÝÎÎÚÁ9Bª¯�KÛRI“¾ä?R©ÐôøÙñÜn`írºuêä‰Èó¶´c �°En‡‰©ÉˆˆØ°vݬïW7UãÔÉ18¸«ôÇCuSuÖ×em‡ô9¢ÌÇCóy¿¹-&¦&缞Š~®tLD)Ï•ÍÇzú\™töÊzL¤Ï•Em‡dÿ'ýˆV}‰ä\Y†þ”sD,é:88¸+jýµ8rä°þTɯ�ãgÇã§ßwÔÇê¥n‹æqFžÛáÒø±’œï""úZíøÈéôœñ³ã1V¿\TæozPôv˜ï‚6~v|Ö ¸Ìµñ³ã�“yÙÛ�ÅÏe KÒí0V¯Çèè3¥Ùv¯“ÖÇzr®Ô�/Å1‘ìÿù^÷££ÏÄÖmÛ]?SÆêõR´ÃB}K} ¯…ÄÄÔdŒÕëÑ_«•>8J÷§òÜãgÇ+ÍPß??�ǃ–¥·C™ÞE.»ê¦jcPÝT-í =ýÚØºm» ~ÉÏéã!]�H¹•=,ÑŸj}LŒÕëúMΕsÞI‡ä5Qæ~eó5#ÇçÊJ«oö-òKÓy=hË<ÿz©„%åᑹÊ|Ž0º|LOÛ+»¤²¢Ì¡jº-˜Ÿ… g·ÅXÝu#ç*óýGß~9W¡IzJ—GÂ2Wº„T‡ofaK¡jŽ ©™®¬Ð¯$ÂݳZ�=½6r«²Ðö-ñ�ä®Òdë¶íæ£°à €Òª,ö}ËøcÓÚ(Ú€Y¨ ¥SYÊõ-ó� MÈÕ`Øâ\¬„é8PX•¥þ`ß þ¸Ð(Õ%$Ü%‡fÖ0@ÿ¡�*Ëùá¾>ˆÐ„Ü1ý ˜çö(°¨Êr¡¯h- åc>:ÓóKn¥›Le\NuE/§?Î÷تCÚÇ”Õj•&€AäP:hغm{㶈[·m�S'O4þ?¹õò|{£¢“·�LBžV»Uô©“'æ|/½­éÏ˾8OÌ­q{å\¨¬ôÛQa"4  Ú«0šC�tè18¸+wåb»ê¤.Ö�Moã|ÁË|a‘êÈ�Êj~¹]Sr„&Ð#­ªAZU~x¬µVí’T𤿀%©fIW­U ç––´ºËj;×0šÀ2¥/ÌÉ »ÕB¦ÍSh"f‡"Â�îinëäëÁÁ]‹†)Íû¸y?Ï×�[ÊÏ •vü‘v/ú*4€%š˜šœ3®nªÆ-{‡gýœ`$?Ú¦4”À²TÚõ‡:q—¡ , ©©nª¶¬™oðM¾µ Sêcõ9û>¤˜ÚËRiçëÔm……&äÆbwTYÌBÓ+Z_D B«c ù^:HYj5 ”X¥Ý°¯ƒOVh@fµsšÃ†µë#´]ú¸™ojÏb ÎZÿ€’¨tâ�öuøI M(œæX­1B7-¤¤C”ꦪjŠ®Ò©?Ü×…'/42ibjÒ»®%ßÿ‰V뇤5W�¨!‹’ãqµSzšÏ‹Î•dX¥“¼¯K!4 Sš€­ná+ !Ïš+Q’fÇêõغmû¼áIº‚ 2¬ÒéèëâÆMÈŒæAaúV¾Ѝ¹eppWDDÔÇê³*PÒëð$Ÿ�Ž>£Ê€,©tãAúº¼QBz.};ßd™ "ëcuA ¥’>þ“¥ÙÀÀk¡�•n=P_6Nh@W¥§Ø,V=",�ËúkµÆkf¬^Ÿ÷n<Ð%•n>X_�6Rh@Ç%•$ýµš V y”tx’œÐ%•n?`_7Vh@Û4W‘H ýÒë $·2NWžOè�J/´¯Ç-4`EÜÉz/Yÿ¤yY mÔ•°¤Õâæ}Øø¶†&cu‹õYzšM2`²! 4ß}GxÀ t­²dbjrÎ]û2Ò*Mhi9 ¶Ù‘~�6/+<�â¼¾Ë,9·Ñ1•^?�¾ 5†Ð€ˆ˜{Û_k’@qUýµšÊSÉ“èËX£MJªU%É|. Ÿš_Ï­nY,@òÂrSÉÊéË`ãMJ$]M¢’Êa¾Ê“d¢òÈSr:¢’¥'Ó—ÑFš˜�HKŸjý5•'åTÉÚêËpc M ÄÝm€¥JÎÍwÜžV%‹Oª/ã�&4È1w¸V«>VoÜ®8½`l„à  *Y}b}ö Eµaí:�€c¤Ò!I„)7Àê4O×i5eGpÝ•™Pô±A^•&…@†µ Iš:í’>·Oô#�ܪdý æ©ÂdY¡I2Ç•ˆ‰©I;`ŽúX}Õ�aSn€^jµXl2eGx�i•<<ɼMÉYrh²uÛö}Æa°À@#½Àr4%B +çµZ-êcõFxb¡XèÌk-áÍYV ’—'šÇ5L MÜ [é$0¿‰©É–ß[ÊyC5 �·Á\«…b#„'°Zé5LÊ<ö«[Ëe*yz²y]ôÕš&Ë$�šåœ#¬MaP×|{â¡ °zÞ¬_¶JÞžpžï’Ó24‘òµ QnÉ 7ù\'Ñ9a±s„;ÝEÐ|ÞJ¾NO×qMVÊØsY*y|Òy¿­ðô|�þS'OÄÀÀŽ9ÁVï¬.(d¹Zc¾ç=0°cÎÀ§Œ��ê¦jc°qËÞáÒvŒÒí�|^Æv¸eïpéÛabjrÑsDòÚQMQ«é:­úÍçÊVýÊ2ö§î¼ëÝñè#GJ•ù (ý©Öc±ÅÆžI•oQÞÌN¶e‰çÊJ^^×éó]DDezzúõˆ˜®�Õ§kýµéúX}úR±ØG,ñçVûKü™9ûäe¸è·ÚÖdÑ3£ZiŽí ÚÑÝHÒó zynXè|èú©-Ò×Í2÷³ ú•Ë<&*‹|,ågÚñ±¤Ç©õ×f}]ùî¹ï¾^ë¯u*Èèx`’=:ÞÚ„¥v„ ÙÙ|ö qððÁؿ††nŒ�›·Ä‡~æC1<¼Ûy Ÿã­¶Ý Lš?úÒuìØ“�[¯åÐtDÄððîÆ¶|ñü_•ö€ý‰#ol|>~v<οº§4Û¾þÊC-ïæñµ¯>TÚãaë¶í18¸«¯óUKŸ#"¢ðm±uÛö9ÛØë[7?î¹3§õ2€YFFžjôa²–$‹Å–ñú™”§§Í-s?âî{Þ[úvhîW&S´Òã�õWj|^ÔqH²�鵿³ö•™±ØÔç|¯�cÎKÛ™M¯�JÞ�5Lò¸¾C2/lÃÚuQÝT�NÞI‡%GÆ/ÕI¬z±Ééû®®-UX’œ”Ï¿pù$–^½:9¾Ë8ï4yá[à.ß缕H÷YR«ÇÄÔdc`�62òT|øÙºf¤Ï©e1~v|ÖšeîG$×ÑZ-Ž9\êþTÒ¯l–´úº¨cŽéWŽg_z>ž»î-—¾9óϬ(í|qÛ ÙÎÿ5µîÇ¥sD%¯¯ñS'OÌzc1ÎZ4gtô™Øºmû¬5M’°äÜÀ›KqòÚ8úrlß¶eæ>yzÎÉjúâÎBoeÍñY'±j<7gÐXÆÎsêe KZU\eáÛZÍ]¼€\¨õ×bxx·[ÛöF?¢ìí�^§¢lã�ô˜£òÆ÷Äúx85☧ÍÖs�“êÅ™þäÏÿUü~슱z=·aIºßœî'÷m§] LG”/,I¶õÈèã�ƒ·l'¯é‹;g…&Í«ëÜ‹’ŽïÖmÛ ßÍAI×Èò�Èš¯‹ÝY‡bKW˜0#–”a¬1ߘcV¿{My€_SowVŠt' ˆ‚&M;f: Êhû¶-qâäéÒŸÀ|ûŠøÕOº[s�:y"ŠvBoîÐe9(™ç¼ �yÉ9µLÁÉ©“'fÍé/+K J¬RÄ�*T`Òâ�Êi/[˜½vE×o)Û~ÎCP²Ày ó’óksʼnAu9®³ÞˆKWÙ|ofÐU¢7gi©RÔ ë+ÁΚPz:oåèÄå)(I¨0Š0pL'E»öNLMÎz㥨ՙËéO™’CË㣼Õ%•"o\_Iv¢Ð Ö�cF^ƒ"¦§g_š*•ŠF)ɾ^q�Ô1’iÍSu\w�(Ô…©9 Ž(O`!4 DPR¼Ásò}ƒârìï•þ-ÇG¶µšªqùÎ Â ;j^s|Ñi9KùòµÛ[Ýh¤húJ¶S…&@® JŠ?x6(.Ͼ¦ØZÝUJ}^,xXR½X+Ó´œÒtTú¼t�œŠºÍóÝê ryN%IG(á5]%R.õ×.'�>rDƒäDY“B¿ísnàÍßwpÃbò°h�Š’å ";ÁÀ”^ƒó=žc3’sw}¬ƒƒ»¢¿V‹#GG„õM€Ü)Ý…§Ì&je�LÊãí�‹<@õŽ>Y9z\Çgö¥ÏåwßóÞ¨�ÕSu'P�>\±§å̹Ќ¯©GÑ×1)û”œR„&X‚Ö²xkD%Ù”Ò|L,ùZ¼ÂcÇZ(Å“^6"f­q"8²:¤,ë†[ä€¡ÉÆÑ—#úíXXL–ÂA ¸—¹Š ­R©M ,}¾O¦êM²«ùv£¤TÞœ�ˆ(juIiÂ’Vc�ɥ׸&zÙùÞ-(YÊɺÇGÓsèIOõÒñ&8)®äü?<¼[µ �©KP™6vbjrN0*0Iõƒ5Añì¼ö¹ˆx[ã�‡E>)U%¤µº±àèï…À¤™ÐJ¤W!š €…¤ƒwÔz@Xr‰Àd.¡ Ð1ÕMUÓo–{RÎà4w'º¡Ö_‹»ïyo;ödDM€®Ð±I˜ÌÓÖ@;©*)ðÃÝsèV6uœ9îÊepp—i:@W.5š`6�É}`MÅÖ�é8‚’Užˆ—X]ÒÉ�£…6Éd�VXR:Ö7:}iÑs Lé'k`%%PðÂ2‚4Õ ´Súš²uÛvÁ Ð.Ró˜,¡Ÿ£  &¦&ç|Ýî*“tPÒܱ%§=ˆEnéÚ­�p»*]²2poÇötj[:QU”åí-ú±VDIµI}¬Þø^§Bw„âwu4Áü&Kì;h`1ªJ Þ›¨Tz²Øk»ïÉßëÕ`¶�ÛÓîmÉúô«NWªíX+Ót€Õvo4ÁÂ&˸îk AI‰zøišH;¶ÅZ5޵�É*¯ùšÊAXBÍE :¹-Ky>Ë}ü¼+}ÞÑÍk›€îƒ&X�Éêé@� J(Âà5ýûYÈ®f{z½-Ëyü<†%E;Öˆ9×0¡ ”§û  VN`Òz�CS“ ®krËÞáè¯ÕZv4 o’kY² ìJªMÚµÐÂ’U˜´�Ðrf¾NŸª2ÙãÉY•Âbë�X»Â¾¡7’ëÚJ盧؛ @vN÷š`õ&í%4�œØºm{ËwÕª›ª1<¼[PB¦¶¶û†NH®u?ýþ»- ;Åk‚ö˜´ŸÐràÔɳ¾VU‚�,PFÉ5Ï¢°Pœn„&h�IgM G’µJ%�£ ­EíÚj¡[oݶ½ñ¹é8�iÂ’6˜t°¯  »’Οª¸¬Õ-ˆO�<ƒƒ»"Â&�aÂ’˜t–Ð2dbjrÖ×Ãû�C CB•ö ¹“T›$Ò&@& K:D`”RòN`0nß@kýµËwÒ(#�I—ú&šzo``‡jX¢ô-ˆ¦ã@¦¨,é0�I÷M Gª›ª¡¤ºvÁSÁ`ßPèkª»è@&Kº@`Òå~Š&€îwì,ì áö¬^² ló]t€®–t‰À¤ýMÝ!,qûÚ+}�G9¢A û„%]$0éQF@gݲw8úksç^ÝŒW*•ž>¾ýÓÝ}cÿ_r]½eïpãÖÃ@WKºL`ÒþŒ&€Î–@ zŒ•ŠA¹ýC5ßzXh�?µj‚î˜ô–ž´Q2Ç-ƒéØI;5ìÔ;óyQ«Çàà®Æ­‡MÑ�ŽÑéè�IúßšV¯º©ÃûU”й“uÓ»åÉׂ ¬šo;lŠt„ŽF L2Ò×°rÉa ôF2E§¿VshaI� L²ChËä.8tåä¼È: ÓÓÓªL.qh�‹ ¸By315Ù˜‚38¸KX’TšÜ²wXc¹¦Â${TšÀ"vÄððn QK½ÓF§cu—�Õï›t;Ú7Ù}í´»JÊþ!}ëšÀòNáš ;&Ù¤—ó°^ Y¨™ŽcmßÀü’»èX×–Ö­ÐÙ"0ÉpßEÀeÖ+€|²® ,‰°$ƒ&Ù&4�–”¾÷�ªàÈÒ»à*K²»o°Èžô­‡…&0÷”­ ²I`’}z8”Z²¸« ¤˜&¦&W4ìÕàOHbpž÷ýcßÐKÖ5�Ö§hM�]“|л¡”¬WÂBƒ??ûû†|ÜÕø\hBÙOËš Û&ù¡wC©Ü²wxV‡ ²0ÐìÆ`µÓU,* ´%dAz1ØÁ 弌h‚ì˜ä‹…g ”Cz1X� %#,ɉ+4�é°¤>V× ,ÜÓ¨Tº²¦H»g¾¿×­íI?Þr¾ŸÕý³ÒíìÖcdqÝ›2í²¯Ö_‹ÁÁ]qËÞa�dŽ “|RiBá4‡%*L(ú K˜à8ôœá²d®Å`)úåBä‹À$¿„&Kpü…ëânÍ�yÕMÕ¸ûž÷6¾–@ùX –‚–ä�À$ß„&˰aí:��AÉ�pÒ‹Á M(aINÇ‹“üš,"Y cbjRh’!Éœ%.LpY²ì|¡I7ûtú�‹÷±Y”°$'&¦&£º©:ë{³“­Û¶GDÄèè3�ŽìÄÔdæ;ÚÉsØcõR®} 4Y‚���‹n–�ëN¸ó®w7>¿eïð¬ùÁ�j‹ôë3}.Ù°v�°„FG«l¯E–&}�G92çzÑ�þKú±6¬]×+E̼ñÓæ”áš–ôã.¯7÷=ëÂJ–äyÌ50°#¶nÛ>k=ÅY�IRŸ>äM‰Kû…&‹Øºm{®�ív½.zõ:OW@µMu†7¬]wÞuGœ;s:FFžr¢î¼ë�à:Ѹ‹NRÍ0Vï]UCº?•„9eïϰ Ò…%É:Dys¥ûé}­NJ:õ¹%4Y ¸ìµæ×y7¬^�÷ïþ}œ¿PõW­‹;ïzwO�ɯ}õ¡}&vÌZp·ÛnÙ;S“qÛîÛâÃpž.›˜št«Ù¦svY¯Ÿë¯Z×xç·oÀ4�‰’¯Ë4ëûÝêÓ%c¢ÁÁ]Që¯Å±cO–¶O1SmcJμJSY2¾¦>+4IÞ -ʸ)¢Å¢¯ÉÚyœƒ70°cÎBó±�t<Ê´vBzpžn‡ˆöÍ-LÖ>J¤×-ùÆ76Ý"eÿ¾s:|½pîÌé¸é†¡ž=¾ F€¥©nª–þ ‡‘‘§bdä©8wætÜ|ëžXÕº–ý�NIÖîhîO•m}¼¤Üá�VÆêõ®¬•ØÉ1Ó‚k˜¤7.�«A�Ž>SÚ”·•&©AY}¬>ga.+žw§„%Ùî|Þ|ë �qn¯;ûÚqó­{âú«ßÚ”µ³?³”¿Wæ~åøÙqoz´æn8M¯�¼½.’ç¾`…IÞ5§�G_Žso.ëñ*4 ·©ÉxâéaIF%Óq’wè /Ò}‹ë¯~kÛûwú‹Kë_ Mf–¤ÆEz õ}‡•8,I”24©¬9Þø<©0qñëî‰ReI¶mÞr�F ·’>Æ™Ó/ÆM7 éçu™°döÐCWŸ&(•&%×ÍR^a Рɺ&!4¡W„%215ÕMÕYߘ”G©B“é‹;gU™pY'Ãa ÐmÉ‚¸BºLXR“rQiBÇK€^IB“Ûvߦ1èaII\¡ €åhu{0 ¼½vîÌé8xø †ÚF…I9©4¡mT–Y�^ÓD¥ ¢²¤d&å%4aEÒsƒ…%@Ö˜žC‡KJ¨P�‰Ež–MhŠ K€¬šÐfÂ’’*T`Òjm%4aE¯5a �eîžC›KJ¢Õy”"„&,ó/=�=$,2OhÂ* KJdbj2ª›ª³¾'0!QÈÐdçµÏEÄÛ/ÊÕ–y³ß�8wætÜ|랸þê·j–JX‚ÀXšg_z>øÜç5�;é7{„&ÀR Lhfzs<|°QÒ �GB–He ZšÐ ,Š" MÖ_µ.6¬]gÊ6Í„%Ì"0a>B„%@á$¡É»n�°„4a sLXˆÐ¤dÒï²<|0Î�9­Q€ÂiMTš”ž°„–&,FhR0ÕMÕ?;¾àÏ<ûÒó*K€By*6nÞâ–ÃK˜×šˆ¸\]’Ü: èöï;O<=S“˜C… K¥Ò¤ æ«.I‡%éUäŠlÿ¾qîÌikš”�Ê%0a9„&”T–LLM K€R²léKX� Ë%4)˜$,ùÆ7–¥•¬irÛîÛ4F± KX2� +!4)a ÀŒdÑûV¡Éb‹æ“ –E`ÂJ M ≧G„%—ìßw 6o¹&®¿ú­³¾_ÝTÕ8ù&,aÙÜ%J }�O~ððA·hòØÑCqððÁ9!I}¬®q DT˜°Z*M2nbj²å;"€֒êÛGŽžUiRë¯iœüQYŠ Lh¡I†¥WzOÞ–,, MÖ_µ®eŠ\–°*ÚEh’aéEʾü§_–,AúvÃIÅ®*“Ü–°jÚIh’aÇŽ=�>rDX° Ih’®2!ó„%´…À„všdÌÄÔd ìˆS'OÄø“/j€ey*6n>·ìŽþš “Œ–Ð6(¸ k×Å#G7.ö,ßþ}⦆b``‡Æ€’˜Ð)*M2bbj2;zHX°J¿ö럊/üÎ磺©:k�82Ae m'0¡“„&=615ßøæÃ€6¹÷—>¿ú¯>Ö5Éa !0¡Ó„&=",èŒ_ûõOÅGþc!4Éa #0¡„&]415Ö®‹'ž–tÈcGÅͷI Kè(� ̆µëâàáƒn ÐAÉSB(.� ݤҤ ž}éya @¤C�IW©,¡+&t›Ð¤ƒž}éùxàsŸ×]’„&ë¯Z'4éa ]#0¡„&�Ü>€îy*6nÞ·í¾Mct–°„®˜Ð+] MŽ¿p]Ü]’uG€ÞI¦D M:FXB×]¡ ÿ>(,è±ýûÄÁ㺩ª1 T˜Ðk¦ç¬’;âdǹ3§ã‘£‡cï­»cüìx)¶¹²æxL_ÜÙ±?諸W&d�Ðdª›ªñÈÑÃqîÌi��éE`v”&4éa =%0!+„&Ë4:úLvìɈˆè¯Õ”~/q¿i'm ÝrìØ“1:úŒ†(‰sgNÇÁÃãC?ó¡¸eïð¬þbú߬HžK5žK{ѰäR¿=wfª×ÓvÄ÷Ö¾'Nž.ýñ›,�‘§a±ç:+0Ü5ëß¼ÈÛóíÅA[ë¯Åààì6»»ñùüë|d½ãšÞ÷w/ÒÙÎÚqÒ_«ÅX½££ÏĹ33'Ø¡¡swŒå5èée[oܼ%FGŸiœ ÇêKŸÿ™ W*Ýñ~â鑈˜y7 {±Užt²=ºÕ�Í[{�ŸÏåâ–ŽoíÝÉö?;ç/ôî]Ú<öMòÜ?Ù¸yKlÞrMã8ÞÝè7Îôç³ÕŸܵ¢çtwnÏ@o›{N:öd|ñü_x^;æé��¥»³“dÐvìÉÌŒÑÒýëÔØ±ðÓpšÇTƒƒ»f¶]`2çxÈc¦�<çy}=räpDĬuò4ïh``Glݶ]`Ò´Ó}äHËÁZÑ ì˜Žˆ¸ûž÷F}¬GŽž5Ÿ.¹°v£=æ{¬$,I4wH²¾¯nºa(¾ñ͇ sÌtª½ú»Íû¼ˆ’9Ùém=a2ûÛ¾%rŽŒ<ÕPf½�“ãàü…ÉØ¼åšÜ.|�lCž^ÛgâÅܾŸÇóæÆÍ[rÙÞçÎœŽ›nêÚõr5×Öäë›nÊm`’ßS“115Ù¨m‡z)YÃdxxwÔúgŧNžˆG9R)Ë£¹?8¸+bÔ¸3{^:º>ÞjWž±È]ršÅÌÓBªãgÇ­c²ŒwÑ]*ížnul§Û ›í‘^À«yÝ’ù:%ètAsµCÚ>ïÇGžÚ¸Uà�ÇöÎE˰qó��±>{úñé>õ¥é”•2�1­B€êÅZaoµ»Üã£Wã­v<÷ôT�+Š~ÐB/~n!L»:N@oY°èäØ&«ãý3ò¼Œ…1ùÒô9h)‰é,�DZÝBØ»8œ�%çΜŽÛvßæMÉ.Jª‘s¢Röý5Vww·¢ëÓÅ×jÑɲlwÓݦ³ðœžxzÄ —?P$¦°äVEP kž�¨§¡ÉO�˜ŠC»�i À’7L2Ô–Ì£ìë—Ñšºw±Ëóªíí¦º„•È[x,ìȯ¾Vƒ:'vŠ Å”œ´én?—æ[@ލ,ibýÌâ3%‡2ëZhrþ¤°€ëñÛÂ’,úZ|s¦ä¨.�ö_ÜZÝ SLu(n¿’ìPaR|*L ƒ•&¦â”�»ÿ0B§_]|“»eeI}LeE+Õ‹5 ¿æüµÕ¼¤ƒÀft$41Êëük’k¦áPz¸¬­¡‰©8tBªL„%n+ c*�bztž ˜kÕ•&Ͼô¼°€¼QY)hmÅ¡‰©80—0 ýÚ<5GXMLÉ�6^°&¦&㉧GT—ôH^ûaû÷Xqè &°°%WšlX».ž}éù_ì T–À<&°¸%…&¦â�3ÂX€À–fÑÐÄTza…k™K`Ö0�6]¤Î�9­!èYh/&°<-+MT—ÐkK¬4QYK$0�囚<ûÒóªKÈa ,ƒ)9° ÉB¯ªKÈJÿh&°rÓç/L KÈ:•%°X¡‰©ÉxàsŸŸÖd­ŸšZËDX+dJ¬Ð7¾ù°F “LÍ�ÕSa+ðìKÏ7K¥ Y¢²VI`Ë´ÀB¯B² ’ô[—p›a`¦äÀ%e�O<=b¡WrÕ‡–O… ,цµëbbj2Î�9½Ø�ª4 LÃ�6˜ÀMLMÆ7¾ùðR«K„&tSe¡~¬©9°|¦äÀ�¿0i*@I¨0¡4V“¬' ½®€J:iIÓpT™Àò L` Î_XÕbYB:Áš%ÐA¦äÀ&¦&ãÙ—žŸï6Â�«¾-°t*L`gN¿Ø®°D¥ í°âÊSs`é&°€ó–táåš°¦á@—˜’ hcu d‚©9°4*L`Ͼô|»«KÒTš°*K Ë&0�.,ô*4`)Ú–XËgJ¥±œ ³/=¯Á€UY•Á(Ùfj,L… ´ÐåÛ«4 Óp ‡T˜@Õ%¨0�”‰©É^ÞG¥ ]¬,±– ÌO`)O<=û÷èåSš”[×§áM 5Sr u¡èàm„È&pÉO�ôj*N+*MÊ¥§ ¼ª2�¹&™­.š”ƒ»á@™’S0G_ÖMêcõE&cÕ%ô˜  ¯Ö_‹úX}Þ2ì]¢Ò ˜T–@†©0¡ôÎ_˜Ô”ÞÄÔdLLéCB… ¥¿(}P]À|úZ $%‰ùunàͱqôe ±ˆ'ž)JX¢Ò¤D¼£JQ¹[ÎÝ\%Ïǯ±!e6'0ñ‚  —sgNi“„&@®­¿j�Ð(*wÃ�3%§àúk5�Ðäü…ISqXôɪ¡¡í –u,7ÀjÕú�1(þس>V·èkÑ�ÕëáR;$%±�=TÔÍTiÒ†Áåú«ÖY°‘ÂËé $ù?È+S\ȉBT–˜}@ÙÇž…ª0Ù°v�€€†ê¦jãó$íôî* Éâ Ò1K»ŽíôGÖŽqÇ9p�MS“-CÊú˜1ÅW믩0)ºþZ-vÄøÙñÒmûøÙñFhRë¯Åù ¥¹3ŽJ“ Øhvãñ“5šO%�8®³ä¹ëÞ×=÷½ÜàóTõ�÷ÀA… W˜Ê’ù^ké7%Ë,y³Þô¤b]cšÍ L¶nÛžë�q^Ÿ§µj—$@)ú /oÇÄ5×½¶èÏxÕ#"â+ÞÐø¿ä{Ÿ}m*~ñGÖöì9~öµ©ÔWõˆëj¹ M~açoFDÄÞÊ�G¼9_Ïý`Œ_Øù›ñ{Ç?©£´‚ÿb¡M«ßºÑjÅ·ê°äü«{¢òÆÞoÈùW£éyjÙ¿žoœ!T)§þZ-nÙ;§Nž(Ìø±2==ýú¥ÁÕr?b…¿×öÇ©�Õ§kýµYßû§ÿãô‘±Ç§Ï ¼¹ÝÏ;:øóÑŽŸÙ8úr ÷¿}ú÷oûÙåþ~tðûíüÞŠ¾þã¯Ü7ýð×þjúº·<ßY·”ß]êÿ­ú󟚌ˆ˜|ûßžïgWú½Ž;öø_ÇwFò•$oܼ%.þäÛswß¾mKœ8y:ÖüÅã¹¹ÛÓ›ÿþÝóþßøš…KzÏ Ì…¶ëÖé‹ýíV·iç£_Ï|{ë–w/ºÍY¸ý|sûV/ÖbÍ_<Þ8®wÿðý¹ym~â§fìOÿù—ŸgݧÿüK¹xž‡ßðg�Ïï;yÎh¤¤¶ÿê�Æç_ûáš–?3}qgãó ¦—�I¥)¿ô÷“¿½àï¤6"*;¯}.†‡wW"¢Rë¯5ÿ^;¾îÄ÷Úùý–ÿ÷OþÇʉ“§+—ú6•~w±¿½œŸYÉÏ®äçüýêÅZeû¶-•ß¿ígÛò÷:ø±¢Ç™3%§>¦¬¨H’ù…µþZ©÷íå¾xÃÿ2~æ];>yÿã}¦m^NÞqgÄ'ã¿.úsßÞÿöøè�7Çû¾9µý“Ý?Ý“V>™ÓãøÿŒˆØ.Æëòoÿt¤ß–ÿþµ÷/é÷¾mçžÓÜ¿}߬¯þpàï5ýüý=k¿{á¾yžÇ=mÃåIµïh=öl¹&nºa(.üç+ ª¿½!Æ?>ѳg^ýí �ÏÇj"ª¿½!~7>q<'!ÏÇnÖ6,ÇjÛ½ùq[ý½êïüçKŸýÏñúô½:ueö‹·DDÄ/íüÍøÖñùŽ…WRŸwýxiß4œã¯DÄÖ¶­¶.ão_þÙwîüBÿàí±u[½±>`z|Ѽ®IÑÆéqKk¯æ¶Êúx´ÕØyV`rìØ“qêä‰Ü®w‘LËÜåM9räðL‡¤€ë˜$å~­¶-ù¿»ïyo¼á‡yipÿ¸¢GÞqçã/ÝþØL‰Þßù �B&‚‡<>¯¬?·ånCþüøÛ4^|nþ�õbïž]‹2ò<ºõœÛ½½-ÿ^!V�€bùÖñ{ã�_ùBì¿øËñ�ÿÉDÔÇê1V¯Ç‘#‡K·^b2Î0öœ8ŒÕë¹Í’<¡Ö_k;³î’“ç°¤¨�€¶Y¹¼öTü൧âÏþð'/ØËkÚ‡�¬~|ÿÚûµƒc 1…ö½o~ÇtDLW{ƒ¶ñ1Óû~ôSÚÁGV?Jš¤§<å}ü¸š±•±ç\yK’ýÚ¼þÊvkñÚ"¿˜—z²RY�yY„šþG�Oïú¯ŸÒ�1ÿþKß+}¸c×üã³"é+ÚA›Ì§cv»íöN‹ySufþÙ~ø—Â’¦.¨&²ì‹øˆÀ„Yöýè§âÎ Ú�L)õ¤±o¿7Þ§b¬^/ý�`ìY|W4/ÎC1•1MÖ-ÚgúâÎ8ðí+âø ×i úkµÂ�;û¬ò[eª0IªKXø:§ –ÅrÄÌ2Vw‡Ùæö(š>»•"JªK®|ýhDüˆiMh°4Â’”ï%ÞwßΨ¬9ç_Ýë¯ÿÈ?Ø;ÓãŸÐ6>|äçJÇØªxíRÝT�­Û¶G}ìrÔ×<¸Î󽤓©8é ,»¤Mz¹_kýµÆ>iµ�jýµøã¯Ü¦ãdÑ�½0sŽþþµ÷wìoo}9þ¯'®ˆ¿sMÄ'~êç""büãÝí(ýö; ¾uüÞxœŠˆˆ[ö7Æ.Íãˆ^�óšÇ2–‚˜mppW®ó„æýјäu‡×Çf¯[Rë¯EŒ:`[½°{õ"o~œæ¯ÿÞï�?ûß4 Ç~ì…ûbãèËñÎG¿ߺåÝñÎGÿøÒÿnºÜ¹½åÝmy¼äogd]üø?{WÄ÷z8%ggÄïÿ¸ƒ ¦/îŒÊšã Ž#²2^””§mf&ÇŽ=§NžÈíÆlݶ=úk5pJ}¬cõz¦÷ë^{*""Þ`wÑáë°&€…%aÉ;ýz|gd]|'ÖÅÓð@<Ýê‡ÿà�¶<æÓ14tcDD¼óºwæ›xùÿïø';²­¿°ó7[~üã*M`i,ðJ[% ¿øö±óÚÃÆžÆž=Û¯ƒƒ»_Ï LN�<ãgÇs¿£´³ey¿NLMÆ5×]^ð€ÞJÂ’‘‘§ºö˜##OÅÐÐ��rëN…$iÍ�1_€@w|ëø½ñ¾‹oŒÊšãqü…ëbý•‡Œ=s& Kò”)LLMÎY¨6˜ê.9ãgÇ 1gªÝm–Øk®{­ñùÌú%ôB²–ÈwF¬úÆž+o—… L&¦&¡Ú– |øhúøþµ÷7>yªgÏ£Ö_ëÉãþÞñONGÄô§ÿüKîÐãÇ»á�ç_ÝcŒ•3ýµZáÚåŠ¢í¤±º;ä4´yaÁWzí?õsÖ0è‘ï%¦/îÔÆâ™q…Ýê í5ë—iyYÄbë+Ú™G,“c˜Ÿ»áÐç_Ý#4¡«&¦&£º©:ë{*LÈ ¾�%2Á:&dIŸ& WÞT­7Ö/±à+az˜†*L gãèËVI`R0çÞœ»çlý²Æ”€ÖLÏ LLÃh¢Â¤`ò8%Çú%@³ó¯îÑô”À¤`ò2%'½à+@Â�rÈ � ]WÝTm|ný²È&tÝ^{J#�GÖ4 H¬Y°&ô”õK€ùXÇ„^˜�)þŒF çLÉ¡«ÞT­GDXð•¼3=€<2 ‡ÜøÖñ{ãýqJCÐS*Lè ¾óq§zM`@fYÇ„^˜ÐuÉt ¾óyðþW4=e €Õ³¦ YdÍòßɺ¸3*kŽkzB… @� =aÁW`©¬cB/˜’Ð^¦çÐK¦áP(þL¬ýà킞PaB×LLM6>·à+°˜«ÞóË�ž˜Ð5×\÷Zã9‹¹ððg4=#0 ³¦/îÔô„5L:|�×t�5K(´o¿7Þ÷ž™ÏÏ¿º'Ö_yH£Ð5*Lè:wÈ ë&M&t�;äKeáWzE`ÐÄ¢¯tÅ›ªu�—Y€•°À+åí<]Ü•5Ç5]¥Â„®yÃÿR#Ëò­ã÷6>?ÿê B×Lè*wÈ &M¬aBÇY¿eMZ±f @©0¡«ÜRX®ïE#Ðu2oúâN�@W Lè wÈ O&t”õKÈ#‹¾d“…`Êů£Â„®¹òõ£€\˜�yóÝ)gbjRãÐ:΂¯@»œuϬ¯7¬]§Qè� ]³÷®ÑÀйµ0ÝdÑW€õ4@!Xà T˜Ð1n) @^ Lè wÈ O&äJó¯°Z­˜Ð| «ZÝžZ`ÐÄ]ròÏÝs²ÉÝp Í¼ÿ•xß};£²æ¸Æ ãT˜4˜4˜ÐQoøá_jrG`”Þ/ìüM�Ì"0¡ã®|ý¨FÚêü«{4%0)� k×EDëûJwÊ›ªu ,êû×Þ¯2æ'†&5@D\Q+ÎÀvÃÚu1V7POë¯ÕAIœ¥2�å�{á¾é¬?GåúøôŸI;øXîÉšõÕúk�/¶nÛãgÇ»Z‰°Zç/Ì<×õW­Ìc``GŒŸ�ˆ™*“t;uj_OLýH\sÝkñê·FÄãv@N Ý##O•vûÇ?>ÕßÞà@Ȩ &Ö~ðö¦ñGwǰ;b¬^�ôxšËcÏ¿ã¯GÄpOÆŸÉX‹ËwEÄL!F^õ×j³ökß|;;ù:/�ƒµµ$knŸtjÖÉÇŽ¸;þèKÿ5Ž=þ×½yѾýoÏúºWÏ#'°KmÑ»6øëø�7ü�ñ• §#"âïœüÝŽ?âš¿x<.þäÛg}½ñŸÜ'Nž.õ¹aû¶-ñ'»:>pø?ʼn“§ç´Uw\ãk.‡¹G?Úõv87ðæÔã¿\êcâÜ€kæïÿdŒ~öÑ8/Åÿð‘ˆ�åm‹OüÔÏÅùþKíÐm~éß3ÿüݳû¯Zï… k?x{L_ÜþL&¸Ý&ËY¤§HK\´eÌq)4)оYƒÉcO6>ÏëZ ͉³÷kZ§÷ñ©“'btô™xì衈èþ;–CC7FÄ_Çoýû3ñÇ_¹/ž9ô¥Ò¾súËÿpS¼ÿüÅÌñðøæøÌœíÍùƒßèþcî;0ë˜øÕõo‹þZ-îÿßÿÍ¥c3JuL̼."~âWþeüID¼åÈÿ�óáx9"F>z tí°ñÞáîŸ ŠÿÂggøW¡Q IDATýL¯�‹ä9Îg±ç·Øï§ý¿÷ÏTõGüÛ‘2±zÕþ¯þÝ7Ì\Ãý—8wætËçÑܶK}®óí“,žƒný_®�ëÏmŽÑúÿÅËôµž>Çßëáqxó­{âÇßþ£ñâs?ßøæÃ¥�ªvç]wÄm»o‹ˆˆ{éc½{">Ÿìi[|êßÌŸú7–î8øëã—?èÚkãø §¶ÿ—Ø¿ï@O^Ÿ¾òoÆ©“Õ8uòD£¢¡[cØôì†Z-bÔ˜3b&<*š¢éЧ¯Õ 7ÏsŽLÉ™ëÑGŽDD´\üµû9ý÷Ÿxz¤§�Áç¾wSDD¼íú»ã ¿û�Òvt¾3²®éó³¥l‡dÿ×úkqæô‹¥ Kš·÷¯_þâß•° ÒíðÑ'öÄëýoŸx>þmÆÚaµûe9ƒøÿáë§ã÷þBÔÇêñoK~ÍL÷#ækÕ½Ö^ý»oˆë¾ô½x ¤×Α‘§â]·¿'Þvý»ã¿�)õº>·ìŽS'O”¾_½óÚç .bfÊÅÖm¯Ç±Ç{÷úܸù`ÜtÃPlX».FGŸéúsذv]üôûïv0¤ŒÕë�<¡ScÍNç ÍÓ‰úZ…%̓޼Hž»²¨Ùm« c¡ï­Tó‚²½î ΜH·ä¶£Jö¤y§oÆïßö³ñµ¯>äuÀ¬×ƹ3§KßÞ„ºÜÕMUíàxˆ¡¡cxxwãó²Ÿ?{}LlÞrMDD¼©Z�ˆî?—<tsLžÇL!yîé “+ Н[/fw)ý)í@Ñ�ÇD¶^óGn´3J8öì–>»/–âK¿âÝdšLk€U4ÁÌà¸kèOËQ¨ ôìQÒ t†µëfM�Õh•'\¡YÈ“dè$� @� a5yòL`BÇœ¿0iA, í¬•H7LšLšLè·÷:©Õm`¡�&M&tŒ{£�WrÅÝ8é†>MÀ2LicøÜçã�Ï}^§s䩨T*¥kãßò*�ˆ÷¾ïžˆ÷vó*ö0K¡Â„ŽÙ¼å�tLuSU#Ð1rçü…Iw礣&³qôe�«TøÀD€,— :Æm…È+� °,Õ‹µÂo£À Iá“so¶—€eQa,Ëøšzá·Q`R0*j`õ&×_«i �&¦&5#0Á‰ È�3§_Œ k×eê9•áÎ1eRøÀdãèË¥Ù™G_ÎÌöfíÄ´vþ‚pÀ9X�Ÿ˜z㬯Ëš”a;ûJ±G^Œf¡u?ò¸ ÷¿=""Nœ<ÝøÞX½· ñ Ý##Oõì±oºa(Ï¥×î¼ëŽYŸŸ;sº”m14tcãóÍ[®)í1qç]wÄøÙñˆˆXÕº¸ó®;bÿ¾z;MçÊõWͼ4~v¼´×Ï¡¡có–kæ\KËzýÔŸšÝŸºé†¡žµCúydÁuÏ}/ž»î-¥ Ê °�ÉGÖ¿-þù¥à`±ƒµúøBÿ›Ÿ=”|dýÛzþ|nºa(nºa(Þuû{zövDÄÌZ.ïºý=ñá|$&¦&cÃÚu¥™6Ô\ísÛîÛ""â]·—gûÓûµè9òò øÝQ«Ç-{‡cbj²Ñ¯)S?¢UjÃÚuñ®Ûõ§ô§.½èOe±¢ýºç¾1+8YÊÿåU²Mÿæw Lòb¬^�ZÿÌ ø®®-]' º©Úxç8 ×­Û¶G­ÖØ'½P›9&>õ¯uÖ×eõÑ_¼·ô�åúX=î¾ç½q÷=åÙÞVÇ|}¬ýµË¯�¥˜y·œs^}¬Þ š¯lý‰æþTÙ•±?Õ|Ì÷º?U«ÇX½�>r$cÏõW­‹ÊßÓ¯<.Ü9÷‡/5݆ Å9&¦¯z¸ðÇ}_™^äç_ݳàÿßý†‹]}>_ûášU=vú÷#"Ö_y(3aÉÄÔdT7U{z‹˜ �î¾ç½Q«Ç‘#‡cüìø¬t¼ k­T7Ugޱ{Þ;sÜ|õ¡ˆˆÌ+�>Óûºº©Ãû£Ö_‹¯}õ¡R´Á|nÙ;ƒƒ»âر'ã?ýÙ×fµ@‘=ðÙ/,éÚ1ß¹²Œô§ô§ô§¶uÛö8þÂuQyã{J³Ý—·õu�Ií­üøìot9YÌjš¹¿y{_�ËïŠôÂÀÀŽøôoýFDDO×0¹ùÖ=q÷=ï�±z=¾ü§_.í\Ó;ﺣq�/{;lݶ=jýµ}&žxz¤”kwÜy×QÝT�ÁÁ]±ß×㉧GJ{Låsï/}lÉçʉ©ÉܧNžˆƒ‡–v ý)ý©ùúS�=�=Ô³5L6nÞÒ˜•eÓw^ÖÏõþŸ¾¸3÷Û°… L®ü?~8ëëõcW~gžï)3Ïeüìxlܼ¥çƒÑ3§_l|^æá¹3§µCS;$!AÙÛ¡ìÇÀBçÊôúNe=WŽŒ<7oi|]æEÂõ§æ¶Ã™Ó/ö¬š�ͬ… +ù¿¼H¶¡ ÁIáo+¼~ìêR„%ɶ&š£2j>yâ˜ÐΕÐÞ×­ÃÛZ W8¤¡\69€öõ­è�ô-¯¡&‹’Ð,¹½r¢LÕ%e!0h"0h"0h"0hR¸À¤yá€åRa@j�F £&äÊÐÐ��Ž˜Ð1›·\£È%� @� @� ËQ)ÒÇGþc•éééÊC~µR´m[ÎÇÐÐ�•éééÊwÏ}·çÏazzº24tcÏžÇwÏ}·çÏ! =øÕÊôôtå£?ÿ±"n@[ø¶aµÀ„\X?vµF +ŠmX;÷®K… LêcuGm�U7U5¹0159ç{*L€¶(Ò›ç€&:büìxDD ݨ1€¶Ú¸yKË5' �&tÌú«œÀ€Îhµæ´“À€ÜQaB§ LšLš.0«×íU€Û¼åšÌ<—;ÞñºR­¦x.0é¯ÕìihânEÀB6nÞ¢´  o•;YYôõÀ·MÜHKî˜Z}vgñ�¿0Ù“‘6¬]7o‰‘‘§ì„ ¨�Õ£Ö/PdŽŠ&€åõ©è½õW­³è+W˜(,IMÉi}2)«sgN;.IÂïˆÎ•ÚX¾¤å ¨lœ+Ï_˜œ3„vH‡¢s*Lª›ªsJh²z6'Š;ìÝÚibjv¥I'÷놵ë2qÜ(©ž‘®òQñó_Ëjãæ-Ú¡é˜P!éµúSK»~ôª-Μ~1®¿ú­s¾ß�1Ȇµëb``GŒÕUp7Ø±à”œ,‡[;bë¶í³¾7+0iþÏù¾—%§Nž˜õ­a2[­·ìîÉþ8uòDDDìßw §mðµ¯>ä@ˆˆcÇžlìf KÞ)*{§ghèÆÒ¶Á™Ó/6*ËÜ3š®¡$¯…ôk¤ÌípþÂd郣¡¡có–kh—ÔÇê*Ú/õó{ݯ¼m÷m]ç´ï¸nÎ{æ!CXL:›˜ îšõo4?W'ó¹;»›©g²?²²Î�9�=œ¹ßGþcs¾÷ØÑC-kýù�5ž²øŸû|ËÍÍ·î‰3§_ŒÍ[®‰3§_ŒsgN7þæ}é�æüìr?y‹=~òsgN¿Ø20[îã7[ÍãŸ:y"úkµYïHÜ|ëžE·?½ûR?ÑüøwÞuǬ}Ùêq“mNþV«¿‘ü~ó~nõ7æÛg3IzRҺܿÑj›çÛÞôk2ý8éca¾ímÞÍm¶”¿±P»ÿÑ—þ(®¿ú­±q󖨏y˼ÇÎröÝ|ÇJs{4?×ôÿÏ÷ýt6¿–Ò�—>Næû~² çΜn¼6ˆ8räp£Ì¼ùøJï—ôk¤ùûÉ1›>N††nœUù¸”}Üê˜i~5_'æ{­¦_#Í#9.’ÿ?;GŽ^ößXè5²œsF«ëX«6\Éy§Õye¾6Û{ëîF;4‡ªKi÷ô9e)禥ì»Å¶·ù¸[èo-tMO·óõW¿uÖñ°Øy­U›·j�¥<þ|ÇÂJ·±>M¶züäü°P[Í·ýó=×¥nÿB×ò^øòŸ~96o¹¦gSr††nŒê¦ê¬Az·Æ<ÆŸÙ{vCß|‰i­–›w›ÒÏ™hùnÕFíj·…Ž“^¯�<2òT&ß1Þ{ëîÞÝ8¡;öd¬¿jÝœçzç]wÌüì?ÿ�ŸýÚWjÙx×íï‰��q÷ÿö¹ÆßÜ¿ïë�ŸK_d?ü��Ä-{‡cppWÔÇêqäÈá–�?4tã¬ÇO~v¾Ç¿ó®w7."ÇŽ=�>r¤e`ò®Ûßÿøÿ£YsÁÇ¿ÔVÉ϶Ì6?~DÄŸýœŸûòŸ~y¦£û‹÷6^#ËÝþ…¿¿V›õ³Í?—~7äÔÉs7ÙçéJ­æ¿qÓ Cqç]ïnüÿèè3sI»%¯Ñæ}–¼6“Ÿi~é¿1V¯Ç©“'æü�ô6�Õë±ß×ç<×ý̇bë¶íÑ_«Å‘#‡ãËúåÿF«íMöAº£šþÉ &ý\ç{‰d{÷ï;CC7Æ™Ó/Ưþ«Ý8—µÚwÍí¾”6kîÜnÞrMì½uwÜ}Ï{ãk_}(FGŸi<ÎÐÐ��çÙ¼ 7Ý0Ô˜všÞßɶ'¿“~¼ý̇Ÿ§�Ùä9¤Ûadä©xäèáÆñÐk½>oïŽø­ËÏå¿ò/g¾¸uwܶû¶¸÷—>Ö>ñ+ÿ2¶þÜßoýýmÛcï­»ctô™øµ_ÿÔœ}yÓ C�ïŸ;sºñ;û÷}=6nÞû÷hì¯ñ³ãñþä‹qó­{â¶Ý·Å‡?qï/}¬qÜÅ­»ãÓ¿õ±ß�xèÁ¯Æèè3ñÄÓ#±ß�Æõ!"âÓG5þÆ»nŸl<~r¼|ú衈˜™¢�~Í4ÿ��›·Ä‡?ð‘¸ùÖçÇ]ãoüÖoDD4Ú-ÙþÆß¸ô\#"zð«ñÈÑÃsþÆ—ÿôË�6‰ˆÆÏ$Ç|ò8##O5¶·¹�9:s½úð>þÀLø¯ýú§çÙäy̼žˆýû¾ßøæÃ12òT㹎Ž>ç/LÆú«ÖÅ'~å_6žG«vOþÆBíþ…ßù|<ûÒó�¿‘n³d[ÆÏŽ7~&ÙÞñ³ãqæô‹qÛîÛâÜ™Óqó­{â�Ï}>>úókoŸþ­ßˆwÝþžxâ鑸ùÿoï~cì:ïûÀÿF�6nl,'Næâ’3b RZ©d(r‚V*I•î Ù,YBe»n!¤ l�Ø~S`·ÝMëdÛbƒÛ‰d‹¢m´ÝØZıŠÀö‹µjŽ«ì"¤¤˜‘a“àÊ$uq&ä Ô"vm÷ù\ž{æþ›™ûçüù|€9wî=çÜçž{î9ßû{žçôÓñäé§cÿ¾¥¸õÞVÏ—)/úåøµÜc~ésŸíYV UÒx·ÞÛŠ•ƒ+qéÒÛqìØãÝ‹ù¯|ùÕ¡ëÿس/vŸwºþ7¾}!N_�w¯_ëÞ÷ ÿÛoÆgþÁg{Öÿ»ÿáwãäñõxãÛâcϾ{öÅîi¹ùmͯ?ý=mg~ü¿üú?öì‹ñÚ·ÎÇ/þÂ/vC³?úÖ7㙳ÏÄ×Ï=N_�[ïmÅÉãë{^ÚïÞøö…xæì3ñoþý¿ê>ÿç_xn`(3+ó® ?°º›76ãð‘£Ýk‘‹ßœÉõ`ñªÕnÅsÉÌ”sOzª�% ÚÆ�&é/‘[¥tRŸ£&'·Úß�Q¯é¬^ÛåÅ¥øÎ÷¿ç¨ÑÇá#G{Þˆ§N=ÑS’ÿ†"¬Oäûžäç–9¨Tò©sgzò‡��K—޸̴þV»5týù°¢Ýju“ÿ~ïÕü2wºþzôìûïmm{ï÷+ÓüÊ—_�Ïÿãÿ¥ç€8ÉõŸWÑÊÁ•îýÚ­Vßõ¦×1ݧ_û¥Û‡-cœ„?=§~Lj´Œîvüúö÷xþ9÷Gêð‘£ÝýbPyf~ýöÙô¸´­¯}ëüÀû ;þçÿ–(îÂ…·âÀêZÏvôÛÖ�´û ×é¾¾ýÚ==¾øØcÇï1Åç?ès/{~ŸÝ¿o©ïó»~íý°ûœ(÷±ükv`u­ûzæ�7.¼ÕÓþé5»pá­xòôÓ}ÛÿÂ…·zÞ·ÿñ¿>r4^ûÖùîãŸ:w¦ç½’ÖuáSou?|äh¼ñí Ý÷êá#Gãõ×6ºûû/þÂ/ö,£ûùñë÷«v«ÕS]—‚¹´Œ§Î�‰•++ݰ#ÿ¼Ò2Ò¶§÷]~ëë'âÌ™»ÏoÐ26olÆSçÎtßoׯ½‡ï]¬¦u¤e¤À$�¦€öcÏnÅó/|<^m£çùv²¬ç¹;öx·ÝÓ2Rè’ÝÒ¶¦6Kí~7ôþø¶vO_^¤vOm–^óÔîù×îëÿôë=ï×ôüŸ:w&þÍ¿ÿWqîôÙø­ßøÍî¿é³ùù>ÿñ?ž9ûL÷lÿ¾¥¸wÇzø£o}3Μ9>õV÷ß¿û·þ^O@ñØÃ�ô={ãÛâù>.Ü}ÌW¾üj<öð#ñ[¿ñ›Ý¶9vìñxãÛºËØ¿oiÛú9Ú}îùõ§¿÷[zmRuhz¿¥çøÈÑx÷úµxùÓ/wÛ?ÜMËôüÿè[ßìÙδíiì¿´þcÇ�_ûõ¿|/ÄOÏÿ_þË»¯Ë3gŸéù|)®?mkñùçןkÒúÓëžžÿËŸ~9>ñ©O6þX}óöV|åË0—u//.uƒåV»%,É…%W¯\î9ÞV)SHÇþ��I¿ ëªLÕtóöVlÞØ,Í·có²¿óð¶ÐdP•Ç,^Û&ÏÐ3­÷a4Å¿ ë?X l}àìdýÅû Zñöa¹ýÖ?¨üs·{§N=±íÀ>‰öt›UvûÅç�o·~ËÉ:YϳYabä¾Üj·¶+Fíƒ^³Aa¿÷Jql·Z=�í·¿ö{̰ßû}~ô;¦¥õ¾{ýÚÈe޳íýÚoœmÏïïý¶}7_ž¿HËHAU¿m/–âïµÝÇyL>¬ÉŸ÷æ« V®tC‡t¾W<Χuÿ�¿ùR|æ|¶¶¬\‰¯Ÿÿz‘–‘B�~Ûž¤ $-#=ÿâúó“¤õ>uîL· ,¿þ´Þöä·=}�–›BŽâ¶j÷7¾}¡[UÜöAë/n{þØœ–Ñôë�²\«¦ bäµgU2…´íùÏáëôf1�Ôö “2hú@Š£."¹{ÒP•iY.Þvð!´Pöí¯j»O *¬�>;ÝÖ´¿¨&™þ>±Ó×lÜÛwd÷{ÌN®g½ÓÚÖQÛ>ê1ùªËw¯_›Ø¶ïô1ƒÚ=ž4jýî;N»º°K�5Xc>$ë·Þ´]Åð5çöraY¬"ÜÉóõšíe�ÊbÛEÜ ñ÷_xî7Η+ý\¸ðÖÌÇê–°Å™Y«®vµCF­h6�$U1Ío&«tAåâ¯Ùú…e4î—ùnle90½`€ú«]`âD`~¾LG~æ¦2·uqƘ¦_#B¦c·ÁÓñÜGÞ¯ís3:MÌ;ý,ë'ŒK(H‘/ëëO`PP›ÀD²r24CqÆšÕÖëë'jÝæã>¿âLnLGYfâLãgÖ¹KJÓÕ&0qa^^úÂt Œ�Y«[wÛ*tµ(s›·Ú-3"ÒH©KΫ_Óq£®çÔj€Ê[ÐÍpáÂ[ÆÒ Ñê^ÍD¹ˆÂ &L]YúÕfNfI`ÂL(� J&L�y€I0¡³$0©™ý�‡K¹]J稳äÔÌ­ö÷5Ô—Ùp€FÛ¿oI;3£Â¤n�’V˜(�ö¸ˆåôê×ê+L &Ì„©…€½0."³&0af”Ð{aüfÉ ¯åd€W€ã"2k*L˜‰åÅ%%tT†À€R[_?a\DfN`ÂÌ(¡ *&”ž_™5ƒ¾23Jè` ¼ a×âÅkçžÀäÔ©'âÔ©'*ý³Ž¹°‹¯iú7ëÜ-+óëæ$¹¹¦10qá ­N Mc`·4b=»óäé§#"¶‹óiéoýnvÿâߊ·§Ï©�=ûbÏßò÷/~N ZÖnÖÿùü+v€99°º+WâÌ™³¥½ft óÜGÞšDD«ÝŠV»UùL!ïÁ~/z«Ýê ª°Ã J†·KÚy‹·•ñD]`ìÄõkïh„ ~füòÿø?ÅoÿöRϱø—>÷Ù8wúllÞØŒ›··º;°º/úå8|äh|åË¿úO¥çxžóäéïÅoýÆovC‰T®{éÒÛ=�IŸKÅrÞ�=ûb÷¶Í›qáÂg#"âùžë®ÿ_ÿο¸þ«_ïV0~þÿJ<ÿÂÇãê•ËÛÖÿü ·ÌÉÉãëqÿ‹�y^«¿htý”~–lo·b›•ùËûa¯sO`rñâ›qõÊåî IÕ¬\‰ÃGŽê–“Óɲʼ¦+W\ø{æ3`oZíV<ÿÂÇã?þáïwƒ‘s§ÏÆá#G»ÁH^úÜ}þ…�÷„çNŸ�3gÎF'ËâëÿôëÛ3ìdåÌ™³=•$ÇŽ=gΜ�ˆˆßþíÿ½ïúÏ�>Û˜ä×ÿ�ïo¬}ľ0ëë'âÖ{[±yc³2סéÚ³NÕ“¸öÜØ8_é±dóÆf÷„ŠÞv©Êv–q '*M7Ø�ô�J¿à Ývë½ûÝçV×u»|¥P¤ß²ÒcR ßoƽ=-«Âä×_ ãÓ²òë__?Q™p€:šF7ÝY\{êéPÍkÏAÛ^³Fí¥;PÌŒI1–ìN«ÝêÛ=²ÕnõœÐ¦ ¢_ÐÐnµºÝAû…á“ 'ZíVß`&ßuÔúu¥*ì«PÓ¯ÊRpT·vyÐNÛŒ7sU¦\654¢²Ä 6cžØŒk·GÖÉt·„ x÷ú5�@mX]«ìuÀÝÏÇ?ó"ÖTí*L|£\�&³8Álœj¿aÝ(g=h߸Ÿÿù.EÃÆR`vV×UòËoמõ§K¥<`0_ãT% «™õª»Y_q (3_(QWëë'bÿ¾%•æW§qÀòU¸zi)›4މ.ì�n8#NF¼§`ð ‚ÞóQåî8fW«§|øS» ;mõI—½î€Ï_šAu9e¦K¥¤ìê-uÇ�²Ò%‡R:y|=Þ½~M‰4£è†PaªŒ)³ÚT˜˜R :T•S&ý2&”ÒòâRX]Sa *K*îäñõJo'Ëj5; ÛÕ¦ÂD)Wý êÉtîT�A_)­4½0P/UžN˜æÐ%‡ÒÒ-‡Ýpj¢Õäí–î8u§Â äê4V†é„©}éF¨ IDAT &”šqL•%µbvªB… ¥f¨—ÕµCÆ/¡T˜PjË‹Kñäé§�cÒL*KjHwªB… 3¡zœ*˜Pzºå@=r4®^¹Üèvèd™îˆ5·-0¹y{K·jãØ±ÇãÖ{[“í„%c2†I¯—?ýr´[­Æ&Ô_-»äd�Ì+K×¹Óg}ÈÀ¬¯ŸˆÃGŽja[`¢º„º9|äheÇ2™Âv/”õçæí­™­ëê•Ë en‹ªüŒóše�lâë]];4õç6�í®ã>›-:YVéýy}ýD©·oÿ¾¥RmÏ�ÕµZÏÊöžŸçö;Þìä}^¶}vÂûõ@«k‡Æ:!«ò¼{öň03VÞsy_#4%0©2a�vé§ÝjÅËŸ~¹²U&óþ@­Êú÷ïÛ¾Ÿw²¬¯ù$Þãóá~VûXZOÖÉúî/ó0n»ç¿É´í»)‹Î¯ÿÀêZÏkQõʼ2 ú|ýÚ;•9»°îdÛw»�÷rpeìãܼ÷Ùâ>—¶}7ƽèîg·_¶t²¬ûØ~ëÏ/·øše�¬oû;Ö—‘_±-Æ=¾åïWÜgŠçÃö»AÛ=èy÷;߸y{kè2Æ=GImRlßyíïëë'âÖ{[Ö¿·�¥vxõkæRiD`røÈÑ=ÜçmåàJe/�¦ùá]å×t¯ûÃá#G£Õn•®ÊdÜí No7òÛ’[ïõ¯hµ[ÿÆk'ß–OcýÅûîô›ºw¯_ë~ƒ¾‰µ¾üsuß~?°º¶íö Þšø7•Ë‹KÝÇîåÛÎQ¯q¾³N¶í[Ë|•Ã8íÕj·îï1Áo}ûmËæ�Íž¿¯\¸œbÅCÖɲNÖ³íׯ½Ó]Ïá#GnOqŸMËʯÿÝë׺¯Å v,ÞžÖŸu²…v«Õ÷uwY£þ–Ö3îr½ÿ½öÃÞ#㬿ß~œ“ßG÷ï[¸¬òMwÚîôøQí�~/îGé÷üý××O ¼¿ÇŒS�3h½ãÜ?¿mé=sóöÖÀmßéþ•Ž‘“¨ŠÊ¯'¿¼õõÝm_^\êÙÎô˜¿mT»//.m»}пÃ>{Ó~5ì±ýŽ%ùc×úú‰žý½¸ÞÕµC ›76n½·Õó~+~öç�7ãìSV×¶½fé±éö~Ûž?å÷õQŸ=ùÏšAç-ù ‹aaÏ�ÕµèdwÕV»ëë'¶U äÀêZ<öð#µ¹~tí9yÇŽ=^ùëǼžA_O�zBZX3­v+^úä'9®KþCìÔ©'♳ÏÄW¾üj)¶-}(¦÷ÛÆÆù¾ßfX]‹��óqæÌÙhµ[‘u²ØØ8?pÛ‹ߌS§žè†0¯¿¶Ñ÷~_ùòÄÕ+—ã¥O~¢û¸AߦüÊ?ùÕxþ…�w—û+ÿäW‡A©Ý‡­ÿÒ¥·ãÌ™û÷½xñÍ�Ë|å‹_ê>ÿôû Ŷtò±yc³û×j·†~ؽòÅ/Åá#G»Ïÿ·þÅ"âî7,éuHßòäÛÿâÅ7û®ÿ+_þƒ8vìñîÈòý¾5ý­ñ…xêÜ™ˆˆxýµ�mëÚ¼±/¾íV+66Î÷ ÚþÏÿã•xêÜ™î}òËÈï/ƒ–‘oû|È—–³¾~"nÞÞêÞÞɲؼ±¹m[76ÎÇá#G{Ö“ÿVìÖ{[Ýõt²¬ïóÍ·ãÕ+—ã�o_èÙŽë×Þé>—Nv÷u/.ãõ×6ºí‘ö¡ü2ŠÏ·Øfù×8­gyq©gù÷ë e¬\éî'©ížá¹n8Z|MÒz‹ûR¾ S§ç]¼=ÿÚÿ–¿ýÀêZÏóK'ÿéßü>ýü Ïõ €óÏ¥ß6ç—U|.£ÖŸÖ³¼¸Ô³žN–m{ŽƒÖÓïö´¬üúóË8°ºÖsÌÈ?ÿÕµCc?ÿô˜[ïmõ<æ—>÷Ùø£o}sÛúW×u“ßWò�þ…çbuíPd�»mP|]òUé9X]ëÙîâ:¬®uŸ{ÖÉVô[oZÆ“§ŸÞö…À�յؿo©û{~ÛÓcòœéù¯\éYFqÛóËÈo{zþiÛŠë-¾.é>ùíÈ?&ÿû/}î³}ÿžo³´Žâ¶g�,9Ú³Y'‹�=ûbO»íß·V×âÖ{÷«N_�«W.w»C|ìÙ»Ûœuî¿gN_ï.cyq)V®toKÿ¦Ç¦Ê²´îgÎ>�=üH¬\‰›··ºÿ/>öùžëYoZFºÞÉãëqøÈÑø»ëïuÛ0-#ÿØüú#¢»þÃGŽÆ3gŸ‰v«Õ}Lú÷ÀêZ´[­n»uèND_רŲ'qû$oÛÑïY'‹V»uç•/~éίýú?¿sïƒeœÇŽû·ÿ}ýDñö¸pá­a÷í¹íÞ}·-ÿÞÅBþ~}ßøù ‡t¡0húåtß|µË ûåO¦ÓýGÝ7ÿ~÷M'iyV×ú_ù甿ÿ°e¦“òTr^¬è)ž¼çKÓûUÿôûviÔý­sÐv¥¶J'ßׯ½3t»GmGþÂ!]´¿Kú•毮Šýû–âÖ{[K÷w²Œ´ýÚcÿ¾¥xãÛbuíP÷>ƒÊÇ­§ø÷|[æCô-ׯ½Óó¸ü‰ðw¾ÿ½mëÈ/cyq©ç>iYé"&_®�Ú/]�DD¼ñí =i™7oouÛ!-+]X¤Çô{>ùç’¿I�9y|½û­Ðæ�Íží;vìñn÷�b™yZÿÊÁ•¸téíîúòmU|L~=©�öï[ê¹=ÿ¸b°xóöVÜzo«ç1¯}ë|Oû¦‹Åâv¥‹©´üôzŸ;}¶'XM÷Ë_ü¥ÇåŸwÄÝoY_m£»Ìüv»^õ[^þ1ùe—“ì¥KowŸc~=ƒ~O�´ÌâzS—îSœB4…né¶âïé¶~¿Zfþ>i[-cÐv [o~™ƒ³Ûç›ÿVòê•Ëב¿-…ÅùÇäÃßüýóÛÓo]Åý}Øcú­§ß:Ó6æÿM�ñ¨oÜ‹÷-.kœ/�ú=v¯ëGq[O�z¢'èŒÞ1NîÝ·ç¶V»/¾¹Ðnµî-cáÞ2Š�]¸·Ü…{_¥J¦8uꉅW¾ø¥…{¯IÏãvùÿ‘»·½ùmg9»ù}·Mòö¾ûÕÿõO"báÎÿÒ°Ç�³ì�Üg7÷ÝÍý‡>~á§ÿt!">ÿ�~n"Ë›âÏ®ÖÓ L"âÎ+_üRå“3gÎ L �ÉÆÆùÆ&‡�½sïÿ;¯|ñKw~÷?üî�{Ûs Lúü7ç¶¾Á° %ÿ·A÷÷~ùpdÔ7 Ö1Îßwò¸Ýöû-G»}ü^—3©m/S7µb µÛûìæñ{+ NŠaϰÀ"ý-üŒc"šä—ŸÜ >ÿÅåç7j¹ÅíËÿ^|ùå4µÄ|ú…"ã>®8ìu;v³<³�ôÑ öb/˘÷ú#¢[Íš¯ªè"l !Òýîuí¹mHp1v’_î$“{AM7Ĺ÷þYx铟Xˆˆ…{Õ‡� L9ºÐnµZí–Àä^`’º;îp°úR&‡�]8uê‰îïßüóø�ÉK‰y_וƒ+qõÊån‰Í›±ºvh×Þ3p÷aÏ=u-H÷)þ>êqýÖ‘ïŽ0,dg» \­7&–ìu9»]o jf½þq�„ìuàÌA�/V‘4Y1ôèWÙ‘n+þ;( v¿|h1,H¶�ÅeoÛIÐ’ÿü`rvxLzL‡ªŒQ¥àd^˘÷úSH’ïþ=îŒ1{yìN–?éå¥n™©+…Eé}ÕÔkHÃYl¿öLûI®#j6Kΰo¦š,•"7Mz£f�¬Û—2õ n@X²ëŸâÀ‡ýBt[ú‰>ƒÖ�³Ü½n÷°Aã&½¾�þŒ;Pì4×;¯m(ûO�³ŠS`NúgÔTÑiàÉq¦”^^\ê¨òæí­¾�ë·ÌâãÆYWñyo+Þ¯¸}1`€K?ý¿}«ãºü ÿ)ììgçSWUq\¸âÅpSÃ’üµõ¸öì·/›ÿˆÚKÉxúf1U™0Ū’Y­‹þÊX]RùÁ›jÜ)ªw3•u±ÚcÜeîv]LÏ,+5ŠãqÌšî8÷™ ¤Ù¯½^Û¥Áï[íV<÷‘÷ßu Ž´«SçƒX¿²êA³ÁÔ@é¿ÕhPVùAgA—œíÌÎÓ<»ÒÌ;°�2\7½ÛÍ8^ýš:„Q3OV•W–ÆY^\Š'O?­Êˆˆ½��R#ŠT— g “úSaBcäK´ÓX&5©xXðê0IűK`\+W*´õë¡ 0¡1Š31ÔdÆa gÜÐ%‡5è_�Ç2€]KÕ%ºãÐt*Lh¬4–IE+LT–0Æ.�»T˜Ðhû÷-Åó/<§! Œ]ÂÞÕ)lSaBmíé×E'�eR!*K˜Õ%pŸÀ„ÆÛ¿o©*ƒ¿ K˜Š¬c�Wš­ßìºäà�qo,hªV»¡;�uóöÖ¶ÛT˜@”¾ÊDe S•u²ØØ8¯;ä¨0�¸[er`uMCÐHÆ.�íT˜À='�¯Ç»×¯•©ÊDe SgfèO`÷¤±LJ˜K˜‰N6zÀ×›··úŠ u¦K䤱L  Ruɨî8šH… >æ\e¢²€™§ºšJ`sœ1GXÀÌŒ[]M¥K˜1€&P]é0�>fàäñõx÷ú5¡ S§+L�1L`Âò]s`Z.^|SW˜"&ÐßÂ^üØÃ�Äó/<_ùò«Z€‰Ó¦O`Û-Lb!ºæ0-ºâÀôé’S²¼¸V×4¥+̆ ¸oaÒ rt!ÿ{,kÞm‘?Àšj˜Y9°ºï^¿Ö÷o«k‡âúµw4Rƒíß·´í䯮ŸNr�²ëd÷zMÇâ2£——âØ±Ç»U©š»©×ôo—ªî÷®»¿·Ú­ÞÀ¤ÝjÅSçÎtÿŸÞ¬eÖnµºÛØä dXûäf {î ù�ýð‘£=í�ßwf½¯(V¿®{Î ]¸ðÖÌ‚ªü¬Hi}é¶«kS]w1y÷úµî:ß½~­ûû°°duíP­÷…üóÞ¿oIל{ÒøƱh®&ž7Œ:—*ÃųץyûÝ™3gçzMÖïü5m[ú¾)ÇŒ~×ǧN=¡kRÍ®=‹Çü…;wî¼wvñ»|ÜÄדu²m·mýÞ;w"âÎþÎÓÞî˜âýc÷¹War'"î,}êÐ�V»5îãcŠ·Oò¶q~ïÊÚ“ÿ¤rËbסIO碧\6olÆ×ÏÏ&$ËCùÿÿÒç>�=üH|çûß‹?úÖ7½(À6ÓuÏêÚ¡xìáGâoüÍ—4FI”é\r^ç¯ùvès~½�ûÙéïÓ¸m’·÷ü-ëd �,[xõk,DĽñKFüLê>»¹ïnî?ôñ ?ý§ ±ðùôsYÞvµžž “‹߬MªÅ]çãÏÒÜîýðg¢ÕnõôMÿ–ᛚ´ ‡��v«ÕÝÖ¦×ÝÅ‹oÆ×Ï}&ëÊWÑäÿÿØÃ�ÄSçÎÄÍ/oéŒ<~0?ëë'ºÓ~;?hÆ9Bñ\1¢<ߨ§s×S§žˆˆˆW¾ø¥ž¿7éºãC�(ÕkSY'‹��ó•o“´GfÉIoÈü·Ûeï{”ïË—¾E?uê‰ØŠw¿Ã¾vç�ã;ßú^\¿öN<ú³o4åiw»áüð/FÄâïüíÖÝ¿‹•—.½=“}´ßû(í»i›Rw8'Cõÿ É„çIÀ P~.¼Ož~ÚùACÎòç«7oom;_,ËõYú¢/"âµo�oÚõF|÷ÏNFÄŸDDÄÉãë±ð^´Çý/¦ûM…]…1MŠc˜Dô™V¸xAY¥�Ñ6olÆ™3gõ#ËijX’žûÏÿ埸oÏrÿg=¯¿¶!4i€²¼¶+WìgPéÚecã|Ïùê óÇy_Ÿå·1}ùؤ°$=ß»¡ £ò„*å iÛV˜T�)®m¡ß�,âç*õ$„&ÍÒj·â•/~iâcØM{›#"=ú“xã•wâÑŸmîë·¼¸·~l?Î_“×i6º¼¤õÖ´´·®^¹\úÙ©˜Œ‹߬TXRü’º©×éyßúñÓvâ{PÔÏþÎÃqo¦œ&X¨Ó“Éåû†P?Y'ë;ÞÕso†jF`Rcç~>~§ÞOq¡nO(?°×ÆÆù8sæ¬Ð fÒ¬ˆç+{¾ M°-0©[Ÿ#jk¡îOpóÆf·kŽÐ >òã–¬\©T—hc˜@‰Ï ~òã–K ¼¶U˜¨.¡äšôd7olÆá#G»e›T›qK :ŒaB•,4ñI§©†[í–à Â²NVÉqK ©&TŞÒ*�Ï“¾…8uê {@Emlœ¯|œâ´ÂMwç¿þ~,ü…5D ܼ½+Wzn3† TÄÕ+—#ëÏ Šòã–ՠ„²[Ðw™j š.^|Ó¸%PAÊLXR 4¨–¬“ÅÕ+—5T�À„²– 4¨†4È«®8PMÊHX2Âæ�ÍèdwÇ3š”�°ªÏ ¯PA7ooÅë¯mD'Ë  PB�,–@Å©0¡LT–Œiyq©šðÛ­–²R€>R÷›¬“ÅÆÆùؼ±©ªH`¤KJ¬øŸ‚=sæ¬Ð  Uå^½r¹[M¢ªšG`Â$K*HhÐ_ê†#$�f˜°WÂ’ ôa/4蕺á\ºôv,/.uo×%šÇ,9Ðp)4hº¬“E'ËT–¡Â„ÝSYR!£¾Ù¼±¯|ñKñÒ'?¡±€FJaÉë¯mDDôT—Í$0a7„%5´yc3.^|ÓtÃ@#åÃ’AçJ@³LØ)aIå?à}د\éž$M€&¹xñÍ¡aI:WšE`ÂNKj,)B IÆ K€f˜0.aIƒ\½r9"„&@½]¼øf÷¼g]r y&ÀЂv«eÊa vT–£LEeICåC� P'Â`†–4\>4Ñ=¨ƒ�tÚM` Â"â~h¢kPu),1 0� ýKè±yc366ÎÇ™3g…&@% K€�˜P$,¡/¡ PU“KV®hHh˜40®Í›ÑɲÈ:™Æ*Ae °[*LHT–0–×_Ûˆ•ƒ+*M€Ò3°"„%ìP¾{N„i‡€ò–{%0AX®\ºôvDD74É:™à(…¬“ K€=˜4›°„][^\ê M„%@d�,66Îk`Ï&Í%,aÏ„&@Y¤Aé76ÎàuŠnÞÞÒ4†À¤™„%Ḻc�o›rX÷`Ö:Yf6`¢j7­p'3Ý)ÌR:)I¡‰°¤Z¯ÔAÖ–ÌÊòâ’F 1û¶ “fYð`Úáçãð‘£qêÔ˜º‹ß–SQ»À¤ÝòÍö�ï†sóö–Ðdò'+B“òZ9¸¢¨
aIŽî8óñúk±rp%Μ9!8v-ëds›68ugmµ[±rp¥gšÖõÛ ÿ4ŃigOIi¿7U;ö¸Wô>aIŸ¹ªîÛ{±¼¸Ô3^E¾¦ÙË‹KqéÒÛÝßÓ`°‰Ùù¿ JŠã•Ìâ\nyq©' V]Ò„sËây%ô»&ß¼±Ù}?¤÷Pöí$>˜þÓj·z.fòÿ¯Õ%ô“öïü~}õÊåÊîç{Ql‡y¼ܵ¾~".\xk.ëýóŸ¼Yçì\·€ñŽÙÅø&›ÇyLþœ1½ó>Ÿ‚2_‹Wý½‘?ÖötÉIƒ3Vy�F} U– Rܯ›6izo”áy§médYüÉw^zßüèÿŽ}à¯Ôîõxôg߈G6⯯œÃÚï¦ü_ýÆâУ}skNÛAYü_tY,úëë[�’ØŠøÑïÇW¿ñßÖòÙ ûœÿè‡?Ósñ2¯s˜~c±Ôú u vtSr´ïõÈ4ÎåÒ:Ò²‹ëLCìd[ªv­2l;ÓßT;1èz+ÿÞÈ¿�ʾïç·;ˆ>X¼SmºŠ}ðŽ{¼É�‰°dÄ›7 Ö”±K’Ô×ô¥O~""¢g ´y´EêxóöVzôþ‰Rñ¢ý§ÞÿÖÐåüø�ÓÝûýø�Ó»úˆø™­Gî…&Kq;ÞÕ ÷ÚbÜc°wé3½ŸÍ›Ý1ÑŠƒªÎò,ùÐC'âQ®/¼0ظãVɃu|‘2މ°„Zȇ&Å“'¡ LŸî8À< K~°Ù*]X4Ïƒš ’„%ìH¾/ÞÊÁ•ÒuOJ¡‰®9Ð Å1KRXR¶.8@³=P§'ÓÐ1LC«Ý²”\:AÊ»ôãN9¨žAa Õa,š¢v&5²ÄA}Wª6àm:qÊ�iaÆ ˜³ä³4,,Q]RÆr¡)tÉ©a Qæð$�(å‚�ƒÁ@ ¯ ¬&Õ ,¡Qú'B¨¦Q]pT–epóöVÏØ�“*–ÐX¦€jÓ¨2�I¹ Kh¼|µI14‰0® T�Yp€*˜”—°ròSG×Ê.}¹!,ªJ`RNÂècX�Õ&PÅn8U%0)a 1(4I'hB˜�~A‰ê Ê&@åC“]t`^̂ԕÀ¤Á V K>úáÏDDÄW¿ñ�4†Àd6„%0g?ØlÅÍÛ[ñ÷ÿþï„/zºéDN ßà®­v+²Nï|÷¡X^ÔN@3<  €¦iµïV�äË‹‡�$@ôܵøY Ð$*L¦Ke ”ÈòâR÷ÿzèDüùOÞê颓?YTm@S ›28}f4‘Àdz„%Prï|÷¡8ôèOzN ͦ@“ ›28}V;¦�€f˜L‡°*¢ß °ªMh‚A³àä?‹ã•ä«5êN`2y¨ âÄ)4I'”BêbXUI~Êà›··byq)9ªÑ€F˜L–°„ÒY9¸¢r'~ÃC“]t¨�qƒ’dyq)nÞÞŠ«W.Ç©SOh@ q&“#,¡”6olvC“¬“i�Æé¢¡›Õ±Ó d˜TuГɖPNtÆ3¬Ú$�| M(»Aã”ì4(h"�ÉÞ K(=}�w§_µI„)ˆ¨a ÀÞLöFX²ÛÊšqƒ“á ó7jª`Æ#0Ù=a •‘këd™î8{0*8€y”¨,Ø�ÉîK¨”Ô%§ÝjÃdò'œ\ɶ «Ê€Y›U÷ç@“<   þ®^¹l†œ)I'¢ù“Óâ7|0MÆ*˜&;£²„Êjµ[B“)I3ê¨4`–%é³iTªM"0Ÿ°(šDÜ×Ä,:L‹ª€é˜ŒGXŒ”B“tòjúa&©_—Ï–J&O`2š°[14‰Á {2,(IŸ=LžÀd8a °cýfщØœDOnã”p—Àd0a °gƒºéO„'ôû|HT”ÌžÀ¤?a 4À¬FùÖM'b,4À8%å!0ÙNXL\:É-'a*b€†ë’?+˜=�I/a 4ÈÍÛ[3«2IŠßšŠ ÙF è:èó€é˜Ü',fÎTÄÍ5lœ’üçó!0¹KXÌM¾»Nq`XÁ @= šýF@Pa P©Ú¤ßÀ°¦"¨>ºTKÓa P*ýfÔ‰U'6jœa @9590–¥”MŠ'ÖÅàDhP^£f¿””[Sa Pjù“è|xbŒ€j6 « ¨“ç>ò~mŸ›1L ænÞÞŠ•ƒ+¢ÂŠáɰ1N'ó5jæa ÔË­?ÝØç¾ðÓZ«ç³¼¸´í¶¦&�ª,yíÎ;‚�x@Õ ›Q'¢.8˜�:‡$ΟîÛ¼±© aš˜è†Ôæ$°8£N„Š€YkÂ`®*Ué'ëdÑj7»Zê»vÒŽPØ'ꨖ�I«ÝŠ­x'“°„¸y{Ë·$ÔJqpXÃÌÆ¨Á\Ó1šz‘÷èϾ!4)\ƒw²ú…&M¨0–}Õ!DËwÑ)ž°§àDµ ÀÞ IòÇÝâ±ê|qLá¢ó§ÿ4îüð/iˆš©]`RHµ„%À@uª8ê7«Î à$ Œ6N5I¿c±ÏÊú1† ýÜù¯¿ áE QSµí’ÓùkÙÂOý§Å­ö÷cçáF½¨·Úßïþÿ»v2ýÙ7ìéqèÑŸÄ|Î5ÚÍÛ[�xžÅª“~ƒÃæ/'1ðY¤š¤¹tÉ!ï‡x1¢wU&5T×.9 Å¡)¡I>,z5í[²âŒ:148‰žŒÈ5|šëúµwú_ˆæ¦Ú­sx2hJáº�o×*0¹÷â,î;y|=~¸ÙÌ “ÇŸþ…žß?ôЉøA4¯Ädyq)9ÚýýرÇZÇo†Æ‡%?8lqV�bõ‰Ab�&RM2ü³Óy„ê’QçÜoówõœÓ`¯«k‡v*ÔÉþŸúfDœéy¯Ôéј>r49W¯\®êóé†%íV+:-‹ŸúO?jä�ë;®Gܸ{±üÁGÁ‘üÞþM³Û!ÿÜëÒãŸÀݽߟÿä­ˆˆøè‡?Ÿ‰¯~ã ‰mTEÉG?ü™èdY\½r9>tP{9�Øéço½ÛáC�ˆ?ÿÉ[Û¾¨¬»þ?ÿ_ìß·”ûÒê›qëÇO7ªöÿÔ7ã©sg¢ÝjEÖÉ¢ÝjÕbÿÎO›½pçÎ�÷#âNñ'ëdwZíÖ�~»÷Cþ6ÉŸØÁýzÔu.èq¤Øé÷÷ƒ²´Ã°×ÄëÕ¼ýaÞû\Þ¿ýw¿Üœ$‚“úû™­G""âö¯½«1"bñˆˆˆÿ²ô=�Ñ  $…$çoÿ3ŸÍ{üðXãgÜûíõgW똌dŒUf˜äƒ‘â‹Öt­v˼Ïþ�Ú¥ß~3Éõ zMfù<Ç f$Ìb]ùu Z_ñµªÓûdÐ~˜?&äÿÍÿýßþ»_î;Ö‰ðD`"0¡®AÉG?ü™‘Ÿ™M Ü‹ŸýίëÚƒÎû=ß~çui›½œÏ6åÚ£_÷…Y_Ìò¾øÞèw^Y )ZíÖÜ“¬“- Ú¦ô·t[ÖÉÌ?±��óQ¹)³ºÝpRËS§žˆ‹ߌ«W.7¶�e±òšÔ&+Wâ¥O~¢»7}ˆˆ¸xñÍxýµ�Fž$§’ÁV»å1à‘ºì $Ö±@Õ’|P’|õ_Øö÷=tÂyeá3#ëdÝîIMk‹~íÐÔ󩕃+qæÌYçSÚ¡v×àù1›Zí»× ¦D(ý[Õ°$m{¾O]S¶Lí�O÷Ìßìý!"º�I…Ç(Úóðõ×6âoüÍ—ºíÐôcDÿ÷Çö)‰“~á‰Ð¨jH’ Èõá¼²ßgFS??óçS­v«ûEsÓ5ý|ª“eU½ŽžÚ1¢Êí�¶=?˃¾ \õæ¥Ùðôßšq_ UûµMþbXx¢â(›iM <άdu¾(N>O�WØî«Ã §“V‡ce¾ëTO`R¡)€½8vÚ»íÀÝvH#˜·Ú­FŸè@¿cD«ÝŠN–�|o Ot×ÊfTX²“ $+�‰wÿB[Ðï‚Ò5—6¨«¬“õ&±àµó¹éAAÖÉÝù©ïê67ºƒúlý`³¥»P:Óª*Áye^:Á]Ë‹Kµ?¿®Z`22,IýÈ9—.½Ýè‹äôíq“ßÀ`Ÿ˜¼tÑ‘‚“ü…I>8QqLÒ qIò¦’4ý|Šûò•ËMæ (št=]¥ÀDe ì’¾¦ƒ?ð…(»—¯6éw±Ò/<œ»1,,QI2ýÏÊ|¥*8wº/?è«óÊzªJ`",� ž0Iƒ.L>¸’�$6¢ƒìd¶›aÇ$`rT˜Pç}»?X·'iÐW€ù+[¼¸Q} "$�rSEA“”=0QYPq¦(†56‰.7ÌK™a @Í O !@�ºÙɘ$ýŽe�ïÝ ò¦žÊ˜KØ3ƒ”A¹gÛùÑþʶé‰óWB¨®�V‘�e”ô•z*c`",h�ül;ãŒu’P üv”G€*3KN=•-0–4P±Ú¤ßÅT„ª¢_P¢Šê#먬 Ê˜KnØ4ÅÅ ®b÷³íÀ|ídv! UP–ÀDXÀ@Å‹«âTÅ*O`¶Fuµ‰0» ÕW†ÀDXÀŽô06Ty’P`wv’ä߯P5óL„%ìÚ°iŠ#¢ï¬;ŸJšlž�‰°€‰Õm'Q�ƒívúß~ïA€ºk·÷ên^�‰°€©ê  ºà4Šð„ºÚm÷šqÞkPóL„%ÌÜ %a8¬úDxBì$(ùè‡?_ýÆF¾— ®f˜K(…w¾ûP<ÿÂÇ£ÝjE'ËâO¾óʶoԇ;S$P¡LöÒµ&ânXñ¡‡NÄ¥KoÇòâ’F(èdY´ÚBä:›e`", tZí»�É;ß}(=ú“øÁfkìd]  O˜µIt±I•#7ooE|8ºÂšjV�‰°€RÉ_¦AÛÒã¸È&£’íG¨Â¸ÆÙŸŠÆ¤ßþ^tóö–ЀFšE`", Òú]Pö%U�2ÎE𬕟ÙzÄ \BóI€é&ÂJéæí­îÿ;Y¶ãÇ�3ˆì0ºø4×�8Ý󚎎ìdÖš®dBØ£i&ÂcX€²“‹ß~Aʰ jaÊôüÌÖ#ñ_–¾·«ÇŽ Aö:(ë ýnÔíÀø¦˜K¨Œ4†É$�º`¨ìd ÙAÞB”ùØM7šâk¾›} ˜Ži&ÂaœŠ”~Ò“¥×M/ÆÙòrD,ïy9;[¤ß¾1O‡��Í›viÒ�‰°v!‘<¬;Ï$ÆG)†­›wC“ÿü©Ä_ý½5úuXü‡võ¸º¸zõÊeoNk’�‰°&`œ êI†*ï¬~,""þoZñæç¶â‰ßøB#ÛýÍÏ}&­þdf¯aU˜V€¦šT`", Rò€»™%gÞ†]��p6b{¨òs�½¯DD+Þý'ŸúØs ?¯Ýùã8·ðóqùWŸ+mýü«ñÚ�?ùÒ}Ž\‰ÃGŽFDÄŸ|ç•=½@õM"0–Pyuú}7ÎÞøö¥x}scäòSÀðÚ�?Ž®Ìӻ’mÏážÍ›qæÌÙˆˆ¸zåDlÞØÜÖVï|÷¡ÆU[¨. ©ö˜K bR òÁ•,ÞùîCqìØã1�Ù‚ª¦Õnõm«dyÑþMñ€& éÚ­Vܼ½Õ¸çýƒÍVOõ@1,h²ÝV˜¨, Òš�Œ’u2�4R¿.¨» LJ–t²Ì7d0ÄÊÁ•ؼ±©!€­v«ñ�ÉÊÁ•È:Î#€»v˜Tª²Ä eÍn¯ïExoÀp›76…%ŽØ†#€fÙI`¢NEݼ½åÃμ{zŽ TZapŒ€é70–@…å+LtÉ�íÚ­–`9 úÊv‡�mìg†cBï~ ]TìB�˜T6,QYw©0�þŸ>3`¸«W.;FW¯\ŽS§žp¬gT`R¹°¤ÝòíXñƒ èÏ _³/†ØÎ,9 /h¢a�I%+Kò³äøpîð‘£qéÒÛ�|îÆ0ØÛ±“æÒ…Ó{¡)& vÚjÉû³¼¸¤¯ilïgÚä±;Œa²½ôËü{S¿Mnú‰Oª.qŒàرÇ{Ž•ÍìÎ9êXéÑì¶hú±ÒìÎ#šr¬ì L9‡�]¨j‰öá#G{ºä4éÄgÐsm·ZñÔ¹3�-»ÏGùÿ7Y“Û¡øÜ›zq”?Vö;F4±]+�vO|#î^ i‡ñÎ3šr¬ŒLjvË{ãÞsoµ[ÚÁ±²Ñמu>Ÿ*îÓ wîÜy?"îÜûh²…ˆXx°p@ã=øÊ¿/}ò€ˆø·ÿî—ãÿ´¹úm ý¾PIEND®B`‚chafa-1.18.2/tests/data/good/card-full-noalpha.png000066400000000000000000000757751517447374300217130ustar00rootroot00000000000000‰PNG  IHDRL;ßã’tIMEæ$+Zão IDATxÚìÝ{p×açûC†.IôVeO×àA^ Cph�¯–, \W…rX|–(Y’‹ñ•וÍF’+Û‰�8k9–׺vìxõpd—lG«²l=²¤H]ÙBª\¼¸bTw@ÂI‹€°$³=Æv½”tuW¼ò°ÙóÀ˜î>çÌ÷S)g=ݧ_ç×çÑËîû̽Ý=ét�“p„ܬ«Éš€}DáîàÆmÎ Ï=¿løÛ¯nøw[8òٖؑÇ>¾F·"³øhà”p×`ú¥IÏ„ã½l.»|ù²üÑÀ@¿VkÙÚÖžp'á žBŒ�Ž˜x´¶µ !ºº6¹Y7뺆n…Ü ¶B±ÿÎ;„/<÷¼¹›à=5Œ>¢8Á9Á:Á­95,Ø N ¶‚Sþ{ŸÎ•\1ùy…ü*�å&sú¬h¹²Vc£#Z­Ø"ªAò 0b+¦góBˆ†º˜úI¼)>6:"£÷E¼)®>›»êÔ0z_x¯<Þ ™žÍ{�=SNp v‡¡'¸÷€Q'¸¼ãš»;Ô ®ÿVÈò—w ß�CžàÝû¬95Š^E»º69 g` Ÿ{_´r“¹ÛïÚ/[ÌÝomJ«­ðÖW…Ë}E¯Õq�u]Óë£Þ57e+êb¾ë£‰[Qjw¸Y×ͺ¦o…0_©ƒÊ¬„£Ö<ëºÃÃg-Û/¦\¯|'8w�ðË_Þ5¼ûBžrwXpÉʺ&Ý5 ¯¢jå¹÷éAeåÖô¨¦ç©á[™å:vÍÖo£YÏœ„ã$ïCs*Õ†`÷ibÄš«fgDK¶ ]²é¾ w‡[dú nô-Ï>òp2úî=©u>Á—ëÝA¼<³Z[ÀާYŠÑ§†5¹†º˜5(9OŽ•!ë¶²fþe^AȪ»šh·ÙØ>jÐ�7]Ó{rª á¹5ª~׿®;a¨ûUM‡U‡à8 yrPÉ 䀚4ÌÇŽAwBP£Ÿ£ fWÓ crp¿! C«€ /2\gK´‚°‹¡é°’œ¶H¶�ÌÛÝ+Ц’Â…×l÷³¢¯®rPBq¢µ­]¾·¡µ­}ltDþ¼Ô»êJ=~ªÊ›ŠN[j†nßKŠÔ «¦§#ÎnÀ>Y×å=9„Ô�Hªñe•[ºº6uumŠp ‹ÞûKUÔªF£Â„Æl@ÈfTEß×öbßCDß©ðã lÞ $›†TCù,0=›÷>Ë#䀉EÕÅå |ÕˆçíræÍ3t‡(„äç®®M¥’�·¨Eé&Sß¾èƒ�úRS�Éšt¼)¾µ7­þ•H~òñ"Þ!°²‰&Þ÷5Ñ�jBN>nÖõ¾Š=trBجÔô_¥íUt aF«Ì£þSÅžòM=Bfѽ•êbD;’Oa'·R³0€9`ï Œ¥©�Ø£2O¼)NSrÌ�—�F^þòC©÷cz›kh«©ÍسÐîmÞ3š96oÔ7§3Á…�Gxf2Ⱥnk[{aÚñ¾ä@È€°yë£jfg‚ * <ªW›Âͺª…G Ó’†‡ÏÒ˜„/á¨ú¨“pd�ÕͺÄ,"öx3�W2ÙÁH ä@°ÁFxf(Ì3$TKÂqäa–uݹڄ¨B¼‘Ù†ƒpx‡ñ¨´CÔB,)Õˆ«�6èxœ„#g¦Vm;¤ ä@¥ÁF04<2툫3x@¼mYë�“u ¤xSf¤  yàñÎÏFÚP›¦góÞYOiÉP»ÁF”�E0(íÈÞ¹ H;°õ87Z©—G£ê9j.Û¨©Ÿo[ëò}£‚¶„°;ÛO»� éµx|óPx€h1ƒ�U‹7j.n-¨Í¨#èÉè�îj„ ÛU<Þ·îж€�&eæÊÞº€�dÁTiÀB¸YWNB­f) ê ä †ø^®v�†ÙFÐ- X o6_76¢´�å”*¬r¨�ÆgAÓ P½ÌCÚá® XÀ€�#û [`z6Ïðr³îBktK‰:Þnl´í äT_k[ûððYv`euJ�XP¼!ÛᜡNÂq³®L;ÌOM8O�a|ȱ`*qNB ÐôlÞ÷ŸeΚnj–¾ù H;Ÿ“ct劗�rì¬Ì�÷§yO FÝÖ/½O“s€Eàe „ Ã.­:‘“õfù�{³>§ƒïÔ`Â4@CÞ3Q~V}ظœ5[¹%ä,©46:’Lvx¯¡¾gÀEÃC$M(…k’Lvx«n†Þ Ô›ã…[{ÓæÞÒÔVȆnÅÖÞ´é[1=›/ujð*OÀ Ì£ú°ùî ÞÜw7ôÞ·{ïžW�˜¾×Œ~ÀgÁ½ÏWQ,U¹•�ô|2.WLÛÜ{Î !–]¾|Y\m†–3év W§`2èºï[a ˶Z›ÆV°ÕÝ� ‚ ¯VÂ9)ŠžËv\o�Þu¥5º6bÙÅyôŠ !–ý·©ÿ¦Õíß{åµ jbYíŠÊ¢&{AÐÊQq)=þíÇúúû:B™R*ÕÙØÜràîétW¶Ö W¨õ<¥ÛiÒé¹bOÎüÒ܃à£7ɹÉÜÌ»ÛÌZùúŽùæ¶zá¹çÍÝ­mí]]›ô<Úwjs^$ÕÚÖî]Õ g‚ö.yjbœ» d2Cò–BENQ`èõVö{Q-}רç¦o…÷.»ª:Uý ÇäýkYrUÕá_Ô½-„øèìMÞÿÔ½Z;{“ÚTê8Þ19š ´�]êbñ¦¸›¥Î@ö5ãÎÉø%Gîù½ïÔ—päõbæ�+礚D'†v핇¾5#eÍÚuä„ö�nÖ�žÍË*oι÷žð.SÂ̹ɜbô]C^u�„30Ðoô½OÞÁ} Ljlã]ÕËo$„3Bq-"̰ rmÿÏ«C_´:5âMñ±ÑõU»‰Ô@«áá³ÞÁC2áL%o6èll~«½­E12:î=/_Ú`Äú/[yF�“qñº·ž*˜94jnÖ5.á„ÿÆ'á0«!!'á¤Ó=Ì7mÁÊ»Y×ô­PÃ?L¬S©jÕ²›öÕ‹ƒ¯—ÚÌ•º�Õ‰_r„OÎüò»bSÖÕë ’5 U»0ãe &&¹ÂïɣÁijñò¥ *çx§w) š“pZÛÚMÙo¼ ¹ /ïª"¿X•š„ a^�­¥ŽAªÂj•A©¦p…½5[m'‚B,×¶}Ef\ÂQdc޹'¤üpä•åŒOÕÍØèˆþ5øxS\Né˜N÷tum ÿ(¢%Ð$ê$'�îÙÚ›³ÏêÒ/³>ÁRçÀ@!Gß–ž¿"ˆ ·úÀE?œÒޤõ†+  gÎ׿Z‡úw˜WckÞ: Ä›ÂÀ§Æ äânæ=5òx#Ñ’hXUUQGç‹óôl^=Ó¹ON…÷>ºch·_hÆ!ä¤âMm’/k––-[F�„Yà•c×,:ê!ô�:Lá}0AÈ@¼1£¶-B}Z·„#ÿ�ý²”œãmÕ‘“#‘v0ÿÃ…•gJõX+óO¨Â½þ’1·xBâ�1µmêÓZÅT1íøÆê‹?£ I8ñK=Ö9œu¯vጇ€/Þ:|£æcùséΕ¨#_ø„MM%o¿¦”ÂÚÝzS•GûTy­ßÅ…Ëd§/…¼˜¸Y·«kSÂqúur„“m„CQñåé~M%ß’ÙïKŒ:BˆýwÞáf]^! ›o©öXó½ ”�! ‡„<«)coW륾kP¼©|g1’'„¨ã���¨€�£‘Æá·D‚b@PBK8ÄÔ‚ÅÑeË–‘sBK;2ê ô“sw·o£ìxjÌÄ�VŠ9æ¿;¦Ó=Ç› «ªô[³;uB‹:étM:Já=9XŒ ·¼.ć…áo}Æ" 8ô‰:Þ™¦‰:Ê ä .sohu˜~ !ÀÂŽÝýÓ¤�{1ïPݨ³ÿÎ;O‘srÌohÀ !í�sl¢ö&{6|ò�:ô^@ȬRžjµoÊ7ãT¥ªÊxôšM;uroP»æ��4Åuä‡Ö¶v¢B`žéÙ¼÷óRsT¼ñVP-¥æ®n5zqíEáTå±nK_±%6 E²Î¦ìPýsŽ“pÜì•�,=ç0•(@È`pB‹:M9°”Ú|ЯîYôº-eÅ¢êX­ö�w¨qQ‡Þk9ñ�ç=WLÛÞY‹X1F@ ºÛ‹:ýä 6-§s-¢7 @íD�tºgkoÚût5‚– VoÔ`ÎQ½×^=:@�µƒ–À0‹ K±Æå«ì^Úe�J~ßÜnZ:ïP›¢NÂqhÒj -9€åˆ7¨°r¼è´t•ºÂu+5�]Ðôœ&! é.ŒÎ9ŒÒ9H80É‚*²ÚÆ€ª¬X™ïªdùúD‚Êׄv›E�tº‡‰×Bâ ¬J8âúY­µZ· WlÞåk’ptÞ¡väõ™œrè¨ÔË@·ö¦yÅ'”É9 z—/9ÂSxߥ§ÖèÐøPj0 £A(4ÍsN寕z¢€� ÊZÛÚ} ãMñtº‡xC¶a•Ø�XPÚ¹ý®ýLHrhaltÄohÀ¡Z `Ñ9‡ B½È8ĘŽÑó”[´Q§pŽéÖ¶vù�¾j€qx(`ªÖ¶öxSœ„UŒ:ét�zm¨j0ŸžÍS8€YhÉ ã½×¦Ó=‚)Ô Ú(4krŽº¨ª–„!éêÚD!€š:…† $œ+¯Q!@’Éšn PjŽiùŸŒÉŒÃ˜Àñ¦¸œE�¢€>h‘ ÐjäòK!f¡%0æË$Ñ ŽN¹!|r6^¤˜…–€„, šNM�r«Ùœ³µ7MQ¦ %Ð�œ$Z0‹4¨©—ÿ…%¾¨ÔÖP~»–þvWâSh9G^�ya(@È@Â*µlÙ2êë”›æ9G]ŠÉ9!ÀbÈ.jÌmU]ú3{Ñr³nW×&9»ô«G(€�`a '�î¡õƦ„£>usy§–¦ë@Ȱ²‹ tN;NÂI8³®zbv5@#ñ¦8 Ç¥&Ôbø`SÔaÖ5€� ¤éÙ¼ì¢ÖÕµ‰„圄ã�sÝÐ] ÐB2Ù‘N÷P¡)?!ÕÒ§ °²¹fÞY¼–8èÈÖ6®J¶¥ŒÔ¢mP‡œ#N1D 丆.jÚ ¢úhýÄÔ¹)´Ú$g]cˆ  º«QbXƒ!:!À•7á�p¢²ìª�¿‘Bã`ƒÝ9‡!:€è®D–pxN¦gó•T@E�ý…¬¬Úª�¢ŸÕ"Ê�B³>ç0D 䵈.jzÖ>©zRnª¥«k“ü@Î9@­$uóC-Tg«X®V£PͶ'Ð�‚�sŽœŠ€¨r›ÑE jŠœŠ ëº„ dL<„�pܬKi詺Cײ´Â¿ bØzá÷á ©¯î® tùV–’sºº612Zr€°-9úG�ÚY“ “{™IöRf*€�½œycÝ~Ja gÿ�wÈÏ$¨åœ#Ÿr ¡†º…° r"5Ê ¦" çA×Q“ƒJÉ‘$•¼uR¼)~û]û™*šXŠœŠ Þ÷ý¼ê·W+ï× jEåÇüµ–œÖ¶v!ÄððYY-ˆäÜ�ÕùÕÉdGÖeô‚v’ÉùüÉÄ«çî½{䇭½iÕ1z颎[uâ4ÔÅä Aÿ´¨o‡Ärz本ë¾ztÀ{�ªâýH-°¡.&+xBˆxSÜÛ‚dÐåQÞU¯j}“Cˆja©•imkWƒŸ¯…Ù£F� : “�†ZÛÚµ:HwDw´Ë%[lì˜ ÁI8 u±Ý{wMMŒg2Cœ¿€´{ï. !ò«“œuM6MdÝ(Ô½O&+ÓïM<ú�ÃÌt«ªÚË ßùfSýÁЦ_½G{Õ—ŸuÝ'žøÞ̜٠õ«b»÷î tw¿ðÜóÃÃg“É5+C¶ö¦§góÛ{¶ß{§/pÅôlÞŽ�åeÄÜëmýª˜|öÐ2ouN~6ºvGÂÑAü’cJµðZÈ<åý²>o…×�hMŸ¨Ã‡Žxoº™šß¼1Üòi‘ìoŠ›þP)“Êd†¦&Æ·to«_óÝ_–NŽfñÞûLX+·‚Q ºÉºnG8W¥šW|LŽZKM&#>kîÃ+ÉYzÇ,Ú1oUµ¶Â¦„æÝ}K÷6ÊÀâX3³¼}léÞ¶~õZqu€Å-ªÌß}ÏMæxn¥ó9¨Ã%WF5�h=…´7²7¿Å‘-¦�.sG9y:CÂY(ÙWM>¹€—É �8~ìÜÅóK¬/Zcrô¬i»nƼ t*y3GR$–­<#?È–Þ:RxzÓ†³8Í-k(ðæ!ÄÄø…ÍSÜm Ñ’;C°tUïØ@ÂT7çÈ{ 9XD­ÌûšÝå”Ê»|ii‡„ÍáCGNžÎÐ?X B@Âè˜s(€�i|ÿÉL€@MMŒ÷õ÷QÀâ0&Xpà¡ 45>g{ÏvJX(Zr€ù©ÑŸ$@˜:B{`UÈaR膄 çFз»“Š€„€Ì9‚y¥�²|gÝÕ€ù�»xž„ˆ6ç0¯4P†ïì ä "ny½èT# çÄñc$@ä9祗ž»xž¢æÅìjÀ< çñG¥:POÜÖ¯^Ki„`1úúûd7hÈ9! á`Ω_k¨‹MÏæ™� ä$€%9gçŽ}$ (&®Ps*ôõ÷MMŒS ÍsÎK/”7/f]|hÉA-Š7Ås“¹¢ÿtîâyÚp¦äœÆæÞŸ¢%BÙ§YÎMiLÁûsBpEa3ŽJ8¼`\ÎQýÖr!®öcžžÍ“p†òŽÏ@È„œó¥—’pF眓§3”@È„‚„°ÃáCGúúû|?,5Ñ@Èlvòt†„°&眻xÞû“xSœb!°™ºÐ«¼ô`™Ç�õõ÷y³�›u)r;Ç$áì“É MMŒ=Þ¯~â$е†—�¢V¨¥ÉZ$€Å9GQ¿*æ»÷µƒ–Ô5øò韘›ÌñÂr ÎK/¤ P›îÿìÃÃg ߦr¦úÊWœ™Ë“s@Èlˆ7Bˆ“§3$N?FÎA�`âج¡.ÆK?�ä#¿-ÝÛSKÃv´äÀfç.ž'áàÍ9²=‡¢€ÝhÉ�Í ‡¹Ô(Ì9BˆúU1s`1Zr`'9a4å@Ñœsòt†r!µîÌëÌZa¦S ŒÃ‡Žôõ÷Q äÆèëï#áPIÎá%¡ äf$& SãG�÷—s–­<þCyL<{Ä›âG�÷OMŒSTBMB�Lvä&s9€v†‡Ïž8~ŒŽj,(ç46·4ÔÅâMqr9€v˜l€E�ݼ·÷l§(` ÆäÀ?zæI‹351~îâyÊÖ %6`:5–BÝFׯ^Ki€�Dlz6?3—g:5ª’sêWÅêb”LGw5˜�p„'Ž£(¨JÎ9y:C9€�Do“ PU‡‘ƒsÔ­ ä!i¨‹MÏæOžÎ�p¨®Ç��»x^Þj) Š190ÕÉÓ†âPujpEsÑ’#�»x~jbœr  œóÒË™�„ T'Ž££�朾þ>Áàr€pðVB '! =„ Œ„ÃPÂqâø1Zr`_'ä`IPÈÎ];51.„H¥:uØ•úÄ­@ ¤±¹exø¬¼pÌ;ˆÊÆ•SU““§3Bˆd²c )uó‹\U¶¥ºÊ$7™Ód˜8lje’›ÌÍÌøðX“›ŽV÷�Ææ–æ–5òhI§{ÄÕçSaÖ ºº6Uøuû5ª~øºÓmðÔ“3¿´ rë$¢:Yæ`¸rd=;ëºZ ÷·ã±ßw·ÿ¡›u³®+‹WVË—³³Þùª¶r_„¹bY×=|èÅ—^>˜É íÞ»«¹eMýª+ ‘‘ôfœžÍŸ<�ilnÑdt�¼ÙT«LŠö=8|èÅJê'Ž[ô=øð¡#Õ*ÏTªS–Iä»fbüÂÔĸõʤh™léÞ¦Ã)L™T÷bR]¾›N÷ïEX}îëï“�ùô)“õ«×úž�ž §ê¨ê!ºUV+©Ï¨ê_Wצ„ã+BŽÚšì¹E&èWä ºÖ%“­míÖômȺî«G|5HS$“BˆýwÞáfÝ��~ÕùR^‚«¸-… ” G~öÞl¢*ÀÍSòuZz™]‚·Ø5'û‹«ž™ËG¶ò-B“$œÉ ÉÊkTE!÷ÂÌ\¾¹e�>s‡ÈUŠü ŸôyB¯É™ÞØÜ¢I™LMŒoÞ˜ªî5vAaùyóÆ”>!G'Ó³ùéÙ¼l�÷¦²@¿WŽÉI§{œ„“uݱёW�˜8Ÿµ,±®®MbØ’Ê­ÚU¯.º¾Z|v5ï€òÈÇýç&s6 Ë)z”›ÂÛÉD$jª¾-jD£w(Náýf%�px›,",ÝöKäEá úäÎ ”‰[BåÕ˜j5ªú!û¾ 3g¨òe€ø%Gÿ™+Ù/ÁÕ ±2ªÛrSŽÔÚÕ“9£Iì@˜Å¨J%-üzš½{,{ ¤ÎÕõåÐóœñÍÍC5j�š©‰qžà¢L–nÞ¹|P!ǾŠ;k^á×�<�¡ÞÌá èÖK @È®ùÉÍÉÓ:ªqx4I§5›˜> ‡�,슩ÕL2–‚‘ý¦ÐáiOLrˆã(wÉÇŽ�s@ÈæÑP›™ËW~Å9ÐÕ@È�U言­è±BjôÚ751N9@Î9°Í8�sBìqîâyšq@È�%ä|4ãP#÷} „Øof.OÂ!–˜žÍ?þÈ£”5u÷§@È�Í^zÞâc IDATù …9 äÀç.ž§@È�%˜o€¯ P äÀ¶‹/Æ€*…B,ÑP›žÍóbr`‰éÙüK/¤ИB,Á‹q@È�Öô FÎ7@¡€ET$Bt43Ç… „Xaz6îây¦�…• „˜jbü �s@È�%fæ˜6„X„fP�9 äÀ0ç.ž§„؃ùÀ¼hÌ!ºh¨‹•ÿ…sÏSJ€©_£È9!ú¢„؃fr`�éÙ<“ª€…Ö(r ¯“§3‡¡9„XrybÚhr`�“§3tT‹Cc9ÐñÂD39ök~˦Íq³n©¢„˜ÇI8¢Xk2Í8 äÀ*3st¢K5=›gd9Ðåztâø1úª€�KÐŒªˆÆr�†º˜÷2D39°Í8ÌU¿*¦þÞX@ähÌÁÒ¯c„,òæG3ô´œÜœ©äÍoïÆ× TˆV_p1Ç¢ 9´V£òKïÆP!º„¢ 9NÂqlÚœ™¹<Í8Úîšð¿4•ê¤äõ?0¼ÿG�0Ž|)9¨ÜVÂͺ„œ�d]׎­�/ê:qüûTÏxÃ#s”:0¼Ç9>t ‚nè^Dåv‰–ë|pÛ ,oŠ{#;Õ#=…o8 =HÔÿ…y¨p´P¡¼}ÙÛÍR-D¥œ„³‚RGÂq’ÉŽÜdÎÄ•ÏMædÎqÎÌ“ªi§h ²ŠµØ™¹|ýª˜üߨ2ÌM¤¯¯ûк×ßÔ­ByÃ…n¡‚–h~†ªç­¦oZÖumêw§óó‘k!§µ­]«*µ>ëS-¾-’�Ç”“V‡Ý±fÝ{¥þéì±§„Û>Âj|4—Ïd¢ß#rÌqç·„ëæ®«JÊÕ­×Ê¥y—)¿åõuêvÿWcs‹"òè«ÕРÏÿQÓ/2±ÈËäóÔtr݇>±ê!Ä�çn”?”ÿùí÷fÿìuÁ}õ·ß›½úÑëMrΟnøº¢wÙG„“_ö‰¾?Ýðõïœù¢}5Ôå(ßï§R�)„xøgOÉQyøgOEøíý7þT~øÒèuµÈ®Ÿ_>"?¼ðÎJß?]¾´A~˜;øM}VxÕ¾Ï/[y¦p%A-§ÔB¼_´á–×ÓéaÑÜÒ÷ŸFFÇËܤt¿ä´·µè_¹½.äøÒ!§Š!Gv$uŽ&…¼è„sã;ÿ,?ß¶û5îO…^9|ë}�[>þë+žé¹�2‰Ðo�yX}þõ-…ùÕ¿óÆ—Šþ<ÐÕP_òÆV²J�Ãom;¹¼~Ulî?ßP*ZÄÿ¶!÷¹éoÌÛp%ú~nZ}ŽÐ‚Vc¡%ã]²ïoãßúÏêóû—ïçB¹ÏnøúÏϰ#Jú؆Çê>±c×mï'Ç[�òÑѹf¥j€‡_å6ªº®¯²}­»ÚàੱÑ}�Èk]]›¬9KúÅÕ^jú¸Mñ•”?Üç2áoʸm÷kââ–ggDñ¿6|�ÑDø•þHb†>ÙÆ·J2ê|äÖß¾ðz‘*x©ªyi'âëíBVc)ëìÿÛe\`’ŸŸ¹ÿc?~ìð¥Ïÿñ¿�v³nÖuúMä,kS6UnåîÐ'>Èìà$±®Í®¦UÂÑ? ÔÔFý潡߼7ôÓü> $,nÈÖø;n¾MŸŒ�C¿ý …SrŽê¶§[}uA•@Ë*·Z%YÂÞB¼''¼ãÀˆ#»üH°Dу�B\þ7òÿïýä{O½iú&Ø7�¡Î•Ûå::¿HµvŽìÆ]!Ä�ïü3 À=ùƒ£‚>hÉ�Aä°% Þ hYåVgËy³9g^j²€H\¾´áÈ+Ëϼ±Ž¢Ð'°é\³]nÓ ‰ôgÜ+¥e3–΂Æ(S¶…19˜‡lƹáýãˆÊ³½-_ª3óî6s·‚îj„„ð®½@y›qz÷~€ ¢Í99¨šq€dc@ÈÁ"©IÕÍ8@'F÷X!Z hÂŽ‘9‚oª7BJbæh˜ˆ�ƒ"˜rè‰Ær°TôU!Æ‹7ÅS]©Æ…×—ƒ�ž©äÍ&®öoÞ’hÆ:S=ÖþgŽ—l‚�ƒÊÐŒôTؘr0æU!–P]Zé«ôÇk ä "L9ôG�5r°04ãSИBÊù`Üe49°}Õ€þT�5s@ÈÁ<è«Bl úªÑŒLñìCoS ä`4ãÈ�çn¤�9Ö@È€…–BüÔ;@é«ÌB�5rP“GCÑc „\gz6¯šq�ÌE�5rpæUæ¢Ç9¸ÎšuïQÀt¼„\G6ãܶû5Š„˜M�Æ0Ú³½Íô äà:L9ì@�5rjš·‡)@È�%x=°=Ö@È©uŒÆ¶¢Ç9`@°�9 äÔ:Þ l¢Þ Jc!5�fr` šq@È�%˜uØŠ9Ö@È©uôU¶bX!5‡×ã€� 1 ØGͱBjE¼)N!»1,‡�ƒÅ€`7†årP+~óÞ“G»1Ç!°�9„Ôúª€�|0îÒW Ôz¬rP[hƵƒk„Øìƒq—B!¢¯¨ªÇ�9Ök¨‹rBÒ8ü–>+#›q䀄/ëšÝ­&~ÉÑvݦgó„ l Ç1zýs+� i„œšÃ¬ v0ÇZm"äÔ&�¡O¬z‡Br€êÐaîÓÇär &�ЊAã[Œ`Òìj„ݪc@¨5s¿©áZé'g÷Þ=ñ¦¸Û ò;o|I~øô¿îBä>7M™¨AöUuË­mínöJ [á­…k5u·“p„jEM'7'ÐvŽ,._Ñ9 ç~ü%q¥¯-9N~}ËCK_Hãð[ÿÏÉåÿr�øÂ|2 œÿÛv€¢~~æþ»Ä˜bkoZVƼµ¦ k›ÞŠ™ül‡®®M¾öG•ðŠÂEÎͺjeœ„#†-9Ô!ܱî]š÷óÿñ‰‡~úƒß§¯€yIãð[Bˆ�½úâÏ·îùØ«ÿ „¢éJ-aëžE,S.䙨GþÝNñf�ÝÕ6ˆ¿;ó9v"€¢._Ú°l噢µ¦pêÀ6Å#6êZÈ<56:¢Ïšµ¶µ'ÇšÂͺY×�¤„óÞ�âF.o*H8{õÅ_db¿±Óßü´ï7¾ÿø"{ZˆTªSñ±ÿý~!„øÁ•ŸçÌ—¸Âºá뾟ä>7M{€¢æ~³î;޼²|Ã-ýTnM¯Ü–)á®®Mþ�36:’›ÌƒI OÏæ×¬»2ë”'N&3TÝÅf2C©T§ì²ôl£xUxÀëçgîÿø¥›–­ôöåK(‡©¨/gY0 @‰vL9²n‹ˆ\TÝÕ(_ß9Zrj³ vrP–CÈ� >wå€f!UÐ8ü…rì1•¼Y‡Õ`@9@ÈAMº«1 À‹Y¤ 9X¼h»«©Y 1Á!‹7Ååä€�üæ½! „Xˆ9…–CÈ,1wð›!æù`ÜB0ë@¡ŸŸ¹ŸB äÀ`Ì:Pˆ Ö9€…–CÈ�ad_5f(ôìCoS„À*ôX#ä!QcÖ€ò–CÈ,ÁÛr90Éôl^~`Ö€RVíû<…@È�1Ö¬{�×€”GK!° ¬r{üüÌýòsr` ¦V!9ÐS«”ÇÜ„ ä tŒ»@…˜`��3ð’€J0Á!&aj5r€�Í0  䨉ù£*ñìCoS„À*L°FÈ�î˜Z äX‚9!!Úã%9 ä5ªp‚µéÙ<ÅBÈ�.˜u`qfÞݦ>7ÔÅ(BôÂKr„Y¤ 9@ÈAÀ˜? 䨉©ÕBpÝÜ0ŽoºBŽU˜u5È7ñ7!€U9¨iÏ>ô6³Hr€�„TîÆwþ™B9ü醯SBŽ…x(ÀRðªBL¾¢È7‡÷Ò}0îR¶@)¿¾å! ¡rMå)€ !ÇÍjZEn¨‹e]{ªï Ç‘ñÆ÷6V�ú�7¾D!ÔŽ‡ö…µÉWÇ^á$ù©µ­=7™«z;ÃBÍÌå…õ«bö…�d²#7™BLÏæÕÖ-½À§g?°fÝ{Bˆw—w ñ‡8€¥H¥:3™!s×?÷¹éøß6°,ÔÜÁoÖ}b‡§~Uý*q2Ù‘u]U÷¶¦ry|P+ÓÚÖîf¯”ð ùS7ë&çö»ög]7á8Bˆ¨ZQ¼ß.?ÛÁI8étOp¥úËsL°¦…Wß*:ÅÇÝ.„x†âЃlÌ¡ßÚ¼¥Ô8üÖ/21CÎwÎ|QÍ=@Î)…ñoQÀu>¶á1ùa×mï ‘¨~++„ÖZW×&!Dk[»>«”pUÂ+ K\~ŽvØt¨é$ïv© Y•… ±ÿ‡Oý÷Á×~Ôq|ëïªÏÁ}K'ä­¿ð&üê[7þ«Ï� !þåèßUk¡+ÿéµK¿«úÜøo÷ !FFÇ�>)ÚÛZžé¹ýžþ÷n`UÝ�[yåÉBãð}AlÅTòæ«ËËèÝ1•4þ2û�3_þö«3ââ“?8*L~qùþà“3‰‹Oþàh Kÿ™Bˆ!„ø½IqxU=µ[˜?ê>±ãò¥ s¿BE¹ºÕQ96D-MÛ¡"‹Î9zZq­æ:xJ~Ðg$Œ7�Y@•°R­¢>{âø1!y ›Ju ñ«o|oâ~ü¥³Çž2÷Yïçÿ¨é®ýOBˆÁך¿ùýÉ ¾æû_ d±‡Ž¨Ýñåú'ç¡ÿë?œ8~LaÜîH¥:…ýó¿zFˆ ü××^>ø–™ûŽ˜¸�÷§Ó‰[…¯=ömõOAïùÕ…J}o©ßWþßûÓÿu»Hˆ¿Ï<B¹W>ïþÞ�Bˆ±cÿejbÜ÷-ÞB(¿…Åò)ÖýïoY?Õ<ü'ÿß[?|!ЯþN�{yK÷¶�ÜúÛ^ÿÀK/4·äî½»¶÷lBÜÿÙüš¹/ ñÅ@7äÁÿ0$„xð/;MÜ ¿:såÃó·Üræ 1Öþ_:Ðq{ï ÿbl4>6:"['ª[%VÝ”œ„#†m¨ÙºYWÃñó*w­ðÕ•µêWgSw5!Ä«GÄÕ.žÕ“£–sòt&Ð;ñëonB|xýþÇþî%soW¿ÈÄ<& Ý YþN™¿`bÂñ®ó¯ÞúO˜¹ j+î;¹íý„¸uúü߇¸ -±yëôÿÛ‹ãß=ø˜›uÿÞðˬºknrå…¦Ãùîïݸî©77öb›É íܱïÃë÷üÏÜ€ÑC¼„[{Óc£#¦×@6Üòºõ¨Ö¶öÖ¶÷_ ð¸mlîÛ¼1ÕP>ÄW4ÔÅn¿k¿55Û¬ëÊì ‚´ˆìàí;·Â—p„6ÓÉ•±¦EO%]_ñ.º´½³}cÎd†›[ô¹ýC«ÚØRØÑTûÝíøÂsÏsésPMMŒ›¾v<ãK8N¼)ξˆ\*Õ™N÷ó§ aw4·¬W^ÎÈiÒ�Põêº&ñA®ŒjÉÑý=96uW«î‘ÍTÔ`+;î}ö ¯5z_pPUî_| “cÆ‚ØÆË@9Âjˆz‚E{ F¢÷>Ô&}C÷± {@´êbª ÌâË´äBÎè;rr  æ®9¸ÎÌ\žÑ„KÁgBr€�ƒy1Ñ!@Uð Br ¦u9À5ÌUKÈBÓܲ†BX:^³NÈì13—gÞZBæÑ8ü…r j ä  ¦�9 ~É!ä!§´©äÍì-ö„Ê­t 9 õ äØ+á8m¹Y— !ÄôlžB ä€S¨iõ«bvlˆ“öAL&3äû`è†phv›¿ÐPÞÙgÐde„œ ÷2ÐÆá·ÂYç0OE êfæò¦¯?M•H¥:}P†›u-85Ø�@)�½ÉМcÐÚ®0©@‡‹×$Š}‰<¥· !FFÇåfÝ`«A©TgpÏGS©ÎÍS!|QÐvïÝ¥>LMŒº!ªŽØÜ²ÆÜݱ{ï®ÜdNQ¿*¶{ï®Ã‡Ž}DÉφnE*Õ¹¥{›¼LwjȯPªþ©TgcsKÖu�„ÐWpP-h+dKTn2gîõ6•êlnYã½ðš~PÙqïÛ¼1ÜV„ùfÝëo¾¾îC&æBNÕ|ºþÃ1:^房VôÇ.*Þ|ºþÃA׿�©ÍS;wì î+’É!DÂqvîØwï=ŸžžÍ7ÔÅÌê)çmòÚÞ³]±s‡a믊]ñêíî©_ t¿´òóÖÞ´›uwïÝ#�ᢿ£?yj´¶µËÓи{€,mu‚oïÙ>=›¯ÖAU´�yýêµëW¯½÷ž+ÿYÅ}ÝPóžòJeâ�¹µ­]nÅðª˜)Uái»{ï7ëníMOÏæåʸ»†ïÞ×PÛ¹ƒ{_ô÷>¹Sº÷…Ü;fÝëo !TÔ)óC}ÈÕûÔ–�ú<Ë._¾,?½ðÜóòÁª&¦gó»÷îéêÚ48xêÕ£&Þ¨âMñÜdnkoZnÅáC/tòÄ›â­mí Ç ´3º›uÕò½Ÿ wAá:ËŽ^FKnÖͺnÐgŸ5ǪúÌ5ÄúƒJuãôn….èp ôì ®Ú©*·/<÷üððÙe7í»üöÁe7™ô°òòÛåSŒ +·‹+Þd²cÿ�wÈÿ\aܱ>óî¶¢?ß㥪× ï¬\ÐÂÕï !êo8NhœžÍÇ›âAçÀxS|ÿ�w¸Yw` ?7™S�U oŠ !ä¡ÿÂsÏ !´JõóîeUàñ¦x:Ýã$ÝL,”ÊÿÿøÓÔ6šµ òv•pœ¬ë>ñÄ÷L §šqä þ�?}¡Š;·¨ûþì~'á<þíÇJýÂÒ¿ëö»öËSC1<|ÖÐ=bôA¥ö©ï7÷>î}imk?óÆ:!„Y dzÂï뿪f„œÞe¹ö„™Rœ®ÿý+ëünÀSš&“ãk"Ⱦ²Ëþþ;ïȺîÓ?yÚܽ»÷î’zÓ·¢µ­ÝI8ÃÃgOžÎ˜Ûe?ÞïêÚtøÐ‹'Og ݲ§ûƒóå��~s·B�àBˆ=ód@“Ý{wÝ÷g÷ !úúû*¨Tªóö»ö !Žï?qü˜¡û¢±¹%™ìèêÚôÄß{éåƒæ^¦¦gó]]›ÆFG‚Ûã¡�Üû´º÷z‚ËsPöë‹ÄåK®d‰•g´*ÿË—6è¶J6„œþïwÔçúìjSJv&q1œ/ÊMæ›[‚®éNŒ_�̽>Ê•·i+d­Úô­0zwLMŒ«qɆ¦Mi›[ÔgsÏ>µØ‰ñ †Q™ÌP&3tàîBˆ™¹¼Ñ—)5šÈÜÜ{j˜{‚Ûwï ô÷îôðƒÍ¼?Œ<çh˜¾Ê0f éúìjƒŽ7�yCš¹u ¢ŸÁî`+ì8¨ÌM˵°9œà€Å’†aÆšæe ¨ÅK$7]9…TûŸ3ý¾•Juš» ãd›³Ñ[!„Ⱥ.à 59Ô¡eôVÌÌåM�j©TgsË;§›u-è36:ô|{Ïöª×Ö|u6Ë*·F†RT†¼rºº6©ÿ��wlz”å$œªwYVá”ÒÔÄøÑãýaÞtïûÌÞÿô¢üWu-¾÷žOoíMwumr³îÀ@¿où©T§Z¾ü…ÂåïÞ»G^³O½ztÀrvîØ÷ÇüoÔŸ_~ºGý‚¯fì]¾âño?æý×§ò´â¾?»_Z•¬Ñå'Gý‚÷_Õ£¬±Ñï’e±«öCïŸlÞ˜Ú½w�üùððYoåIn©tD–an2÷£gžÜÒ½m{Ïö{ï÷ö¹gEwÏÃßøÚáCGžö¹áá³'Og:"¯KBˆ‡�“²sG^._�BÄ›âê0óþIcs˽÷|zK÷y¹g¯üÉ7¾&„�[*×ÿÊŸt÷ÈzþÙçŽï÷þÉÓ?yZnŽBþ“51¾¥{Ûã�ùû*0W²ü“§3›7¦¦&Æå/<ö­GïÿìjùOÿäéÍS'OgvîØ·sÇ>ù0H.A­€Z¾ü¹üv5X-çŽ}G�÷ꓟ’9óÄñcÛ{¶÷õ÷mÞ˜š™ËoÞ˜Zèòåž=y:³½gû�žyR®ÿî½» óRuÝc¥±¹%7™kmk—­ÁÁSU¬‹z«|NÂÙu›kÇk²”" …_]¤%GÞhU]9òW²_�ÑQg&q±TñV·�êbç.žvimkW‡iW×&Õ£ž<©ä­Öøë:Wÿ¼°�{koZ]kZÛÚ‡‡Ïþ¹\¾“pŠ._%�„ãÈg?¾Xýy%Ë—¹åÚÁ3—÷ü¾ÖóÇŽ|ù¯ÿF�Ì‹^¾w ½ÿoŠËM8ŽoɲTå?ù¶Wþ¤èŸ”yÒ#WÏwjÈ?¹ò-߸îPW«í¶×ÚÖ.÷Ha»¹úßa S®ÀÑãý…ÿTôú£~¨Æ§f2C�Í-ê[|+0oÉæúÕke9ûJFþ¾÷—“É“¼ë_xåT?Q‡Aýª˜o='Æ/ØÑMÜ·r3U166·È²UçT&3¤ÊGc&3´¥{›¯|2™!u$¿ôòA’[ÛÚ�ï—¿¿µ7­0¹ÀÌLJäçÖ¶ö“§3ònmkõè€õÉO©?¹r½úÆ•˜pÕ +#«ü“­½éøh\&µ†òOäÊÈ#SýI*Õ™N÷´¶µþIn2·µ7-�ɉñ ­Ÿü”Z”ürä½X>8ع#¿{ïžW�¨uκ®Zád²C–Œü™‹TIÊ�›)KF±{ïoÉȧQ²däfÊb—%£ ³ï«}ê–뿵7ý£gžìíîyü‘GåÿÊ‹öî½{^zùàöžíòY¿*6!.¬_½öÄñcétOæãCòï½çÓ*x¬_½Öw?=y:³{ïžLfèÞ{>}øÐ‘õ«×>þÈ£r£’ÉŽ“§3òOêWżËomk—+¯–/î[¾,4Ù,/�I¹þ­míSãî> ËG]ä ×ÿÄñcêÛåÊÈÑ¿rùÉdÇÃßøÚ—þâ/åBäÑï?ý£gžÜÞ³Ý;ï«Z¾\ïú«å«%—/K^®ÿ�»Üññ;M¿€LÏæz1 …7ÔÅä# 'áX“pÆFGÔ5!òø />EBޝ í zÓ³ùÜd.œÇŠÁ©Ï®öæœÂÆ–*²ÑS·-½*S´ræýaÑ£ÞUxQ›wùÞ-\¾÷'Eëʾå¶¿W^ãìêÚä½Ä,¢| ëÄ*ÿT¾V¥þIýÜ÷ *: J,õ'ê'…?W›PØç¶T–óÆÈ•QWéåÚaLÞçM8!°lZd›ú+: Ǿy÷ˤ�H6VŸVˆê®Ia#ἡ«’�ûȦ~–¸;ŠcÑ�YÉ£„2ýÔ+zRêOJ€ —\។ú§®®Mò˜œš_ÜÊTòk…ë¯K©_óýB™(¬bÊ_.5„ZeKß’å7zŸÈ’YPÖÛh<ïš—JUá÷z7V›ß¢p8JùÛq&3Ä+Ž•t®®kÝXfÙ{r¶a–ª4¼Ì+•êdÖ[Ñ’c!^@Èj Ø 90IC]Œ Ö@ÈjØ 90 ͯå1Œ™�ÃlÞ˜¢Jaj5Br)æ(ƒ¾ý„À*Ì:@È�‘x>P ³r{ЫŸ�SÑ P S«r`$a@È�U˜`  (†.r«Ð«Ÿ�ƒñ” ½ú 90O)|R©Nf äÀTÓ³ùúU Ë€ý|Áu%R#{‚þüK¶ë¶÷õ_IZr8�jýùk!‡Ó V¤R�Ì:@È�ñ8�¼èÒOÈ� ˜{@¢'?!6àY€BO~B,Á Á€Bl €S ÑÉ…�½¬ë²‡–ŽW‚¢–ÍÌå)€y÷*·µr¦g©—T O,t�p ¡¦CõòêbX¨q©TgsËšxS<Âu�-9»n{ßè’<òŠ^“ª¨Z¨cÀ¬UaDH#ä„*ª*†å4ÔÅr“¹¿�îj„ jtè½/»«ÑÝ‹�`ص© Ž“LvúÓ³yùâú~qò3Ãr@- ¹÷~á 5Èš19AWn—b…úÔÚÖ®a0°æ¼ÊºnÐ%ìHWôóáCG¸À(#•êÌd†Lÿ Ôæ¡K!`ÞƒdýêµaÎ:Pô»dåÖŽ– +êÞÊöµ�ÓÕµ©«k“V+êfí™J\–mW×&7ë: '’’¤n¡%Î9AÞE[âÓZ{¡Á–îmBï…BÕå}ÿYôw¼?ôþD^ývîØ§~¨~Ç{u*üà —ÿå¿~�@)�Í-ñ¦x:Ý~5¬°J¶ë¶÷-È9NÂqŽnñ¡HÈQw -"<lŠ7Þ-’Gƒ÷?C®¾r€yMŒ_¨Í w³î—þâ/Ÿx"¦.÷}æ�ÞîžÜdnz6/ØØÜràî­m퇽ø•¯>¨®-ò×¶tŸü‘GeÞ�}†‡Ïª_“WêhnYCQÓ¥R�ëW¯¥ hÉ�lÌ¡Ç0�S@ÈÁ u1¦hnYC_5rpÝE�B4”›ÌQP‰Tª“yÕ@ÈÁuè±ŒÖØÜ"û§P äà ®ÀhtK!EléÞF!ÑW „Ák€žâMq æ%ûªQ äÀ�K0}Õ@ÈAÉ„C�5`úª��ƒrÖ¯^K�5`úª��ƒù/0E*Õ¹ycŠr!ålÞ˜¢1„frÀe؃Š䀋°S€�ƒJñÂ`¦!•j¨‹1ýÐ\*ÕÉëq@ÈÁ4·¬¡1謱¹…¾j ä`Ö¯^KcÐYsËúªAñ Z‡œ¬ë²Ã"¼pP@OL9€ò® 9Ó³yJÓm1år8Và=è±ô´ycŠB@¥!àò4Ggr°x uôXÚÙÒ½�þG ä`I èƒ)@ÈÁR1ýÐ c†AÈÁR1ýÐG*ÕÉëq`|ÈI8{(rÍ-khÌ€ÈMMŒSX¨LfȾ�¢¯r4|OŽ“ çD)¡1¸?ÂD–=¦L¥:™r‹ 94(ÔP£1ÍÕB[ß–îm½Ý=ìk,8äEј9ºnÁ¦îj©T' „TSC]lóÆ�9 *�Í-­mí¦oEÖuÙ•„ Çä@ÉdïÌÀ,6= �9A_|£]¾ï–©O…²’bYÄ¡ž›Ì™²+åÒܬNµ¦|ɨ皅+SaþQËolnQ¥[›mhT&Æ/D{•ðŽŸwe*ÿö¢¿oŠ—?[ƒ> ¼»U®L�$*¯÷g]Wþ²oùj Þbt³®¯|Š^¼¢–ïÝ�òç©úWïnòÞŠîÙÂ5)\sß=¥ðù‘ü“ò·¹9Þrî˜I¥:gæòôUk¨‹É­8ò £âC 9­mí ºÊ-Þ·ilVÂq´*Þ…î‹Ö¶v'á„Ù˜Sþ:^õ‰2gæü—øy•¯aÌ[Å\âò½¿PI]§|‰žk¥–©V»Ô/ø~î­:‹óüT^Wk¨‹©ŒQùÎ-UÔj«}‰EUqÊl£“p �™E§/ß©àáfÝÂ놯våf]7몕™¿ —æë×!è= äªåOMŒË‚*ÜjïOäòݬë­mÈ’,ÿ‡¥~(—Vþ¯ �ÏÂÂ/5…T©åûŽ ùkj×ׯŠþaÑz³\ùûeª•Eë‚ÞTYø;¾_+S}¬¤–©~®¾TfÓ³ù•©d?ÊS{·iµ4õ·©T§\™†º˜úvy UÿYªdTí_þ¤ð‹^œ½µsß/ûNu2¦R�ê˜ñ.¹¹eMn273—WǤ÷â¯Î©2»¯±¹Åw¿S!¤°w–Zó¢‡qaÎ)¼©?)š¸äÊÈ�M¥:½§y´Ý›[Ö¯^«g}µ–+·Bˆd²C·úêÿßÞýÇÆqÖyR%G ÑÅh½ÝÑÆvŒe'—à�ÄFÐR'$ü‘‹*RQ(wÁI'¡ž@‡ø!q:tðÇ)üBèŽ$' H§^ÿ¸úê)†S³u‹›*µåKw4‹³Â=µ%U$||ËÓ'3»ë]ïîìó<ó~ …ízvvfv~<Ÿy~ŒþÏíúÕÔÔQºsõNPýìgíb¤Ï‰SSGO?ý‹'~™Á—ÊùTöÉ0œKÜšÚ;<†s33ǃrGqÎ¥‹8•ÊÂÔÔQ¹fÌφ‰¿þ≟¯,/=úÙÏÈ”é[_ßþæwÎ�ÿ”ÌáÛßüNÝ"²¾€¥ç¿¸xmfæ� *•…ôǯ\º,Ë/¯Ó˜+˜¾ºTW«r¢ ÊAÝ3æ•K—ÇÆ'dùðý‹r]”­$—[½}*•…ÄüñÄÏ''��O¬,/%nôþàû<9£”šŸ ÍVW«•ÊB9Âp.®þýß®œþHi¨$¿Ž¬ì¹óg%œ˜›Kælþpz•eSÈ’›ïè�i¾©ßÙ;<¢—SJ?ò¯Þ=Î�?›(›êK,†þ ¹`�æ/s+ôÜ¢865=·Ä;òA=ý‘½Ã#ú0ÑË?<2Ú|ùe²Û¯×ôd_yü«¿~ösþÃ#£2™þ�ôôçΟ•Ò¿¹Åt|’ÅÞ;<¢—ÄœÕÞáYx3qé“^bÎò=$Œ\_ö�èÄ¥F&Ó…ZYþÒPIÄ\ý½0²üò¥æœÍ-&Òߢ'Ó¯¿òøWïëÕ”Y™ GñØø„þ–8Š?ùð#zMå©:T;<½²¼$m™>ùð#²qôÎnvìð´|¤8P( •ä?å_™XÒšÌüôñÓJ©ƒûö—†Jkë5yaN|îüY=gùˆL£¦c‡§ÇÆ'þæ¯ÿVVY>¢'Öó—xypßþ±ñ‰ÓÇO—ƒ@&“÷�”ƒ@ÖèôñÓ¥¡Ruµª'VJÉüÍ�È;òW9iWW«§�ŸÖ #“ɯ sþÂ_}A/ŒUõÂ|íïÿA–9(‰ùË–ÜS�ùë‰ÍÕìú Õ_yü«':.gK³¼Úè¾ 2cyvض±±¡oLÚ¶p²ãÖ~zC)5ísñç¿]~U)UxlT¹ß�Tv’+—.ïŸÿ1ƒq÷÷½ÒߨÖuÿ**)½vëfb™@ßùNÿU—»wx$õâéiê~\Ê+ҬżIo–ft£—DeNâ6^£¿¦g›þFYA)�ܺy£î’4ú]T’rdº:%ÑhgxdtpOáöëµtcžM?"ß’X—Á=…ç{uxdTþ”n¯’ž›ù¾^q�“å‹nݼ¡§Ôň—_}¥îÝÖâ@AÿI>(e2݆DÖW [J©ç{U—¨äãkë5Y ù ¡d²Ä²éÓ%-™ìØái¹!W]­êï�œ<¤ï÷ëÅ–ù—†J‹‹×džzÍÉôÜdÕ÷ô;zJ3B¯­×n¿^Ó“)¥fŸ�ÓÛAJ¨æ7JÉOæ#Û\?@£ºZ•¿êÒ§L©—\nÏφòqý�fãÀÄgõdúƒæ§ôÄ‹‹×dQõÜÒ¯e²ôÇÍ9KL•?Ék³žAþÓ|-ÿ™x�þ¸þ“,@ú#éo©;gýñôd­/³¾áº²¼”ž•þO¹C¡'Ówô4ú»34ÿM¿_w²Äܳ•¯ÖÿÊMŠFwåÍ Ì6¹¯—˜¸Ýù7¹žš 05uTÇõÄm;óÍ è»é�è‰å6œ¼35uTn®u·0 ^yÔ!G)õ�zQ)µñÖ]\ømï{I)õ­¯Èöå”�Óè^rIj÷&ä¤oW;D× \¹tùÇÿúãl*szš êÆýfz‚æÕ©¦Qü«û‘&ïo:eëMŸÍ¨Öúôí~jk “YëG3ìµþ§§ïâ }d&®º!DÞÔÑ«Q_�sô|ô”uÇ�0ÿj~uzæ÷ê׿"éO¹Û”¥óu‹mŠ¡¢Ýoiñ³ÞŒ…%%ìD hE[éõüu&Ñ M2ƒüµÅ‰7½=ÚÉ�nYMÙßtã w‡Þ‘ ”?BŽÔ-[õsèòj2äô´ïï|ús�zrd'°m ·HJ rrùÁ÷/¾üê+¿~öŸ¢ÜJ’i”1ÚÍB�Ä0•jrÖëÒ‹9ë 4åà(yM’�!§Ini>˜Ä¦±'Qc³éÐÍ?R7ö$ÎW°¤´áSÈq�£Õ i¤†PšpËMyw T²~„ýëXX^U6�®æß“I¥¡…‹d÷ÕÝp¥=´——d3W$2Fú?剨Ódí.IÝÓëlÙ£„cιw_Ñß„cɲ½8ë&*XêN`VÈ$¦¬[?³é ›„"ýŸæ÷&ÎW†ü$ŽÇÌ.©æ¡íîa® Tn{·y5°C«ä&�8†GFy0h£øÑ­-ãe]™¯9GÕïË9Í+XZ¼nð¨ûñÖgÈéEõ`l+³³Š©¬_< ˹�ïÙm >'(<'Çþ¨FÈAKÇdânZg�v�öð ¹Zf¥ºž¶¤Ïç‹ÑÝ2´ìE^VÏzðœû@r°Å�Â� 2Pí?AÒNÔDð‰Õ8‚�„Øoä…Ç=s@Õ}@ìdOýy¢å![Ü�è™z�®Pè!›kÔñ—~ »¤ÇבAÈ�áç�‡N°@·øÚ„¸dpOáÜù³lÐ9zã8ÇÚDJÈÁæÌŽ\é§òyð¬w`ªq@È�-÷~t"ŽbûŸ/ ›%nÄrÐ…]Šž9 òpIÚªaËBÝGeèDÅa8G[5t !]PàÁ `ëè�Bltìð4•9` T „XŠž9`k¢¸á�‰Ž!Y£gh—Tã4j«–2 ä kTæ€v5©Æ9°•9 uÍ«qB¬À0k uTã€�70ÌhÕ8 äÀTæ€Vðlrà’c‡§Ï�?Ëv�ðlrà˜â@axd”Fk Q¡„¸çà¾ý4Z�P�BœÄ �jrà6*s@"á(¥ægC69pRq @eHÃ969p;ç<ðÐ ¶4T!Î[[¯Ü·Ÿá¤@Å  B|P((F Jå€jràUÔar.ŽbÆ!^¡2€œ'œ(ŽÙ äÀ+29€Æ¥TÇó³ai¨Ä!^9¸o?�ÖÈ› èñè�B¡×BÿX½Ø̃gïðS¿xâ—\WLW¯¾ÐÝø§Gz�yÊvk8o3Õ¼vë¦Ìöµ[7åuÝ„3<2êÄ¡—|pOÁ�FkÒ!„n!}ä蕢ɵ£×¥mo¶˜[¿ìÌÌñžåùR¹IïÖa’(WOMõ£Ñ��…[ó´³mccöM–øík?½¡”Œö¹øóëšœÂc£úÈtTź0³u‘:q³±\'})·µ®ºZ}j®›ÙRG2ýâ+�õà¾ý/¿úʯŸ}† ˜x\X+†GFîÛÿéÏ=ʦh……e´Drwu¤`#÷7Þú ‹« ]‰¾õõY¾œïÖäT* vD?„áÜwnsuæÔ… èf¸òo÷Ïä+ÆÆ'ÊA àúiÚ•ÊÂSsOuq†ºÒI¿8¸oÿƒ'gÖž¨Ñht¼ ‰éé#2ô9×…,/ æZeu_ SSG•RW.]Öï;W²Ú½ãˆò¨¶6Žâ0œ³mud?¹'äÈΪo“÷«u�nÙ)7ݧ¦ŽÖÔ ×w‚Ù�ç^~ö•[7o¸ÿy—ÿ­��(uñKŸÿ®ì'f]Êââµ.þô‰½Nvù:iKÉ•,³Ó–>Gp#€µQð�‡Np]ÈòÒ Ëkë5ó�M¹Qnw*¥fŸ�s±LuýwÇ”zQ)uìðô¶÷>âÁ.!·¼çgCóÍ>öÏ1ûäÜrÔ½ �úÞ§³ºZ�™9îM³EwŽ,ü‡?ò¡ôNÒõý¤ÉÜægCrNf²ÙÈ¥¡¿&8o”Ra8§Ëéëu¯Ë�ú«åeª÷?ýwÇ<Û7Ò�ú˜ daô]Z{Ÿ“Ã0¦V–6,Æülű7¹'åÀL8}\ ¥Ôè�»®�ÆéÓà�6×yh¾r‚ëV–—ú5îùT©,ô=ᘅiwËT²ä·ß>ÁN•�íl‚žJ<*]9ÁéV¹ §â(Ntº@W8:´šC¨ÉÉÂÉmf#tN÷q Ã9­Ðëx£” Ã9{ÊÀCÝ`à„êj•Î9ôTP®\º\]­ò”98rWÐ9€žÒ]qúÞ!è4äPWÈ —Êz�®8ð*ä‘¥‰:t=áXÒ ä #VuÜšŸ +•FZ ‹lx*ŽÍÅ�müágìcì$„¸mey‰šºÅ†§â�#äÀmŒ( @]q@ÈÈ9x"Žâ•å%¶99OŽ…]qBÈ9!¼Û'GºM[ÕyšzI ™{ˆ‹]íe§Ê`Éå‹¢8~ñå+u'Øyç7wv~Ôæmuàþçܯ>1=Ô›Ù×”RO>}qô€úDµÖ³oAKþëªWÍP?1Í“Ñs¢¦îüìɧÿÜò¥¬{¶?sê‚.�õî’”è)Ê9èzœ°ùÃöt™Ì<6êöŠéJK£þ6ò¥ú_v ;C‚ü‚.þ@r4n9?7ï'¦7ˆL¶²¼ôÆÝw*(®=ó£©�üEúÊgu M-p—ýiõ{þEØÌÃXû�ÿ­}ì§w‘Ö=ÛßÙùÑ'Ÿ¾¸{Ç‘±ñ‰DY«Ã «ÌJfbÎV:&lúE6Àê~»¼I#p Ë„z§Ò{]¿v½$:Ìo7ÿ&=Þ,i£99yˆ�cáÞ,�'s±Ã¢´è}ô³ŸQJ釬õhE¤aèÚzmôÀ;—7³ÿž?>[÷Soß÷�üõíûjñ_öItîýµýJ©‡?PXW¯yØ Í4 {rzO¨®V¥?§9¢OׯJÅ�ƒ'gäŽ{¯¯}½¾‚ÏÌ'çØ–p¤;™ }rÔŸúó¿rtcÖ•å%³|Ö_këµÅÅk33ÇÙ‡¬¢O.ŽŽ±–³¸§+2zànúÍ&/ý'yÑÊ¿@ç~_xErŽO8@`Û™Î9»J±RAW¥•å%)öé‹ ‹qž:`a™0Šcù]ôÕß]«ºZ5¨¸ÏÎLÌ8ÅÖ¦vÎ2­{³úÎÁeyß@fôA_#²¹|{ÐÏ™jÛ”ƒÀæZA{Ÿ“CÎAO³~¿rNÝF �é3¿¾ìÞq$ãx@B@×Yþ@K d”sÒW;ÀþµU,O8oVšE¹9@w™Í>çÐh òo çÍj�e+5€�c#Çïò^Pø]º’sÌ+ÀË„£_s“«+x|"< 9ªKäç͆æwv~”¨«ü¾ð È áP‡Ó!º¡-ÛÙÈ¡¾¤¹¼í*Åúš'�‡ã‰7àe¡è#úäYG†\_ãMÝ„CW ‰.„ ?Q‡œž%ýÚl¢F¼ú‚æj@?sήR|gçGu»5Å“ÚÀez56Ð_Ôäý�:‰ÑØ,à9u“pB€{rŽb€ip3ÞpÆ9ZÊ9Š*p*ÞP�X…>9€-9‡Ñ¥À•x“È6úLÎÆ,AM`QÎaÔ5p…îN)§n@ȰyÔ!瀅c �p;Ñ\ °4êÈèÒJ©�w~£s­×Àž„ìEM`oΑŒF}Ï6z˜@ÈÐýœÈ8Þèÿ$á„=É9Tæ@f ÇŒ7$€�€œ>$3Þ�pB€žä¹ÖòŒmÈ&á$ÎÃ9º™sˆ:�qÂ9sê™SØ&€sBp,ꬭ׾üå¿SJ=ù´Úyç7úzÌèÒЭx£å Žâ×wØ<€K¨Éœ”ïy`¨¢£t/áè sŽ¢&pLq  /vï8òÆÝôCU:Ðq¼QÆý£Ý;ްqGQ“8ìÆõú’ÌØkÐaÂ1Ï¥ú ÀEÔän“Ñv•b¹NGÑ€ @žâ�ºwh„À+ËKSSG£8ÎUÓêFQòo¨Ã9€W¤¹Z9rØ…T_Ôw•bsL*sø�pºÒ>�QçÐ'9²²¼äñÐjm¥Ƙ@Â@È<”¹Î‘søoäœf޹ÒyÂñ{LN€�À·œ#…F]àG‘f¼¡È'úäùÍ9uJ/Žf3á�mBrNr€i¢Gã ! çÜ3êšâY:\K8  �>9î)$–GwÆºß äÞêî£Ìœ“Ž:lmVÅet¿!ÞH ¹€dÎ1;ê(£M×ô+Û$ÞI܈Bà�µõZ/žÃmÞ5ûê0&€¾'œD¼¡@]4WÐRà1Jë5Ù'œDKZZ©h‚š-å©Ò‘¦kŠ‘¦d˜p!@¯¢Nb˜iÅHÓz™mÌ„C¼@ÈÐÜ£Rc(*vô,Þ�pl}r´—sE³‰<}ul9Þ4ªÀ!áØjrl1çH­Ž”E¨ÒÐIÂIdEí `±³ùGB`‹µõZi¨ÄvèQÚ©ÛW‡¨` ñ†„¿Ý~û„» ¿í}/Y»l‰‡jr²0»ñœ7ëÒ‹§²À�´“~�¨ÀélãÍõ®ºZe—CÑ' sv3êH/�DGúê¨{B0§ÙV{³¶^ã÷²JÅ®¯Âõßãç ä¼#(SamNúØ4çè² choÝo²BSm{¸ÿyoÖÅþ":ÍÕ·3§m *tÓ5³#mØh½ä3ۤߤû ¼,U·eÛû^Úxëƒü¬9 9Qó MXÛd<1[:ê�«xcfûã }rÐ#øÙ¶÷>Âvè5š«½ýñ�J©ÛåW]ܾz±½i…9zà.‡M¹ÕbÐlgŸ(ß(ºëþÆ›tË´D÷*p2Cs5{¼µóžlcóHep©¹Úíò«ƒÑ>ÐE.Þ\4‡_SÆHÓº<$/¨Ø<ˆ7‰l“8yvëæ�Ä;:ç8Ñt-�Êl.“Ørên5wcñÃÓoU]ímvèÄõëÝ;޼©œ¬ø.ÆÆ'äõää!w«ï-¿'פ›Ð›ÕÀl½&i'ñ QràA¶ñ#Þ”†J\5¼¬Æ9tâ‹×žù‘s‹-�z†GF[ÌÖ|Ï3JÍèÌÚCãÝ�36>16>±²¼dÛ"–ƒ úxüžÿ¾ãè¡øòÞ[jU »|у3‹>ã³}_x;×b³ jI)õÆÝ”RgN]Pê“O_dpÀ§„£ãÍ™S¢8^Y^Ú=ÄUÊ…w:ðèµØ½ãÈw_0o¿ºâ­ÿù¿Á=…?Ý|F¹ùTÐÁ÷<óàÉ™rÄQ\ ÷“8ŠeŒŠm‰?ë¿ÙÃé‘ÑecZ¸U·ö+d³u7—ÛÐÅߢ×?«öß|CÝÛ’�¨“™÷×ö+¥Ö¿÷šë2ðµ½J©ß^ágÍ8ÞH¶ùÒç¿ëßIÛ�I¬—Tt¸Ù¿ Õ9›Ù³‰4ævt}·Ê�7gIs�:Ü+ý²ÝÚP‰%l’ ºº8C=«ô<Í híÞ•þ•õá ÿÕïÿð'ßHôØ!ír9öÇ›3§.4:Í:wSÆ“ë×>ýH? Û²ƒ¹“o·ÿ4äÇ1©x—M?�7ÙÀu’ÿ+U÷A¢*õ,Qju€lŽùŸ[3­Éˆ‹N”§¥kµç^î±ÚÀÂÎú�°ð×­×Þ}¨mcn¬­×<ØÜznã¦k”?Ö–ìTr&j´S%ž˜®ÕáY¢@_Φ�ò”ƒÚƒþ´ÊÁ!^<æÁoáA!jm½æÄZÄQ|Ç {v[{Œ»7äÌ$ïô0š9Ì™´a²�7éöi‰ã‘+¸+-ç�N8TÜnóÂEq”ƒ±ñ‰ÅÅkN—­ƒr ›`²CƒŸcË9G°©Ôà´a:É3�þÔá=]¿öyCîë¹^ BC´{þÙÎV@~ø×-ÊéÆî[‹::ç¨TwųD�n$œ³�O'X§«ý=ãÍÅNîàçð ž=BH;p,ç$ÞÙUŠ N È<@+ñ&Ñ4ç fN66ÝIÌV‡Ï ÐÓØc¦Eõ@¶�G¨ô@»¨ÉàaÚQŒ= 46éxC°@È÷ÒNz”r˜m¨·úK7S¢nŠ�ƒþ£ó%œN;:êèœc–É9ð>Ø�m{è�@È€N£N¢›¢bù‹7¤À*Œ®FÈ€.äeÜ­Q!8~6Ï ]4'ó´›mZO5¤ ä¶~�§ÑÓH·T”_óoÓÅÅ¢RÅv?µi/š,ƒÍØøDuµÊQ„ð?ðÔmÛ¶…Ž=fÖÖ”R¿zlçÇ~zÇé­4ðµ½ÝÊ3}¯¥YY^b·Bä+í¤m9ÿÜþ¤Rjߟ �׎þËEG·ÌÂãF‡ïvw“öCH!²¦  -ޮ֗üÓhTƒDþùÐÁG_TW” ^ûæ·êN|rÛ‡g7ž;¹íÃKß9›ýªM|ë—³Ï5Z$ùÓäPil|B)õâËWœË3BØxlÓâ¨å PêÑùjØh>$f7žS RPO½–J8÷,’RJ©êjufæ¸RjeùHuµj®à�ë;\¬¡9€¶ÃÏ®R|ãúŽÉÉCªã1âl”ƒºé®8Àùr›:Tý`P碎®.0„È#GƒM#qó›•hâkuȱ¤//üS*±“Õ8¥¡9 à@Èi”ÌüÈ—,9Ù&ÏèQ�®«®V=ˆjü½84ø5AÈAyÖ²Åé=g|‡î–�¨v‡r€þÐ59Té »ÊAàÁM_°Š<óÇõüïͯàôqÉ!Ç^ÜÙBWP“ƒÞ�š8M¡»V–—ü84üø8ÀBN7yðÐ×/T°œ·K9@ìA¯}¢r² ›¹Óð•mrè“ø�rˆ Yž„§÷}û­8Pð E¯Ùœ×馽~ôÉÑ ïM“}óµ»·®]¿tI5އ†Ó&'é\¿öæçÐè~€{VÛìÇ »6¯Åvýjl|bl|ž¦#c㺹šs‡ez�ËAðàÉw[æèò´Óëô긾ðî^±ôž84]#p¹EêÁ¡G±7¸»G„y÷àÐðc§ Ê8…[ï¯}æî±mccC€/B€_!çÊ¥Ël~øáO¾ñÿ‡ÏgåŠXÄ�IEND®B`‚chafa-1.18.2/tests/data/good/noise-32x32-indexed.png000066400000000000000000000034341517447374300217130ustar00rootroot00000000000000‰PNG  IHDR D¤ŠÆýPLTE"*9YjO ^’Ÿ €¼7ϯâCZQ&0gRTk3¶+÷qT\kzT“O¶}GÍGé[«mn�oÉ}—�c�2.D¬kô6 Œˆ�S•ºˆ¹œD�¶“ÜšÄϨ«·zÂV=RÄÍ,Þ¶£ŸûÄt¼’Ý>?‚ç*6ÿ¶ìøM;Ør*ÀâädвL#ÿÈÚÚ¢ñSÏÒÕÅìyEÀï‡�*Z8+KMª^ViîÿÿÃúâ_U’OÜ>TýfUcŠod=á€=ZT`ºd§ª.¾ÿþK`v-jÕ8ÿ¨{J�{»AF¯A€ù5%déšW»Mì@sZŠvRÞ—Gï‹‚nzÏqZˉX*tÕ�ÊßA¤—Zˆlufbþ‰¤ßS0'……=Š‚uS„� ’¥ã\Ðb”Àfz™”ÿOs¨�y¤N£ŒªEY…¹Ìt°sxÕg�¦Â˜ü¥…¹b’v§€k¤ÿ–�´„……ϹsZ§¹‘űøÖoô,¹{¡÷|k¨y¦©ˆÆÌ�Ñ«œÌ@º›XºÇ¯òŒ¥¤â‹\Ì™ÈÐߌsÝ‹�Ü…þv«¶¢™îËú¹¡MËœcKËÙŽåŒØæc¾~аž“«Å[ËQ¥ªÒ¾ª”p½î̦½¦½a­ÆV⣵ÿþÿ²ËÄù‹ë¿ÐµÚÿw¸É]´Ô·ÃÄ÷ÀþȬьhëdÿþ ÿáˆá~VýÔÙtꙹØyÙÒo¼ÔȪðûÕEßêsþà{¨ôÎ¥ÿcäø¶ÿ€”d pHYs.#.#x¥?vtIMEæ (+®50ItEXtCommentCreated with GIMPW��IDAT8Ë…Ðo\ÆñgÀîöçÕÄA'™œZcK‰”'’Å­„d ÓFÊŸYP–v vZ`E)+i] %5 4‡©Ä¡€A¥µ²’´•šè*C+­ O¾Ü;/ŸÏ÷Õƒ§ lœ�ûm‡ôÚþìp–œrü%ãšvK1Åè–ºûóŽÐ°—§åCÅïXéÞW§¶?“iÈ�iÄ D £fåÊ€jcf‹4êÒT6›œ3ûáòÆ*X_?Ù›nFÌu¹±ÐWïþD³d•D¨»,gà|2øYçøÞ¬5 ÜëÕ ûWKžö"òØ+3¾ÛúÄD˜ÜxÐŽLÝtÝ#íïõ`0­@uâþƒ4"™¾É» n‘±Œµj«R²ãà|^]ÕUÆiAÝ÷쉉î×vÊqÀÖ°'§÷=-CIš½»"›þž—�q~{›]rLÆã×èÚ �ý¼(¤ÆŠ,j.ð=jy½…&= l»âÄÇ W}()_¨í]Ö¼´è¦ç;T0BOƶ‘oa ‚ÚV¼›EÔT¸RÚ˜[)0)‡2VÑ7!�·j& )0¶!ŸhŸ4÷Ô0}¸�YÙW¼c¢Øˆç>JFq\ ÉoNÅ…Ò)§\ ‰œOº˜‚Øy ç�÷ÃÚ¶Az Á»âi]=` YØ’k……a›læZUŠJlL%XÆ})¼âÆ:ç¿2ËÀÖ^ô JZwF ´M¾Q‘Ð8Š*kî®�p0|æÈõ_®øï8Ìõ?¢T7 8¸ À<]ÆzpýøL’'ê÷p°øÕ®ìµÌey¯R‰CRü¦ ÂAMZ]t#Ò&Ü EÃ74@‘±o†ƒ=®1B}ý@ÏÇXVo��ê;à…>BÄ+˜¦~”BF W}‚†¼Sá"ú}b9£§µ˜ÄûÞn€â´ÿëMEXÃ_ŒZê±¼ žÂŒÊq=’?XÐr1¿²³p¼L§‚’æ$Ÿ�Fšo ÙÎÂ:˜u³¶S9ÿSÇs-NåÜ�Þc_™Ièý‘ÍokîvLKp—Uk¾Wd¿�€²S[Ãh…¨Û%-å[ö¡òˆÑåÅ þ±æàýäÊË7ìÂQ•-nÿœ1KòYЗ©uºÓzD£?è›ÇèîEñÌC˃ÀB;qé§™žâÀË …«‹¬™z�0ÀîüÍÆàúÿ± >SêbʨÁ� Œÿ®¸-6ÎáIEND®B`‚chafa-1.18.2/tests/data/good/noise-32x32.gif000066400000000000000000000034671517447374300202640ustar00rootroot00000000000000GIF89a ç"*9YjO ^’Ÿ €¼7ϯâCZQ&0gRTk3¶+÷qT\kzT“O¶}GÍGé[«mn�oÉ}—�c�2.D¬kô6 Œˆ�S•ºˆ¹œD�¶“ÜšÄϨ«·zÂV=RÄÍ,Þ¶£ŸûÄt¼’Ý>?‚ç*6ÿ¶ìøM;Ør*ÀâädвL#ÿÈÚÚ¢ñSÏÒÕÅìyEÀï‡�*Z8+KMª^ViîÿÿÃúâ_U’OÜ>TýfUcŠod=á€=ZT`ºd§ª.¾ÿþK`v-jÕ8ÿ¨{J�{»AF¯A€ù5%déšW»Mˆì@sZŠvRÞ—Gï‚nzÏqZˉX’*tÕ�ÊßA¤—Zˆlufbþ‰¤ßS0'……=Š‚uS„� ’¥ã\Ðb”Àfz™”ÿOs¨�y¤N£ŒªEY…¹Ìt°sxÕg�¦Â˜ü¥…¹b’v§€k¤ÿ–�´„……ϹsZ§¹‘űøÖoô,¹{¡÷|k¨y¦©ˆÆÌ�Ñ«œÌ@º›XºÇ¯òŒ¥¤â‹\Ì™ÈÐߌsÝ‹�Ü…þv«¶¢™îËú¹¡MËœcKËÙŽåŒØæc¾~аž“«Å[ËQ¥ªÒ¾ª”p½î̦½¦½a­ÆV⣵ÿþÿ²ËÄù‹ë¿ÐµÚÿw¸É]´Ô·ÃÄ÷ÀþȬьhëdÿþ ÿáˆá~VýÔÙtꙹØyÙÒo¼ÔȪðûÕEßêsþà{¨ôÎ¥ÿcäø¶ÿ€, þ© ðaG�AÞM9‘ÀÃvØ«¥M-¾° u¦Ê…@¯ò”€bµ_ž~‹Òì&jnPp` +;kr-RÀ„O�J6È‹P€¢$‹/¥õ8å©ß~˜å¡´A �c_hE à›¾ ËѨ(<ð3Kƒ0w<-PÐë…9-uÂ=Û…aØ�@WÖRÐA×O‰*à0@ùjÙÐ&Šˆ kta ‡Ú¼j% @´XxsÌåÄJÄÂB—/ò(€QÀé`V–(èÓ+M�>4!$%Dˆ5˜`-(�€¨—¿þÉ ¦ç©'y&ˆÌzSä„>–à±Î”+&žª”�ÿ¿ÿÿ(à€…ЀÁŽÌ1ÄO(Õ Š,ñÀ '@`I%0J>¡H¾ôÁ‹'4¢È0f„R RK„#Àp@Í(�@&„ÓÀ*©˜@À¼ñÅ ®ÐàÈ*@à Åð°G3€@KÀÀ€˜@�<:TBůŒð9éœÀL4ØA̬€ˆ&bŒ Œ‘5 ÐÒB ð �9_tBªx2xL±E–EŽ ®DsB& ,ñ'èpOy„A§@Á;¬¶ê*«þ¤³ƒ/-±ÊÀÁHÑåC4¬AÏ«Ä²Ó X°ˆüÓC:(2�*yp‚æxRì«'X(ªôÈÔœà }À…-È~�̶®¦ƒGøÉ4süÓN-@"h8ÐÏFð¶Ê‚Rp_/@Ä1‰ Ê�OÁ¬zqI/EB>¾àÒ@UŒ'L³óÇ ‹   ì4ÐÁ T‚�KÑA0Á'-Ûò…? €È“ —=5¨ 'r ’ ‚nDÉÃAøá�ypÃI _,pŒ*€¨AÃ'@7´œcJ‡”C‹þ5“€À D�4ò`È)�ÀÆJ-€6À‘€0¸p˧¬c”;:À6i8p€µäB°Dhr °³:gE3„ ìR€Ëèð9/h�Apsœ\SM ÈEË¡”€U¨àBüC-$‘ˆÙPÀ. Lð B@ ž¨r‚'T¼� p @"ÔòÕѰ JȾÆ8±„P`!pÆv�]Á/pìN€� ÂåxpŒp°-þ8Á/¸Àˆ� +À® Ðc@°Ä¨ xd!+óR€„< c JY(q�p¢´¸†!&V/|à €ê� ;chafa-1.18.2/tests/data/good/noise-32x32.png000066400000000000000000000035771517447374300203050ustar00rootroot00000000000000‰PNG  IHDR üí£ pHYs.#.#x¥?vtIMEæ 'u@etEXtCommentCreated with GIMPW�ùIDATHǵÖYpÐÕð:cGÛé"L;¥U[—Ž"-tÜPÁe PÈb" ;hX a IB„ ; ! KI€€’@È6 YAes­üû±o-/~sŸîÜ{ιçÜï|‡+Â#YjÙ8û1‚`¯êXƒ˜@ÙÚ…æß!ÿú%qºÞäT Q¥oÅB©ÑOôèÅ…¦Lf,aÉîw~㌢5äÈHbûô} r2¯ÏÚÒ+.YÞ^ ÁÈÏY6aСg.ˆ'¦‚Tm|ý´©.wA«¯<ä<¯áe¶Â}µ6³,]鬦…v»…ÈŠ¦ …X±E†5Áºbì»}�ÈÌ5EÒDõܼjÚ~�+[@¶¡ÚÀ†šä`áã¢Ã.°+‘�Ù T½ßsZ¿ö?x*[jÝèøê„%L¹(øÎB˱”ù'ò¼ƒkN8oR£Á ßm;a¥v:)]•&:Øm§Hâ†2ï£#VIö-Ù,~Ô}b²ê‚çŠ÷T`7Áá–2®eh]”5Çê–Fý.ÌlBƒ^û9Êô|†: ßÇ ñz^µðÐgø­èO€¬û”Mµ2>krí~Ö«.X¿©<¬v&yå° Á ?*ÝKìÿpZPy¼½ëûjƒ5qÊxÖ1hÖGlÏØÑÿ•Hœ·rkï¢)k¡–ûíB3K&¬9šñ'4»¢Ë4}Ç Œ…�ê/�¢Ç®›˜ÚÑmµôìˆYþßÿŒËú‡Äw3ÿ]_ç<¶�zU’pÏùâ¿­°§�ÀŠÐ¶°©ôŽL_ˆ’´Î›tï¡}iÔ9pÿ‰ƒÉ—Jø6¶QÞÈòÿG÷#æVA¼ªŸ¦ä<ºÌsÉ<šºK£»§­ÿhYz bq©±‚�~þò†Ñ+ÇšX¾Þg,ÿ8°£d{€UçÆµœÅ«TácOÇ›T¯w‰Þ‹ž‚êÿû›¢Ÿ™·~;Ó­Ûæ/jÿº L}¦MRĨ¤ÿÿPÌÅsˆn˜>wm¨¥9u«�(ƒª:ÂÍÉÌÿÕF§ó§I¿ª“¬FvU‘ÿg*KV Ç^7�P9€=€¬¤ÿWÂJÅ›²ü�n«Çq*²™‡<ºõ�[ªÃ€ÖkKåÙHÑÑ,|‰œS¤@¿ž¿ÃÿŠIgïÖ—_DÝ´€;Ô›FìI$ÿ@§Vº*vä\ˆ€ÍŸU_§D�€ÏYÝ«TêŠÂJKØ¥ZÿmxÇyÇ”aÂÁ��àêtœebÿ·|ì¸ÛiŽ•ŽM¦íKY§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇ«ÂÉœaTdÿЋNg‘ðrÌ飽dw×ÿÔ0ˆ²�X‹Ùb†°úÕJi�ª0¾ÕiꪇÅ­]–[ˆƒÖŽ¨åŒØGX¶ÿ�«Ñ�òP±Š¨ÿ³Wÿ<®ÿ] ÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈ/Dܬ½žÞ”c’®àÊ™”³ÿ©–†âþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈK¤�¤È’«“lX�»ªÿ×}•ÂߦY«¦¯o7‰ÿþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþȼO£¿ˆÐP ÔªþȽ\~�5#Q|`ÊU‹s±^�zþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈþÈÇfé`áÿ¥k MQ(ÒÌE±àŒriD"ÅÑœ¿q‚¾³Á1”‘É)Š*„‡˜d“\T€±pƒIã’O°Äăʞ¸˜–wšd¤Ò¥¶‹bˆ´Í�¹MÆö¿ÿyÌf�Ú èºÃ‹¯¡F•QhdTá?ÙáåÙ�WÿyΦÔU:ÖZ°šzKŽ’Cm²csÃ5¶kï0¹ÛȤÆÿÉGfëdг›Z´ÞdT7fY‰ÿà¯ë¸‡™¼’ÿªSí¶²¸ÈUŸNÕ§ÿ}µy¥\ÃÑ܆ÿË…ÆýÞj8ß|¯i�ãÀ§Áe�Œ˜¦¼`¿‚®³ÑÆ=ž}®tw|Û=ñX†bzÿzÅž¿°4þ’Ò §©Ó)Ts¥ˆWÂS¿¾„��¢¼Œ¯ê¯4îqa£˜ý‘ñŒX!——JÇ%ÿà|™²äX©ÿÎÕU±|š¥ð¤”Þx®g×ÿg£¬kc¤?Øí5[æºÉk’«à}‡OØ7ìÄÈOÖ—ÿ³Œ­¡öû‹œ–L,q´ÿÄsCçÿ~&‰†‰Î�óŸËÃÎ-›êàâÞT0ÿØLÀvÿË„m‹ú,~ÁËÿqË�tmeÿ{lXƒ¾�°Í{еù޹P¬ye…=Oº×zÒáWTchafa-1.18.2/tests/data/good/pixel-cmyk.jpeg000066400000000000000000000005131517447374300206170ustar00rootroot00000000000000ÿØÿàJFIF,,ÿîAdobedÿþCreated with GIMPÿÛC     ÿÛC   ÿÀÿÄ ÿÄÿÄ ÿÄÿÚ?t/OuSÿÙchafa-1.18.2/tests/data/good/pixel.avif000066400000000000000000000005431517447374300176610ustar00rootroot00000000000000ftypavifavifmif1miafmeta!hdlrpictpitm"ilocD@7,#iinfinfeav01“iprpsipcocolrnclx € av1C�?ispe(clapÿÿÿñÿÿÿñpixiipma�‚„…4mdat ?ÀÐm2d@$A<[‡›ÙñͱÃÀchafa-1.18.2/tests/data/good/pixel.gif000066400000000000000000000000701517447374300174740ustar00rootroot00000000000000GIF89a€ÿÿ!þCreated with GIMP,D;chafa-1.18.2/tests/data/good/pixel.heif000066400000000000000000000022671517447374300176540ustar00rootroot00000000000000ftypheicmif1heicmiafmeta!hdlrpictpitm"ilocD@;|#iinfinfehvc1—iprpwipcowhvcCÿðüÿøø @ ÿÿž8ÿº@!*Bž8ÿ� ²ÝUÓ\Ü4€"DÁp0`± ispe@@(clapÿÿÿÁÿÿÿÁ¬colrprof lcms@mntrRGB XYZ é 2'acspAPPLöÖÓ-lcms desc @cprt`6wtpt˜chad¬,rXYZØbXYZìgXYZrTRC gTRC bTRC chrm4$dmndX$dmdd|$mluc enUS$GIMP built-in sRGBmluc enUSPublic DomainXYZ öÖÓ-sf32 BÞÿÿó%“ý�ÿÿû¡ÿÿý¢ÜÀnXYZ o 8õ�XYZ $Ÿ„¶ÄXYZ b—·‡Ùparaffò§ YÐ [chrm£×T|LÍ™š&g\mluc enUSGIMPmluc enUSsRGBpixiipma�ƒ„mdatx(¯²ÈpÐ/ijÿ÷ëZÖµ­ï{Þ÷²¡ÿÿ"jà Ú†´õ’Y_Èr‡!ËjÚ¶­«jÚ¶¤³ÿØ÷@ùïó¿ÌþGà~à~ྠྠྠྠð&b¶%ˆY.5Àd›³ _àa¢ØZc@b¿ÿ `Oàëò' chafa-1.18.2/tests/data/good/pixel.jpeg000066400000000000000000000023171517447374300176620ustar00rootroot00000000000000ÿØÿàJFIF,,ÿþCreated with GIMPÿâ°ICC_PROFILE lcms0mntrRGB XYZ æ:acspAPPLöÖÓ-lcms desc @cprt`6wtpt˜chad¬,rXYZØbXYZìgXYZrTRC gTRC bTRC chrm4$dmndX$dmdd|$mluc enUS$GIMP built-in sRGBmluc enUSPublic DomainXYZ öÖÓ-sf32 BÞÿÿó%“ý�ÿÿû¡ÿÿý¢ÜÀnXYZ o 8õ�XYZ $Ÿ„¶ÄXYZ b—·‡Ùparaffò§ YÐ [chrm£×T|LÍ™š&g\mluc enUSGIMPmluc enUSsRGBÿÛC     ÿÛC   ÿÂÿÄÿÄÿÚ =¢„ÿÄÿÚÿÄÿÚ?ÿÄÿÚ?ÿÄÿÚ?ÿÄÿÚ?!ÿÚ ÿÄÿÚ?ÿÄÿÚ?ÿÄÿÚ?ÿÙchafa-1.18.2/tests/data/good/pixel.jxl000066400000000000000000000001541517447374300175270ustar00rootroot00000000000000 JXL ‡ ftypjxl jxl Ljxlcÿ �äÿÿr € •QÆ ^Îõ|ù¡ÃbÚÆu†¶Ú¶°$Qd›¤8$‰¥Á!w¼x@mQÌ}{V­˜„·’chafa-1.18.2/tests/data/good/pixel.png000066400000000000000000000011051517447374300175130ustar00rootroot00000000000000‰PNG  IHDRçpcHgAMA±� üa…iCCPICC profile(‘}‘=HÃ@Å_SkE* qÈP�,ˆŠˆ“V¡B­ÐªƒÉ¥B“†$ÅÅQp-8ø±XupqÖÕÁU?@�œ]¤Äÿ%…±÷ãݽÇÝ;@¨™fµ�šn›ÉxLLgVÄà+Ú@¦Ñ'3˘•¤Zޝ{øøzåY­Ïý9ºÔ¬ÅŸH<à Ó&^'žÜ´ ÎûÄaV�Uâsâ“.HüÈuÅã7Îy—ž6SÉ9â0±˜ob¥‰YÁÔˆ'ˆ#ª¦S¾�öXå¼ÅY+–Yýžü…¡¬¾¼Äušƒˆc‹� BA(ÂF”V� IÚ�µð¸~‰\ ¹6ÀÈ1�4È®ü~wkåÆÇ¼¤P ¼8ÎÇÜjÇù>vœÚ à®ô†¿T¦>I¯4´Èн \\74e¸ÜúŸ Ù”]ÉOSÈå€÷3ú¦ Ð{ t®z½Õ÷qú¤¨«Ä pp ç){­Å»;š{û÷L½¿znrªº (£bKGDùC» pHYs.#.#x¥?vtIMEæ!üÁ¿õtEXtCommentCreated with GIMPW� IDAT×cø/ü&~�îIEND®B`‚chafa-1.18.2/tests/data/good/pixel.qoi000066400000000000000000000000321517447374300175150ustar00rootroot00000000000000qoifþÿÿchafa-1.18.2/tests/data/good/pixel.svg000066400000000000000000000004741517447374300175360ustar00rootroot00000000000000 chafa-1.18.2/tests/data/good/pixel.tiff000066400000000000000000000107261517447374300176700ustar00rootroot00000000000000II*"(Ò€:B J(1 V2dSx¼[ ~»ƒÚi‡šs‡ úCreated with GIMP,,pixel.tiffGIMP 2.10.242022:06:05 20:39:43 720220605< 203943-2039 lcms0mntrRGB XYZ æ$;acspAPPLöÖÓ-lcms desc @cprt`6wtpt˜chad¬,rXYZØbXYZìgXYZrTRC gTRC bTRC chrm4$dmndX$dmdd|$mluc enUS$GIMP built-in sRGBmluc enUSPublic DomainXYZ öÖÓ-sf32 BÞÿÿó%“ý�ÿÿû¡ÿÿý¢ÜÀnXYZ o 8õ�XYZ $Ÿ„¶ÄXYZ b—·‡Ùparaffò§ YÐ [chrm£×T|LÍ™š&g\mluc enUSGIMPmluc enUSsRGB†’¸ Created with GIMPÿÿchafa-1.18.2/tests/data/good/pixel.webp000066400000000000000000000013401517447374300176650ustar00rootroot00000000000000RIFFØWEBPVP8X ICCP  lcms0mntrRGB XYZ æ:acspAPPLöÖÓ-lcms desc @cprt`6wtpt˜chad¬,rXYZØbXYZìgXYZrTRC gTRC bTRC chrm4$dmndX$dmdd|$mluc enUS$GIMP built-in sRGBmluc enUSPublic DomainXYZ öÖÓ-sf32 BÞÿÿó%“ý�ÿÿû¡ÿÿý¢ÜÀnXYZ o 8õ�XYZ $Ÿ„¶ÄXYZ b—·‡Ùparaffò§ YÐ [chrm£×T|LÍ™š&g\mluc enUSGIMPmluc enUSsRGBVP8L/Љþ÷¿ÿ�ˆèchafa-1.18.2/tests/data/good/pixel.xwd000066400000000000000000000001501517447374300175300ustar00rootroot00000000000000d  ÿÿÿ@@ÿÿchafa-1.18.2/tests/data/good/taxic.jpg000066400000000000000000010163561517447374300175150ustar00rootroot00000000000000ÿØÿàJFIF^^ÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÂUÿÄÿÄÿÚ ò¸t\ÈNmÞ 9�FT—a–¾Ž„&Ю®‚ÖÓÍÞy R !I¬© k96T q½¥¼e¶’Á@"—¤ZXr.r�£DkqåxDÝ9ÞóÀÅ a!!à€$p‰ªŽe€–�3'Y’„4vªË´‰a}1kZ§‚@Âñ@ø c�YY mpå D‡@GUUIÛ�Õ�×T¾wF˜¾�“ às\>IM‚Ø”,!81¡Â&H +¬­ê¬²€ÞQ²ŠCz)& XµBÓ\˜ Õ�„§Ñ£Hp†S VvPbx@(¶Áa! òbƈ–7KX®…0¬ËmX@'^’‚°VtìU›ˆcmÓªÕ¤ÕH¤»4!ªæÃL‡Óà`1‰ H0¸Ë-pÅŠ€hHHJxÙwy“½¡j¸ýqdé—‹¤ö}3'Á6€b� ”­²ª9„„§È@0%¢ ¦ ùôàž–æHWLYd= *¦áeª&‚\²ÒšÁ�à Z,³�*¤\ÓÑa‹Ž 9Îj¬qÐV–ý»õŠbá€pVEa,=0h C†"�`! (É „ë&ðÕ˜`ÐX Î/N³ Ä´æ¢\Í[¥�æÈ-:M.Š-0MUa;HÝ©¶¡ÒÜ™ÍP†]A0QÃ@H­ÃR%ƒ(ÎLZ¸�¥hHK ×U…>‰@dhËNA¬3)jôÌh™B‘ˆJ.ÒÐ¥^_dè�K¾ŠŒ³J�JpÌ)ÃÎt2NY"¾ÁfÀg¢Èf&ñŒ´ ‚¼¾kI¸@§“HAɵ€i®�„„´ú^nv®¯…Ró×’Û†1B° N«H 2ë'i­�@È9ÂN°­‚Æs9‹ÃK›gv¦´º“PÕ ­ý&¢uUJbkE¶’:“SS7Ø’�çU'�ÓFš\švA-^M,�Ô,|�fŒ9«"€!æF¤9NÅM|wæš iÚó¦4°%ªÔÎU“}/˜2rö¯ƒÉ Ý“Ùfᄈd"€ÆZiÌ‘QK³¬F]kH É 1�†è3Û09«¢³FÓYÚéê§`)B°B;XZ© ÀUh@ÓA²ÚÂUsH è@@ó ­m9ï|úM;�8‘Šd,¦­S�r!>§`,2²$3N³Jûž sP:ɘ¢–X×hÆ 9š�šÝ\±SÉ× †®#¦“–È Zâb¶5f¥ ¥Mi‚Xà+ŽÃ—¢˜K!7&#©5Ã`œ™¡ºgL C6Æ¡§*óÑè­hÔS©Ó¾ 3�\rôåd�±h`1«,T´RÍD±¡U9E„ï9ÍÊêë*¥Y“\ŽdùøùEãèäŸ*ê��BÓJ )° °ÚM$XAl+a)玠[@ÊNÊל�ñlT€»Y¥Sf–ÕâsZ `@ÂC˜„8d jC¥Ìk*«F„Ó*W5B ª^M8Ó“rr„P«ÍÀè´T¼LÓ.j�. ønZâi£=A¨ôÍâ�ÀKVkV®Šƒ€�&p–Î Oš¶…§ÓHUf/¥Âhišå—Sx+'q??—nyÚÃ-;ãÓ®Z è´áÆ[AÁ! M*­@roFj~‚¥Ù]L4Åé͵6Ùd‹�1‡„Ú¨ú…ªæœæÐÎNÊ‚€©t±d� m¦‘\v�Lä-0NE`:i•Á�ÍÀrJ‰Õ–±S`¬0€ƒ€Á!¤Ê¨4]—|Ä4‘ªj˜î¦m2àb«EB¥Òa5[Rw‚Ë•§Á‰F��5¡ -WTb5\Pu4Ӵ׉|>Ù!œ«VóÎ rbÔÚjÓpKF›@¢¨cÓ9j”¹iôr‹.£&:¡^‘•,iá®Dq!1RÌ2™¦+@ê@ÓB@f„%© ÙèBžK¨ËMk A²ÜOå랟MÛi[f›¤:ó¨�¶�àõš´cA!a0A€r 7QH,4@Ð0[ŸσÅeXÄWeà0±,�äÛ,Xä"‘ ªíTšÊ›sZZ ч4,ËšÐŠŽ í<4RçH`饠Ài)ÕZSN…I—–: ‰«Nl4 žÃ™£IÊe¥’ˆé´qöÓ–Ë—Tß׋ÀŸJªÚá’5ä×ÉZטœš!]lô+ÍךÆÄg2ê.ˆBÀÖ„1)’•0SD˜û›RV Q·KhFœ4Æx;ËÍY¢Å @ÜåÐÏ &ÆX‚Ë€d €À)ˆ4 gÀ�c! d … ´Î@`”êaO˜¢Ð¡;èÖAÌT·E1Œ&ª—&–˜žn¥m]Œ ’^L¯¢š«¹J“`\žbz lÕdu@°� IÒçê~¸Ú©¬LÒæ©+Êr�3¸ËòòcEͺáuÐOwIÅ)j‹ÛÓ=ÀÌ` ˜hÊÍ¿=-yÇA¼ž§*¶”?Ó�4ÖhK¨š…dhQÚ¡a\- ‚¸5¦°@Ðp,%9‚‚Ð@Õ6�k„†€œ6¥ ¬j‘m€UEm#˜Ô=UéÅ'ÀÀ0»ÂbÕh¬­³º�Fª1–‚‡sêI0%5®‰UW1+à$â§™ )Ê%¥2̰ÒåW**®¨9§¤5¤&Õ–ýYŽ™l†JÇ£P:(µ7êê-5æ]zg`VŒåØo<úÂ�çQ±*²ÑEBš¬çN s:šr7:$pæ ªe9jS@DÙk‚cJS¦‹ÎU–¹R¤g«´Ëv e·;²]Ä3RéÆA¬°.NBvЦVM‰±¦¡,²Ô§A¦²Ê,¦‘“˜š¡R kŠ�e ÈϹª\Þ®m]9ÀMŒ%è¡!UiLà¾.Ô»#zPÈE²j»!4œkTš´Ë’Ùž´¦Å6KM Ö-иm�ÓUÅvóDÑ\1TMæFóRa…EÆ¢¦º*ªk3/<û†¹Jw¡ð!š°õ™çÁmh&-pÞVÑ5¥Ó`Ò6oÇFF›*žøÛqƒ”µ]Ä“qUZ*TÕ¥éÏ~¹s•2iÒímƒ)¦Uu¦¥¨ÛžcJyma¢©¸@hМ¶ãU*ôŸSè“jII˜|�|¤YÑpUð°Š�†¡UywêRŸLZpí ÕTøOBÀ42#°gr¬®_$¸b‘ƒåÚNZT5PMg hÒF‚�é4ö…3Šp©jbö=~™®YìÚ—Àû¼llUNi1v­;@™®"å$EÅËQÍZ¥Ÿ5 Å˪+‚›U®ÕŒ¯S ´¦S9/²®ëÏ‹G7rKº,ÍUÍJ R Œ€ôrß—¦¹¹N•çF•…tkž ]Ô½Ï8¼ùé®ó¼gi+d1ÅqZi©¹ÍRœæÔ‰b©fÍXs,la¹šdÌ53n–¾u52ȇó¼E$ŒÕ]k“K¦€N».�àÐj–©K†®Ë¬:ƒSZ¢¬ÀX P58e‰r´Q«bæð}d š–¢Ð_І@«0ZPÉÎârŠjvÄÀk ,ÃPUo7 Òâ¯/Ñ™h;JE�©´›!+'V_+"l sL—Ĉ8$L0ÝKSªª@„‘TS%JV³jf–`h6”…4>žM¸ÓmgY¥ÓÍRÑ)”™»ž–0õãNJ̬æÒ¤9§Y©;s²–‡6u�ŒÊϾ}<ºvë ×…ÂTŽ˜MUKL A-@Zhº­l¥¥/Ï YìÔªjž’äóÂÄ?›ôã,©Rù½4e‡!äÄR‡ ¹3bÁɈ��™vHª±mH-šH×N’u%à YN‰Ó¹�妲�$J(1-*€rié"²zPÐ;T‰¤ådΖLJ<¶ê–Òm®›jj¬.½5ÚfL“bs'\•Ë¡[4æˆ@5ªÏ*hÁ{0á¦]Ì-âxý@ÜÍç^[hÐÁÛæ-¢f›�XÂâ×tBª|Ÿ£ ÕzHLž¬øè´RnĦ*Ó ƒ †‚´+›Ð_ŸwNf¸QJ 5$"LÉ�áÈø\" ©ß"uæ´3S èôZ—R§.–“`>oq,–†kÐ ŒÕÄK„¦„„Iˆ5ªÁ`mhBó9™X8š ÍY| h:IT H:Z“öáSgT›¥ƒä¸ÀhP IÖ\0IÓ@nÎ[{¡ÐÕgJ±)Lb$ sS ÊK±VM&§v±Ì l!ÈyIùëÖ¥b—“ŠõEè`ú‘Œñ +À{¸Ø¹Ý‰*T3Ó"Ÿ§â~‡‰“dƒ–Xhù+í OÒËÇú¹ýN€ %µ´(¸‚BgOÇôpˆd*!H¸l¹b�'ɵ·—cLEÉ‹ƒ‡!"àà!ˆp¸ 3VÙ±¬²Enk¢œ�±+Y¯.«�†�äúËP¦5VÈ”žI6g*ó¦{¶  Ð01sV�Œ!1¢4)!P¨<ã[h'“ÑÓ -N«•rNpç“«"©âŒ–0š„á¨A”ðH¸|”²†ú*˜£¿aæÂÌ–-«ê9’D³‚@àÓóñ~IíqV @> @Öªñµ^’pÌ|‚‡ƒÛ4:¥ù»¸=zÒç²AŠ)uÈŠ!#Yááz•éãëÉ*ÍW�)ÐV¦ž®E «ŸW”å÷àrÔ¤%H¤&‘“`Ïw_*îÜFæC„c‘p@H@HppR[eμ&èz•7é&^s[Чòͧ“¨ ¢H‡ˆN¡ÍU]9Ñn ¦1¬hˆ|&€„MÊ\«„µY9÷óW4â§—MìJÝÖ2œ€EHVÎ}�x,錓,­ÉAƒƒ”‹¦0‡Âä OËú}O�PLGI6ᜅ„Ñ4p;k9ÚãÎD-ç£Éž��ú•M|öj’=ד¦§ Ê zÉKnt$1¤hG-z#D�#?¥y®é¯² bÝçsL5žVžm"Íâ•Yúš<»]€õYXz88úÐÙÉsr.¥!"$5ïÏÙÛÎk‚jGàà!ˆp¸pÕÒa‚SÉÏoL5“—“æþM¬XG^+ÓŠ°ó‰Ú|¨iÑn%’6‰¬0%"l’à�äÄ!W™ÇÛa-¬óWLŒÓ6�’8ŠPÄn#Õïã¿Nz´òô+ ƒ“”iBbU*ž�”8)]`véZê,à ‰:N£‘Íò% Q,~kW‡+s-Ñ„W•) Ù=Oõ� Oeó@óƒõžnž‡ÍÓœÍ)L¡ó"‘§8rizÏZ‰¯îb–z(Ëo«Í²ó€p¹Ì´U [ãçèërtlµœŒ½J±Ò§£iéÉ£|—H ¤ðÀt££;.ý{໯$“�HHHà8±lXjI!N”ÝU¾òvÌ •+c°/•\^McªÞ£\À:Ñ¥g2Á„LhŒbƒs Ë92jC�CbåêeÏs^j*”KDÜŽsPƒ@§må·¿™S|<´ØÉfBFºÉi€à²Ë-;FZ6¢¶ôùV2”]R颣€�¶:V·Wð†C1¿(^HÒžŽ'ªâwÚ Þ¾ÁwOÊ[S-ó^Ç-TÕ{ŸffsRÀaÃ�§±`ErÌë?¢|'ÐsÞå¯m¯œ}|'p°hÄ8SP‰éÁÏÑôœ}'‘ÛÏžÃÙJÛo;Rø˜ç‚!Á@@Bf"‹ƒ€Û.šn—O†Ø†Ì„™yè×§ Nºªú®µV›ÂÀ|£(°[àõäÔ .l>U 3¢ –�¶0�L`¥3k‘ CHð²õ³ç­Õ,s y#hÚ6t×5ÃBªQ£¯% ø|¾zz.*ô>uJ"\ZZe}]Um Ú$Y_D½c‚ÃZ¾•Ñ9»!�ÑyºL“EîXÜâÅ’ŒuÛÇoË—�-ÁµÆý?2h4¶4ZÞ‚Âé_=¦ö­ *+ßx›ìpÔ\"�=‹ù'gXÝkÂûxíóW¶ñvr^sÑ�5ëc³çkìysŸÄírZmšЉ¬Ò·óYú~Ã�¤ùê¿DfÏ£··œ×3hPmr88R‰`&NyÚ–úPßJ»Ó ÐæÌó’ÍUÆšïZŠE?EZ߉Iºù<�¥»¢Õæ Eó–¹H›I,¥#p¤ b×"DA#‘pKl*XMÕ�ÞIÔ�”…#…!"!­¹ ƒÇºóñ~‡…ú'Ak­vŠEÌé"Ž’QM‰¢¦êŽê–¦vŠö‹V§iƒ ÑÙ;YÏ¥ó0´� Æñ©ù˜ºiÙÍú¿=ìñÓQݦ¶²ävu¯èO�ì”ÒÚƒÅÕO5ú�#l¾¨ó^ŽqG´ñôô>uø{,®ÈÖ¹Ñç­N|çnuöŸ]âoµÌçÚò™ßÆ�1pÀ"k«1oÈeë{~~†óPtE«\SÇnˆ)·µi§…д‘%(!H¤93jà‘ÖÒóº4ÍêÐi»¼óSZ,Õß;<Ý7ÕÖoJEehã"žoEü à ¶Ëno…¢to’„é—:Ýx¶‘‚@‚@BE!!#–¤ë�%¹hF¶$HT�P,b˜“Ju“R ~›Ï¯Eæ_kk­Hs\ÈDËà€]6bç7ƒQhÒõbžË³×9ÝF7]×·é8r²®¼ÈaMTOkŠýW™VÚ(%9µÛJ©7ž¸y½êO‡è[0ïÁæôZV–V.ª=�§®òtù÷¿�Ψ÷ KTÃ*Š\úO+[œ�Ó�pöw ºùGLà!¦i“Ó{›ÓÒæÐuœû<«1˜ t» [´�ª;¢Ý¬·©r \ˆ5!Éy{éŸÓ °X½)ØÍM›°W¼ØÍßmmR)Û•­„ØÍsËFMÅK.tvÂø*^ÁŠÞt§@!Œ&8R.„ŽZà±Wšênj¦–«Ž¤ÕTê¦Î(”M)G2)À,w1m’DÄ9‡±²[ÍÚÈb"—1z ÌäæEØPnwÎv�ç[¯C1é¹Óõ ÛYdx�|íXžz÷ÌÛ1 ³yäµK{]K°²·¡ícó�‹p{ sl+[¼º5znð_³ñµùç¿�£ëÏÖ¤Ùœ«~AW«ðz,óÓ½.óû;Òâ^Z7‹*HÚ5}ˆù†‹ÖKô¹ß—©ð´?AÃZØVžÛÈØ±¨óæÙ\5šô¿*ÚLJPƤ x�›ÖÞ´ùrU<¾½nòÆoUÝä‡ùð®�Y½:UüçK)ÀH|k-6{ó“]JxZdÙ|õ'J®X&&¤6µ!!ÃáKow™OËÍâÍØÌ»‘{%o7o"ĉA d$ù΢OE6çµ”±V! ml�¦Ì–ŠKÙ:D�TOG¹dt:Ýkñeé80m}ÚZèÒÃu3�ŸMcôè¹~ûÁÛO$&ëh˜kÚY ¸õ„Ógd>î?5o_Ž=Ÿ…ÝëOÑÓæ¥ž+öþ.Ÿ>÷óõýYz,�·Gƒ_aãꊗöÎ=ó}ô8™çöÅÊ;ytc¯ÈúPôzf¾hË~ÃΫœÔ41¬Ä¶Yc¥_íŒý—� [kÔ5¤–„¦¡¤ÈpV»ÂîÜÃs‡�ü÷¡Ñ¯Å–7nº|9—V½Ñe+W ÑÂE²HÇñŒÐÖ¶®8T©=š j³Ac—"sR ¤a!"šOŽ"æ=ÞEW��(Í{/"´ùÙÜ•Ï'ÒJb2“‘2ä}SêQh…ÉÃ&IG°@åÀH'y~dÒ›JÐd;Ý“ƒÔx-�Cæá½ÇÉÑtœ�OÉz½;ÞÏ{¯PëÍ™2 �‰læ¶á¤¡=Y·7c­cûÜþkÐyÙnòekjòþ–¹™ëïü=>sïç¶óöYgM׊Û_iáí£ƒMKÙÚG :ùÙÉÐì6¾ui™ãÑoÜËæ à³Í^ÏÉ»6§:].Cš†ÌWzË^ž?“ÉYb—®©Ó•¡)â!póöÓ·m|õ¹0]?)êuz;=èo±çâ<¨ú5®f¶9 GÁ^ŸÆ£:ËgNΖª—i›ï=;^ŒÇRÔ±¢¤À�‘Ø)*E Ú¼Š¯Qšö^EjäOIÒùœˆa#™!#Œh²²–Ï9ë]JláM)j[ŠE''_»‘ü]•�©çsR¹¦¾µx}OMæsíñ®d46Š+‚®¯ÄzÝ oÞøzèâ9rÊrÊèc–sjYZ·ÌáγkÖËÆ÷Ï”Íû3 \'¯O+èmè8«²wyrßâÃÎ÷ôœií|}›- 9®¥É®Óò³†•jno÷Ï“ôóò¹¿}àïo&ÉcR›GK¥�u aæÎ*ç|Xôòðy�‹õ>¨Z’ZRĹ™}çuiµÇ�ÜcƒÉú��ÍÇÍzîùÙ#ýé=7{9§«ô|YòŸžêÓÊyyeêé2mºd:fA¡KИf¢ h fÓ‘Ä)(…Àʬ§~=^t_°ñïc’ºç©K\>K‡Ô¥œÂjYÈè®ÆÏ†‡I†¢—RææHjQ4C:Igwñ§«œðÚxú§Ðà>ééä»Ï߃ܼv‡©ò°tU]ézËÜÙÝÈ&ÂÌMëÎ÷k£Í^ÛÈÐÉ�g_¹WëŸ1É[^}üm{M.¬îdÎ[½Ì~u°Œ�]æàÙ^'×èPä=wŸÎÁùžýý¯�¦§-Å$ÒcRÉ@¦ènÎÄJÖb‘ÒÓö²ùàýw…½œŸ9±„$\ˆÊIR¹éæÎ•ó0ÅÞ}N“¹ Feâ0ÈêÛ7§OGçs:T†fÛ™y_K§ÑùxgeZZ:/g ü÷eú~ êUeuXÉó¯;7R·µ7;¬t‚kB–ûÏ2&»V c\3´aÃ1Hp@È\ë5ß•ªÌ�=g‘{o©u.¤LŠ\Žd£“”J:\¦XÙçP¬C\×QÌ$¹’ÔÐçÝœGÃÛÛâ�á²»£š5È fUg>¿7¯W’ªZ|DžÏÊÃC!vú‰õ¶©¥zÿ/OE糊›W½œ~wÒz¿[œ÷ÚN—¯ŸÏz¬ñíÍvŠ¿­6·ž}o�†nõçû5ÑÃ?Qß�õ:/e§¹ñ64 $i7:¥X>†°jŽ“-D\ÈXëšÆxÞN¾£ÊÚ‘³gÙË <.JÙâ§HrK9O_ÚÇO™vN…Ϩ´Í”ŒXý[QéÓÓyœ¤—6#áyK§Ðy¸`ίé½Y[XD†vµ™µÝ‰»Î¾Q„úpóÕÑpÛ ¹¼çÒVys %Â&„mµÃà1Hp@ä\Ý_#W‘�úï"öøê4ŽjXt†‰ D‡#‘Ñ]4YQg\ÁÚ§…,ë )dÒ£§œ=O4vÈ«j¤¸�ÈÇÒÍáôŸ�Z’æ%œkWÒ� Ø�æe·Ë6¼íkªémVäúÏëk—H´}yÐösó<Õì<}:ÕïBÓ�çߦòtVÓn߆ôcÏuÎ×4z>[œfôïæ=~�ám¥Îå�I{O ÷rÈòô_#K“<®SVÑÔ‰žÖ4Ôö>¶ð¨j×£ëeòÔèÉ«Ë~×ÈÖÖNEÔ‚Óõ4ýœ¾m'žèŸk¤êæ¯)`²ºuÊì×Õy|¥$ˆJE¿/êt/7›Îý—>nÕïsFnµ�Ó{<±£œ×—ò|„‰ÕÐõU•3~uT]¥¼ó¡9‹–Š@Fç29„EÁ ‡¯�»ÅËOYäÞ÷ ÇR–$8%œKœªFRL×49v“,榙Jàë�ëåîn˜îâ�GÍà‘óˇ#‰®s3X¹÷î|ç²x¹‡ÁÁsÑ�3ëçäñÜ[PHp[kožŸÍ~“ÉÒÄ«žæ>#©køzéâTht*~”Pð÷»šg=ƒ>sôX…¯Gçá­Ë”Óñþ§^†î|M¬ª—sgÖÊŸl‹¬æ%�Å–vqHÞ'Išže¾µæ}§æéêü­z–§·�‡ì�,É@ñvÒä²sÔ†‘çZ^ÆX]óM×±Ú5³ZI=×:Wzu5å .i Çqá €cR zy /}_—^ƒŠ†ât\#`°0×Ë÷ª»%Ð!Á( cÈAµ$m¡Â|–RsOíómup’|œÞR烕sžO ŸÖô5ë ‚Ž NÇJò¾î>U9ÑbO}¬z€r~~—™á×Òxú¯·=W?Ÿsתóªo=èú�Ý ñ6fUçý üÇ£2/QÁ†�6x]»äõiíü‹ÓäÐÆ=¼Ýö±ó¼—¯Äù c3£Æß•'h™d5Mõ£Àg^ïÂÙ’ký?ËvYðz¼ßn¾§Îׂ؉AQci³ìeò‹7w�lÍIOI�Cw�ݲ麇.z\Ùãvk«Ã—š�½.Äêïd°;+ÔpD¢äZrõºÕYµ¢ý˵ÇYãž�’Ð1lŠGÂ�àáȤ8ÓÌlüî;zo2·øÜi<ÑŒ™º4ߘrJd�.¹Áô'ÆMs 99 ÒJ9È9”ZJÜM½0¸ñ¸âÆœåå°õ}W‹ÓÈ<ê–¦n啟´ÜÁßÅÝ…¡ÍNEމ®ÕÛ6=Xð²lx]q§ºÂõ³«ãk¯€î{‘èûØx±ùºt¶›™Ï¡âÇKK<­×è¸kÕy¶PÌq¤Ûô3óÞ„iù> 2ÆT\ö̬4•Úæ¸ Ís”èŸ?½ˆz?MËòô¸ãÓyøø¯S}~]½o•¡„ˆl*’o_ÛËåvYèÏj ™V$�¨m6ÛQ"Éê×G“¥¶N̳ԨzùUðú/òÓq}¤ùþÕK¢}w“¡3¶‹=KÏz±áõ~;ü™`õéæû÷õþ]ú>F1M—-Xôsó^”?Í­~ZšRMØQãg‡EÂàÐõsòÝñçùkÜxÚ¿:»ôÜß#³ÓùylsO˜îÓ3£O ø[> —ÀA!wÒ�#ìcå™ì‰ÖJ“�…Ì�MW•ôúÙÉÙ™ügµœæ¨m¡�‡wlÉÕ\¨p b M¦­<ó–uÁîM¨M�HpØ. O…Á!%ÖÒüTh\•켫“Ñ5všôÒÝ*+S¯ 4*‘0HXHsm“ÝøZ„T‰šþÞ~ ~cE켎6Ë)tö¿ët�{"·8(©+tÉ$P2ƒó|Ît“„Ï:‘žtÀé*ÐvCº½ü<ŸŸ·¬ò58)êxok*Ú¯ xºh8ìÚöZ=‹ÂwOŸ—ëüÞ%èïw*÷žUZÆÆÒëW}Œ¾OÖøÚ>Iµ-&†Kg=»;]Êu’¥gª[éÇËÙë|}¶xëƒGÞçù—I­çgµÉ8w‹×§Ð< ìC‘Jræl±Û^Æ^(=È´%=K4RÊZ[á¥'…zë›’Ž¥OJYMÄ4¾YJëO mV ¯+s%Ö u !Ákž L…Á N‘zVgšŠÝ;b×±ÁÌ=ÑÛ¥jV�&yt»5ÉUÒüç¡Ó£Î{?CDµ#¿ég“Ô¼Ǫòù¯f‰:ÚWŒõ: ¯_ãé«Êå¥j¹Ë%”¶& ·7!À­W"Z)e5cžÑÓ˜é*ÐnC´'ÜÇæê½O£U�Ö‚“æÛù6äsD>”üÇ¥$žãÅ×_–�4«’õF7«�7M®&CR%±ÐÊjA;DÚ¿égŸÖ¼½ž õ>fŒ—!sØÃÀz®9õ>|`uÖ/NßGùÞ–%Õ1JBQk¶|ç·��G½su™$²úôÕæÍ‰@ä!ž éë4M(R!Ò5•Èù7*Ë‚HZ®^s�;)k3m„�FL‡'Âà�‘õÞmÒ܈á CWU6¼î«jZ8ÍÌÄ2ï•…36&)bvm�ÝÑê<Úô~eË9©ô=lþM«ô^6Ç6g-Vü7±ÖAí‹óû¿66‚ä“”Zõrò~¾XH÷BFO–.ç—Œ‚´aξ³DErR. EB_&ob。À@ËåâQ7QrL–¸8r) %Á C†–ê¸ì‡!Övôõvámòg©ÏŠî³Ñç9Â×çVùòó—FvúûÏKÜî*d ‚ÍÏw/’Ó»Í�¡áÀ“†xoc³›õþMnðÕ}±¥ÕùtdÑÅ­Õˆ¥¼ÔÔE2ÞQªÎhú‡¦„ Ñ2E�w/•èú N\÷¸âæj¶ÕáýM�5ôOW\È™$ÍPѺ �:-zB´—hRõóðv4ÀGÜ«èþÎ�z'@IœTQOÝÃæ½S€Úã¿{ánÄEHZ9r˾Î?<ôsÖKгÎú:ÔÙ�]Âw¸0|,ž­uù2 ä-S¯«´çB¦@Sá¬p?”Zç6ÂÈ”;Bc òË•N™é½Á0†nd88d)¥Á CTuÒþ9Êy};awì,ÐÊ}?Ÿ‘JË�wFk>Ñkh³ù'Ñy¼þ7Öë³�ûŸCÜË%¡O_Ô�Ÿô™¹Çªó9F£Çz=Š·½çÞç dúôöu‹­¢æ[‘ÒŸÎífôùªþ«KªrûÏÛ·…eì¾�àkw5(Ïf>Oз¼üwø¥Å.�5×^s¿_KÁ~»Ïd“%Ì;8êšF.Ñ^K¢÷Jù×jÌG¬óòáÃÄÓ‹#$$¸šVGNž«Í×Ùùv«N‚Xq@8µáýŒ±ºáˆöžNÛ¼H�&4E•H­ý?Ëí{3ÙÚü÷¡¥.š–C Òù˜?9!ÀBž éëîXèR‘@å )Cùž�–%LË ±U ƒžt§jêXÑ5 ÑK$!9s!! ˆ\5Ñç»÷ô~~u¯9èôÅ…ë<ÜN2ëË«~{†´ù^§t©—ŽâZ9øßW«‚½/�fOhº”§ ¹Ù8�ËÆÉëü¾AgSóý»ÐßHLäÚãv!N™^Í\ÃEP´YÆîsè*]œ×MèÇÎjëßøZÝ„:ÏKl=c?–tùsô¾~ltL†¯êìš~×Í¦æØ‹Üõg6�¦×6‹ÑF’6+ØËçº\óë¼üåÙ ‚„ˆ&ˆ‘Dù?KZ߬òôßá·gPÔ€PhÍè–ÍèsS�RE(¥×3ªï¢çù÷,ú¾ ½'«®?F˜>–†ŽÄú3’Ž÷{Ÿ5KÃ�}~‹‚B@Fi(¤•óÍr�–1ÂÈg³i¦Ùó­4Y ©¦9æˆp†5!ÈæÌžŠ@ó—ZtpÏKÖ‡6~Ukåæý›^‡�œÔ ߥ?ÔϼüÙœù�C§Ûø·¥‰0æÔµ #v‡{y|ȯYærXÎe¡œïéÍßCG­ò«kŽóú²F¹§Y²¥LTßáèÖóz“ºV˜=±Þ+úZ|òŸÐ<tðU:ò³Ï«swýœþSÖ™œû'ºm4ÛnS‰Ñ^?Ò×gš½§�o€Ó�$G{�^Ò]ìcóJrìü¬5ùç›krÉl˜HrèBÂN¦¯Åz{…W·ò5ô^v²ˆh4DK‚s¹–h9!¥ì¦¥žÆ>k»:¾V:ØN﫪µ¯+ìt6Hh(ä_ç�ÿ?޽5øóT˜“§°µ#€ ZfÎI%üëlÌLKnÔT9²£t%r²6ˆ¢µÉ“R.¦M¸$b‰f_FØ^†ò‚³òðÍ—à§m^ õžM�KP‹ž~Ó�?3 ý¯;}ýÿ‰N“³sk©K‡KÞËä•^ƒ‡ŸW“a#Èz½”ô¯IÁ‹ÍÚ¾ê®Ù®Ô¹z…èpŸ:my}K<ã£.¥­¾ß,ô¯ð¶ÕÂ+ôAçV±»þÎ/é+8÷F/)¬VƒqKéi™Ó~ÛÆÓÐùÚ’T€nÉ”¶îyï£çùû40�qäs½ÐÕ5!K�ªR,”òz/Èz{ˆý¿‘¯¥óô�%Lj&‰gKée ¥’јwä^Æ^Ž}™‹G³êi=5äýn‚• ]�Açc¡†b„§�:zÛ\Pˆ€‚@�•_=ß1d8Ç �¢áŸ:6®“œ“F3�„¹–r ©ŠGÃHy¿Gª–öAk9õ~f]ß•Ï_sàés#š*"GúÙüç´ô^_?›ïßGšý�•LŠu©d´Ù“Õöòù^îÏ6^‡ƒ—›­wä½N²•î£Íç§/&uöW"9 B ùîÑM‡h(†ó“¼eåUiBDndn°ƒ‡.$$¢ Ïwõlñ`LòÞŸPY(± Õùxù*¬^]½ç�¤µÍHúFûy|×¥ú_;ŸËz·Ê­îdRõÎtž¢@h94;çÀö�½_—Ç ãuï‰×¶·4ïq±e}’êWm‰Xˆ‘ú-ߟèÓÉËõ^]ìr·Ȋ~;ùÞ°Yè9d©VhÖô£ÀºóÝ“ìü®{ù&UE¶JÎÒ¼g¥¯3Géü½5ù›aÅ.em ¯¢çñÓZ<óëüÜ›9ÀØè©²…0ár8!Žg ìÍÚ¼Ïf”õw±{ü7·ÌíR�ÎÕ¿vMˆÆéšþÆÎÎ÷>f‹]:Xõ5óÞ–ƒnPc”P G£ópËèÑ™ ä^¾ÓJ\›�W+ç›f±ÖC‚›.Ç‹žUÖ™°ØÓÑ0 ¢9 ÈR.nž÷k­­ùÿK~Säãç)ãñíí|K›\)Ne—¹�Î5­®<±zõ÷žÚÂ�DA¥ �‹ [¿=éO�®ò¸ß+Ëz=T6¿SçMÌÊ=p­däÛ Ñë;˜Ö•Ó·‘ï<@tÌ›v{RWKU¯‚°…�²hz¹øÁøÿB}_™Ï·Ë-*4k™ð~¾õô­¾gë¼›µ•2ó¨dŠC™¥ícâ;ãŧ¡„û�7ˆb `H1ˆ!ËpÜÊà”6ªº˜gŸìÓ·dÓ¹™«ÎhàZ…,ÏÔÉèy–û7-.xå&Þ·­¿œövF�©Èpp¸^Ï:\™¤¬œïØh¥Ò¥pÈP€G̶’b‘ÀLä4/Ö2ñ¡:Ó—iæl…\—iùÌ„„„"Z”倽;a÷ïÌ”¡ž›ÍË&›æÛÞx:M̲dè¡ú>t^Ž0“O{àèrãX FÔ²@m25*zñóÇ^“ÍåÐÃ?êöªß¬óò³–‰Ökí,EmSˆ½œ&«{«_›Æ›œY`÷oï|1µ‹Õ·=�ɬ7ÉÃKÿN<Ñ^Ò�AÁ�¤áÍŽ¢ß“í¼>Í.dþ‡áèR>s¹ÐW/©F‹_ØÏæ= Í�_ö>^¡¡R‡-M•\˜¤ àÈÞ¼ßv�”Ñ¥RÕßL@±pÈò�Yçã¥ÎŒ –ÛÔöº|w³´²@‘!!!Âô9óôv Ouõš"¤HøP’“ù¾ðb@åÃA…êÄž)ZP�É&r –×,©!ËR)€�+¯l^ݤ$PÍŽ8Xòñ¯²ð4³+€“™hú<<QÇ úÏ'Nh‚‘¥Á 4² >î,·­É†ç&>/Õíæzÿ?g¦w^dß#3™˜½/Büg;õn/×êö>Z¾ð6ìóô·‹Rš¯Ñ‹©¢Óà¹Ú²ù×¥:¼¹úß7'›Ñ^'ÕÞQï|M6¹©{Ca–Tûw},óü�b§…˜Íw?‘jf3cš=×—›Z�ª{ Ò¡3!7!•½x_xBò$+‚A¬pQG¼òy¯äÛ$¢Ôµ½]ü÷±¶wU‚D¢(æ]Â}/—Ì´ð§_W ñpWTc5+Í¶Š€!p*¡ Àmc}â•y²Ú"k“” RÙ9Rv�0àUSeeõm‰Ý´Š™s©åçç5v<­½ 4Žˆ—OßÇÃçbß®òko†ä:ä-QI7 ›<êeé{|£zvYúNoêv~ÇÌ„êéo1F†%Ü̾Œí,ëšßìÓÏq/Içãã½n�GçÖ¬áÔ™žö¸õ8¤öâåUÙf  ¿—z Þìü®v'â}~Œý«Óùõëü�;Y€l“Fϱ#CcÂÖÉ<ΤYS¶ ÛËäô(=<úî Ã9[ �d©:©lGá}]jèõùoѨ§…6Zè„–‡\]éŸ5ì|œ42Û‘ GAw¿_9ël�"BdŠ® ¸¯EæsàtïvUcMûP�„ÂJOÀïÇmª©ØÁJ+§ Ú` f"k†Æ‰©  zéo(«­ùÏKªEÀ!#×ó¥Üq�Ô©ùÛûÉ6ögç=¼¼´]˜=ç…pƒ2®ø²EÐé¶Mœ’‹}ÓäýåiÈ=‡›˜;]¥èˆ˜eìñ³Ï Îµ½•—çÆ÷^[ÓèÙáÛÑq¹htÍgÄè«Ú±!2ÿ¡?.èy{/iåáä=-ˆ=÷‰ZœºÍ©i6XµcÔŸ‘î¯å›_¶ñõô¾}Òpä%>¾~+¶|=��mæc¯Ï ’S–›×•ô5«£à¸‰É~Ëɾ—»ËPŽG#ºf·¿�ËõÞo>×4ì^‹£½C-æ¶9óô=µúùO@¦RH �Îlã,ÅfEúÛèFÅ"�'ó�äâ&HB7¼\ñRª2ÈDÛ�&¸fä™! Ààà�ªß˜ôúùœ2“sÊÏ>âˆûËßÔy•cª|�³žÖ¿+ö5�É ™K£jÞZ¶,XÈs�?¡e{Yx:r‹ø= ^×|üï £¥£ÍLÇJîêzæooñcå}>�žM} [Ϧ‡t¡*øè~dÑ£êGÍéùþ¥s9«¥z~ õþVÆ>´HU­Néð›¿9¶~çÊçò†Õ´×é>&– 8|™…ïo?›ô/4ÆÂ÷þnZ™)O¢¼/¥¤2@ÂòŽÏSÆý�™z9�Ÿ"d� úL>DÏOç`.¼×v�E–¤�Cšú…«ó~†’�g#Õù\Ù»èþi¥‹õÖ Ð!äŸÍ÷�…±$l�¯<^l6 C†b�–¤dÑ X@1HHùžgÒëU¸d °´x³tÍHxÜ;mrO”õE'éüËßàkÛ'ŽG\OÂå²@ÐpÎ(­¿�Žä¯CÄ•yÂÑùS´~ƒÝÃÉñ6r.¨–YçÚ©YþÞx¼“é<øò~®ÞƒÏÓÑr…¢^ɼ׻ëÅv³|�*²ÆGK×ÏÀg^W¾d,ç>÷Ç58ú'Y��U{Z‚ù'Jôœú8¥¡á=~�IÃ~ÏͦÉÁÀC ?o/’je†®Šöü±½-‰= jb#°ÄØó–¶d÷ž>¾ƒŽ¡‰¢ÇÑaò g5t~æ—ªÓŒ¯’½sTlôù<}-"ýŠª÷�ÑR¹ãÒù¼ðŠéå-=MèF©BÕüß|ì†ôEš ¦´ZiÊ‚²¢ˆ\Û‘ ¦ˆ�c`¤8pÈ .îŠ[ß2HààØæ‹Ü“çó<ñ §Ìä{ôyÉéÌ™2× áðø‘Ãäô½œ¾ê<ó„)œ¶Ek{Yy,Þ¯™}RIçkU•ìeƒªósñÞ¶¾“‚·ùÉiVOÐú †óSÉÑ�›€ÓôãÈa^G½poñÏ©óu~uÔ¤ Igbó=kÌR÷^G3G2y�C\~­=¿•zü®H „îêG»‡ËÛB7¹#ÒòG–îÓ¢­fý—•z Ñfõ™=“æ,Õ“Ôyºz7(”šæ_$Ý-3IÏ‘>§� B––´ò™z´së÷”föiŸ»�ôž_=¼g�òÖž³D#0Q\œˆeüß|ÚAÁm¨rÇÌ´gM±)bŠz™ k‡" –@¸*ëjª½Žy�;cví à�à�ôW¹ò˼úYDÉ, ?^>W¹«Í—­órЦæªèxc£K*ú/ƒ¤Ú$H%·åW;çÎûx|ö)höžn>?ÑÛ¨öÞN›üm‰Ó^Ÿ¶òyôùæ-œ¨KÍwiç{÷öÞFž“Œ�‚Xü\Í_ösùÏ|ytåœÕî¼k±!0Y�Ü6]¬t¯Ô½ç�­•2Î@7¡êgò^Ùô>f¾¯ÎÐú¹Ãé¾nó@(^ŸŸÇÒú•�Ð÷8±d™=Zkrd‰~|×ÚÚ€0,f'Ë7™°PÆKÓêÙâ¿EÃ\#´T¥¥Sd¨£ƒ‘ ºz^„y\«k‚¢"Su˜^¼ix{[ÅÆ“Âhv)ƒKÖlÁ«m&ÛÏZ½«Îú9Üóš†Èf]³óÈ¿aähM+itœ‹^¤|³¨„1ŒÇ2z¿; N|ówÓÈz{úõþe$Ùfgõ*^¶?—bµònî ƒ™ €±ùWgvr ¹pK'ªu3Lµ G«å�¥åJp2jEËOÏìú…¶îphàá@êËË/ÕÐLàZ¢ ò½¦ÃJ&ÓI&Á&(r@•Y±l$ÀA­¤69‘�0\9k‡Km0;÷ê8|††—4jùxfñÍ|ß‘õ:½W•{<ŒFnf—ì89�c –Jf‡TùþÙÔñ5vo­ò=¨‹¶Ÿ-p ‘±¹Pm¤«Yv52ÊhXÂô½(ò¾ŽZ¾=ƒl‘�K.úsá°½® ¿“ %éJ <Ï{<.;Òç~‡¢6ûsÅØùlÖ¿~“ƒŽ­sµ¬^½>‘óûë`"‡É! � O_�v¬þjú‹£á�¥©¡v›$§ ¬c|¢‘_"i¹åŸÜ=8«Ûð:¢UÈsD.Uãpöv#§ÔD1.QVk-ß®²!Á ð|ÿ£ˆœˆÈ\4*Ì‹y$.c @°`KKE!,„å®Õy¯C¤4|Ü Ã[“-?7,¯>ié§—ô:=·‰Wñb™5 ­A!Í “‚P�Kt¨ûywƒ³å³'4¦ÄûÙfxÛnùúJåz&æûYía;+!t´*±Ã¶§«ŸŒé�Ï&תrRÎ >„ùü®¦OÑðÐ�²¢‘3Ä{Që¼]lÊ”Í+ÿEÍòmnç&{Üyø¯W§Öy¸ù/C]ÑŒ¾8Ýã�êô2Ï,`viï¼}5¹�¬Âd¡XÆ­zQæ=8¥æéë|�º¥ÝÙ§¦|äšXVŸ%È.‡ã\×Zæ‘¢j8$9�ìù…ãz}íùS§—- ˆs üO?³¿>¢`Ò$!<ƒO]`‡"‘óîŽ3r AÀbId*ªóâÜA€x¸D6‹€™B���åulº{<˜S×\>ý‚‰Gìרó²Éóò©Îñû7¥¦žËǦåkÒLDÔ1VœŽD§ $pKJÐd•µ0:_¤ãž¦”²ÿµ—‰ä×Ôù«çÏ>ñ×Î~dÃ�…ŒJhœŸE2*ïÑóøŽjôÜ‚¨4¹@ê´úO�í¼‹�&Æn—Ó:œvÀàŠW;çÖËÉò­¾Lü—¥¼É¹ËÝ7£•{_&¬Ã `«XüÙ�GÚËæÅ{?F¤ïB<z ç_šý•f—°´”Z|œ=”=³•Å¥ž /Æg‡ë‡©ÀÜ]·9^i�JCç=Ö4¼ëÙå+hY•#ä"�ŸF~sì¼�_' ©u)bÓkEK´S³­êåáyß âÇÉú]�μØÖߟkÌôt}Hññ›ÆÜB¥3‚I¬—~¶¤@)ðHdççÝ›üUO¦|�¯Yîüš»˜@›Väàáª�_J~r«ÖùWn-9.¸ç:=!÷2Ëóò¾õ�/K�édô1züÏG!Áw×ζÇÌmÐkPŸ¢8´"R@*¼¯»�‚*lõy?K×Í€ � €p|󧈄aÍ%TÀ†±âFÏPÁHs) ÆÑB3 …Á ª«… ºª;éK¦ô9#_Ž<ƒ×!W©òëO˜šCCëSK­HK$B9‚%Êj‡ÈæÑcd8e�;e•íd­|½Jå�Ž{˜÷7Lòv.Æyýs›Ðô%:žŸ±ó‚¤XÍ𠣑­Þ¾zß­óiÍJNNäÌ�WÕ]÷°ùŒ^ß.x]Z{?*öxì�ÎoTèb:Y!4›.PR×Fç§k�LÚ=?ŸU¶—ÉÍt±N¤qY^ÆXiú?>®fpKG¡§êç�oÁP‘ =Ò�š dÄ@´ñ°ôüö>ª*-tyDÓ�„ÈH 8>sÓŬQ�1é@¤`“¨L½¢ "à CoS!,°\2€³3£lέ=ŸÎÙBÜÒ¼Ú”W°ñnþZÊ–p “‚ZI7<ÀÑ5‰efÚ†CŒo±¼ÿ£çÈ\¾‹¯Ç‰®ÏrqÎ]à{¨�¬óÓú•ßF~l«kÍ­®`©Mª›«�sLð»}Sóžõí<‹·�MH*“d™Í?é9¾Z¯‡/=Û¯¿ðõÕçfÂnµ&¹&Vµb„¡tiwÊyïÀvOºñô_FoÎ�2*‹’ Ú§Àa;HPpXèVý ñµ^@`‚ª#ÖÚjP¢SሹUxÙO<§§®´dHHppB5êãhHŒ’Œ€G Ÿ:r™  ��K‘2Ac`¤8 RÚÊ©µÝÇ2 �¥éá#jÉïùïk•>¦pJ †AÍȆè”—°Ù$R Ð8f‰‡ÙÖ/¹Ÿ�kÝóÄ �˜âo6xÞºy»,ÉÓ<¥dýw‘}qÔœ¶$ �›oå©oÅú±³Ë[\¡µH6¢S(»?GËò²÷ø±ÁìÛè^º92´l®; KRÕVX–A –Z݇‹Ùú_6ß ·,Îá háÅÏi2�aË”rÍBjöÏÏÕe*�hzWŸ¯©pšùé‹ËéÖ�ìéϳÑç:ò«&S×ÕÐb��áB`.GÏ:¸H$R2g&�æÎŒS"1Þ) ¶âH$6 B@FDðpÁ³JC€J"[WJ¯Ågµdà%°40z\åÜÑ€ÐÉR�l¡È¥4è71k3.)’fŽLÌúkÏöÎæ¼^§£Ç$ø™ù¾œpúUî¼ï ²Y§‹×‰ �ˆˆ&–ÝÏ]/±zލ”šÄh¬ ‚P¬î÷·�Ê�nñg�ׯм=/JfŠh¨Ë²T¢Ä³�-91oÏv*[\OÐr²DËP1¡¹à�€9$&‹~œùî•à!;)ßsë*w ¶”Cò|^õIè`’êá�¤ëðÆ±Æzû;\¦F@"äÄ!/žõpÈ„ d*:uZD $FâH6´B0�¤$|× ™1@Hpø:ª“¬‚±sµ*à€àä: Ÿšl¦Dà ’¡’!S—v‹¤ÕTÑÕÑõ( 9öo‘õ“TæëÄŽêµ@2  DžÖy•:L±�.† åÄ€žŸ±—ÌÝ_À£³öþ=Û�º#ev>B íÛ„LàSœ£?Gåý9P´°¯KçÕþj[ ¶sG Sä^”y��šFé[œÑêµZ}b Pž77£��¦H[©­ð[èó1éûº’ÈùßW@F¡¨n0…Á�rD% äË$U‚d8l&YÁ‘pÌ\1 �WwšUv-:㮚SRk"Bƒ‚Bƒƒ�!ÁÁ!!`!!Àlᙚ~Ks�.J¶Ö¦Âšm©²£¨ßÖL2&²áÃ|‡Š½X©ë–M$eÎ Xï¡çù‰VòJÒ½o—^ƒ†ÊÑ2½+2|¥jI¶é ]k¯íd–Y@Éêü�.ó�d ˜½e�^ô§Êôž2j€µq^£‡-,¦Æµ³éÑØ¸Jšó~õé�ˆÄr•§†ïG‰�´{J™„'Áàù¯W „…‚AŒ GŸ:t£jP’¬A §V à�±Ï„E!À1ppÌ$cT’� H‚B¸ÐÚÛH%1 S£^\Û³KfáìÏ—]:i¥;b@íáüó[V,–>¨Z\±Ò�@éf››RB­ív¥ôé�Ù}#¸#מ- ¤6KìCrS,Ñ(ê,ög€«Ðpã›Õ¨M} ÃÒÃS¢¯iòØÉil°‰D�b[3ºº/ìçM›8F~ÕÒýW•z˜œ‰N»W;g'ÑŸžŽdÚä�Þ<ìf˜Æé[~µE!E,¶ó\žð•ÃXÀ|Œ6º`²-úNL¯sÏ—ìÛ?zõ^uíà §ÈC4"•€†7b+™…Ý9=Šº^ÏÎÇ›ó=ºÒ·êüÛÓæ!®Yæý9ÊÔÔç�ÎI¾Õž‘º�6Z6@B+åÑå¹}Î5 ÈÜFÆžu�ø2jý…A�…à þqÕÀbæÈIƒ€…•:¶dš�ª®Ù,´±´R)äÈs8d)�‚äpsd”„‚Ý1)—ÃØ£\>DµÉ�¬¼ìÖ6uK¶œç?.¬Œúø9«¯WÓáÀ�ªãq‘�ÌV�ü²mË£~R¶Ýµhö”¶´tÒµª] & ‡$AÚGPHÙ'¢ór+*œóÉ’\&oZ]—kz4D,ì'Ám°SöuéDÙ Ás&sS4´5•v�)騰ð�QÅ”£?jóûjó?Yçk‘‹ÐüŸ ›3ë¸sÖë,Ñ*�‡ Uáòú˜ÙzLhÒ†µ·Oš5–C¿aR0„H 8>mÕÂb¬Y¢²æA#$cFÖ\U`“` ÄÈøJ)¢‘Hsr)�‚�à€˜¤r…ƒ‚G‰—£�—xÈæ¹9  …äpZyzþ¯EYU¦‰Td¨ä×Ç2™ÓE»Lèhö^w£~{¿I§($¨¦RHD„ÉRé9²a wÏÍÜ9¯˜çKº„}c% v¥ÒGƒzÜ+c‰útÆ¥•“µ ¥Êj¤-ù¿N¨Ô]äÏoŸ>‹Çú›züus"ä¯+Þ³÷5ùãÙk7µ-HK)›ó<¾ç èò:ÐϰÅrù´5å’*'�ïØÒð….êã4��' C6¤9FLêÉ“‚Ææ¤ K*À¤86‹‚Cƒš àXÌR QÂ�[lD‡6^†^}ÈZÂ|×'#àààààápørŽŠÍcì:<j¹VI!òtóv!FbÓF�AËö|ÝŸ–ô·cpÎc$ $ÉDŒšr†�z\Ù²Y"¸¬Qä«”ÜKiç·ætÚ›5¹ß ãvá&Õ¦»7)ÐÔÄíHØpŸ&¯ZJFE£«J],$9ž£›-ÝÅ5`™ ®}>c›Üõ]^ ‹Ä‚@@�!Zk¯Ú5Ãà„ˆ888>kÓÂÆ„6’¢˜×cFÎRb�So'�LXÜ—2BÁHHäD׎EÁ! ¡�H-6Š�kcK/O::¤‘“‘@pø$\9O™Âô[yzzqp©”ñJèüÙ4-wÉ–à+†gEæúJR3`0�É"Ia#ƒ€©ó “‚Ö­Ç•‰UÇeL ‚°Þ†Êk¬ÒüƒÑÈhídŸ ì�MnèØ@ÑlrÅÒt5qœÕæTéÕßJôêêÓN‘ë9p½×BæÊ™„€Œ… *’µua! 3¥éÒÓŒB¤¼ª¿ZÓÀ( €”pþi×ÀÑp,‚F¢œNtèS,d¢»v‰à�PÞOŽš�à˜¤$$8$6 ‡ A!â¤:ceèäÇg#‡Á!Ã�ààáq\+ÕÍé·ò À�-Ø&Q!�ydæ*} ᤤ@B¸á•ú4ÉîÖa $æWIÀH–壂@��£Á�¬3Zd‡ ’š"I£mVEVh´Ø…´äÈBØ�еùãI¦îYe�¥É5q9¹LB®…-©Vý>w»*jMIŽBB@€€J%$:ѽLú´÷ó¡f²�û7<9 §óN¯=í@,h)âh–³¤¤Áp «ÈH48RÙ €ÁHpäR ƒ‚@Å#€D"ÕàcêPŽ‘N åR9ÞJWÅèW6ÎÞ]ÊÆE¢i e!aߟ]RÔªjÖ>¦¹ä\ûiЯLgk®G¡¬7²DäL¨g mÍ’Æ'Ò­ñFÎ8Õ«µœ’L¶á9µ](y¥)uÇq `¦q©”ÜÐ~ª²›¢™¢ þ4Y>G 40l¾à¶F¦@‚Fh–Hpù(ŽG"„TšÇz{<ÈAB‘ó>¾�ah‘‹�càÎ� '‚¹VI��XÚ. k‚ACp¤\1  Ac`¸r Á #1Br .¦}>oZ!ÁÃà�à�»Xú=¼“¬šO…RîÀ秞Ϯ…gQSlŸO|„:ÚÜB´¥#Šx½'¦ù¾’h „H¢œ„�¢$·ŠÑåÎÜFGvûœðƒ‡`FSÅM» ©ºƒ¢«¥È8LkHO™¬‹Iú ±€0É¡‰1Óúö S!È!ƒ R>%à‘ð@B*ÍcVž½£Cäø\1LCåý|O‰X4Ù¥¡ðcÎÝ(Ú4%·“Á `¸88l5!!pù"` ‰HHÖÆ B@FbäÈ`¹öaåé-SEÁ ¹Îæ¾s\è_)¹Zn'€‚£«‰åk�4ôʺ4z*ä�­ŠNÀ«iE"Su7Ò¶–¤çA’/@P@H™&ò[YÃâmAÕù�lСØI¢á˜TÄu@:­ØG�A|D�$ù+²ÊD8MX”IÄ"hx ¦£S!Àc`@¤$dˆ N¬¼:ÓÙ9„È$$bŸ ç|)±‚’*aVm9É‚Gd™ �¢�€›R.‡�†Ñ@p,m ‚ ÇŽŒ…¦…g¾ñ�¦t­=gqUf²»|Žyò¦8!@à+âRÛ‚Peß=«!‚-1¨LHYžôzty2Œ NjݾUqõ�9bÁ¨ä¥ŠÉÜ Ê�‘HrU‚L h Å–‚B�·2b€„Ôݤ¤ »�äNn¸>IAhv‰‰H$« ��1ˆ¤8|(@§Bk.¯Ú¹äp@ÚX�¨ù·_ ‹�lh««€1g­*çO©a+ÅÀ@±´\ÃŒÅ!Á€`¸|%�‚�àXÚ( ñÑÔäiV^޹Å8*ž}8xú[›y·ôåàäå£y•½"·Þ:Ž- ¤Òè NqZ�9ŒA)½ª·n‰¬©ôy¿S£C�;ܱÌÎìÖÇ4Ncvó�n…]oG[œñ±Ç…rí‘ÀÀªªá"2B­H�×nÚ\6 ™W‰$@UnÚD À‡À#J!HV+‘�0"€�‰‘ÊpÐ#‚Fo"¯Ø Â�€‘“¨@¥ó~¾ ‚±D' ˜”ͪ“¥,éŒc…”òH9¥¦ÁK|9HšàšO‡ @ÅÁ ¡´$\5ƒE!ÃI§œžŠö+/I\â9D+.üøêô»ùä… B�×4Á[âKô5–ÓÊÙ1îág«Ôq!Â�×NÃP�r¬9©vØJMUYÞ†º|8Fm}7ŸÝ¦¿—‹biijê½N\®g*À¸*¥Z&q+ ´L ÑY»B §ÔÖ¥&œfîŠQÀ¦ì%À¡¼6ˆ‘†XA@ÀÀ€ÆÄ@H,8.N”Ö-iì‰cRŽ É|߯„BÁä¬%„ LÚËÏdËkFåZ"C�e0’«7-j&š �‡…qØ„‰#p¤8jC1oVt“=ëç„pÀp®ç—3€Òæ-RG`ÚŒÐVO&éËÐ „AH»¤H@,ªã¶L'L»Ž 8(­8Ñ\¦SV•k �V*ÛjLu‡p™©WH�´!�]SÁ#®;$È0+ȉnÒ\9b®‚€€z$b NC€À‡Â˜JkjPCΗˆkìi1'€@#”|·¯’é hC‚²²j„j™&TˆÌ\ƒÆÑK!P�ŠZ�QLŠ@ÁK4�¢€ PÞ) cy"T!`…Œ�I°\8³�LZ`> ÑÇ`•„�¸GrÜ.F#p uGlžB˜)Jr)iJ %¬¨©âh¸U˸LƒÁT« KL ¥*Åš¢kîI´)•¼‚�õq°PU-@ØÒ"’˜aa`PʃD0š0‘%SÅ)ÍJÆB1pø965ápä7ÁÀ±¸P ÀXÜ.‰%0D  ™  v  ®SEÁT«ÄHHª—`™`'ÁX«d,i))Ùr´óV—ÕÙWa–\ÐxˆHUÁ, †á)U‡5Çpž Ö*ÊR# ®¬ @„ @ÑJd)†xr9ªÃ¸ˆ a„ŠQ Ê%œŽ‰C€ €XSOtdíªµ D¦ ‚ää>yÕÆbQUU_qÍÕ.Œ[ùí;ª³B+—Ç’L”$mM4­¡˜ˆ $œ Àé(n'†AXvEÀ”Å»dpp(|6UqIiÀášHiÄÈpÒ6“À,B¦Š‚¡W ¦6uBÚ´µ°:ã"xi F|J�µ¡ÎÚ-\eúKEgD°¦‚+&¤•O�,ÞU™x˜A5ÁU]�…:ÍÚ'‚Xj�m×2óPÜ(L$ž iÈ1ð„m „!€B3&òg]×V‹Încr†RùïO7©7´Æ–>—K;o&ÙÝ2mI˜ç< š{žaˆb0XjLó¹Û5ù¸Z4¥ ÷†,U�4Wï> b“�›\…�i³>¤ Ö�ÁÞ¡W�y5 ó¢ AÖb4¦ øvfž;,ZªRÝUï-j›ô«Ë@ÈL¥UÎ ÍUz³z4iR`”Û…E5§È&Ok²LÙ;ttÞæØyúÅä�-[ÞuÕA²@A`Ôh´e5LVl„QTÐà” ,Z»rÔÖ §X4Z¢ž$¾™†å—J$=©iR¦�9uS¬˜Á6’Ða¼ÕæhµxŠÌòùè´j…–¢§¦…«Ì ÏN¢u¶z9RCR¥É¢ò×f€­´Æ@™!�7Ò΢Í(MíR¡™Ô†­Í„ì4‹Ÿ35êjd<üÕÞ�K”…´Ü’à,³RåA^¢¥¢¢�Ö±dQ�Ìàôâ¶Â@¦mP£ÇE5ÃJ•f8TS£T!7³R]­sÅT�ÔhѪ6 �¯Öuòmp»TÑpT‚ŒÙÒÓ©Ì–!¤ÒÂÃBÂJoF»\ —†1–¶÷ê8Iˆ´×4±µc¸ÓÀΘg¹¥P—hšÁô´Ù™I6i1«�WBÕ1µ:T˜šÉFDÕáØ •5@BàY©Ï›z+ÔâEß zÌ™E?5—E»Å̼õ.@°U 3Ya«HÖ¸´L"ÜJkB¥¼fZéµê\ך}ÂÚòñ¦åæÁZazhB`iÒ±s奶kn¥`ÑÑLÔTÆ™ÕTiº\‚&­°j<¼Ö*zW6¥ú!Zg™M@h£5 (²ì”ºmk§Á´-D̯ŒVIm Ð`V ã€r†µm¥R‘“\‹ì'¡¦p̤èE,6†ç +ÌЩxSFT•Ñu^rÓGL’4¶ªË£6Ƶê^ždhŠÏN•ú’@ް88qVY¢Ö˜<BF‰d; , µ8YÞÍ%°ºÕ‹^s;¨�±Z…Ö, eàª�‘z:‰j@A³|žV[Ó¹V‘“/ÖŠÂwšæš×ŸMˆM¥Yæ–™–�K+;Ó…"¶¸`$MRÏMŠ�Ýs£p°�¡7^*Y- HÂäÕATMrýÍ0ÌOÓjÚÓ åñÈ™ºÄݺVAÚj-4­VuWaÞ¿­î .¸+Qr¹K–}e�úÖ0;š5¶WW]§\–=…,:)©TƒR‘µÛ®+}{¨±nk=éo-œ)vÌ=ÓnãòþßN'hËê î­¶½w\u=Mf`»½·œ5™†Í œŒÍøî{œM[2�Ï2Ò­[ §½.œZóUÚ«º³…3 W`7Mâ,S2f{g'89î%IëcÛÈÛf)6Lfb_™«EF§0Žâ3l›»‡Û?«¬Ýê·0{[¸­öª�¸‰kcsDfVîH6)[ ¾5‘¿$݉ԉh3rÍÝʇÒ7ˆÝ›Ì¾ôSc›!v §±C;ä˜!Ÿ&nãtMÚ}PyºyfÄ##Ä=ù>OŽü�xþ ú�&5l`%,d;º{‡O ;°â Ìú|¤¯9| ¨]ö¦šŸ¥�eâ(Û§ ¶‚Ãt)—Z”_È©e‘©`+ÓnE¡PV”ˆvX>’¸Š¨Î�P4ÀKP£é·Þs7í�fí²» LÀë+a7÷f\ïí»~ —Ö±õk¡˜u²�cšìW.ë:³©:Çí°ê ›õ.í]¹¶%wN³)ºëuûN¥µ˜&mqˆyy„öÎfåPŠ6�1»3XÌ,r§¹ñ¸uÝ3 °1Ãß‚Ó�Ö»ÁÚ ®dJœ0° çuwOè¬ ¬dËr`oStFØCâ'™Õ¼[}ÛØjbÙ:»· Lv©„'Ônq:›¡ð¯ ü^’¹×&Ѷ"ägÌ™²l–W) 3'w¨ÍœŽó=ÃâuÄÜ ·„¾3N¤%³ºwf)ù*\LKÜEóæDWlØÕ³ueìl%¹�D‹n Ùë #1— »¦«guo[2Ïu-ܧP±` ‘;ƒÔ`zƳx`²ÍF×Þ‹UYœ)ú�Ë—´K,YÔ˶@6í]è¾EÆ-�Š÷íÜbÄ és,#¦–‚éÕ�Ldcr§Ìrb#³ôœ9ÓYaàúwÓ¹lª¶'ÃÀœNü…QSv…¥—dz0·§nÐ@Ëv�ý˜ÝM†²-WôÌç–£@�-ŽûHSˆ–�ÀÑpÈçt[÷‡cUôÚ,B{£^Ð(ÎÞj³P°d›cíÅC3§“�“faOUžWÞ6¬f X°¨�Ðc'ÒúŠ çmv6è{Afacó=Fz„V…òA“";<ê™’X³D·lwgªÀïÌ[*ÄΦ¼ƒõ}þ¡L{Qƒê)©@[Së:•um�SZe6Cçh„A3ˆÍ È?Œl8Dß.ý‹Jƒ±J� xý†;TžœKeiˆþrĨ‰·$–Jé3¢wÁjÃÞxŒâ"ØB«`êˆ+^í¹Ä¬˜qdf³dS‚Þ«±ÎéÜ0/f6’KæX Ÿk�N Ô“©¥×–T²ÆKm`¶È£lõ_sjõ&;-{Ú­'~žÊ;Õ•›ŽºÌØ#j©²%ö.yÖ|­¯’îóöw5Œí™Äø°šÕ-(¢ÝÍ«öĨu• ž 'i•7«GÄj]&ªÎ­»ÄK”/YgPgyf8‹�¤úP2!ŽH5™àí'—iR²@±Ahk0öÀb[.ã$NæÃ\"±›Žì–�LÔD¯°®!|÷ޤ©6Ö+0#@¹lm— cæ{¦;bì3šzj®þ¦»dWQ×-+©:ëôÎͨ¤V«£&}@´Ó-®´\�¤Ö³¼º¢òº†ÚéA´ j\t” ‘Ð=¬Î”Ùéî#WºtpÓi0 R»@Ýêé“ m€˜„À�–fc+`Ý©WÚ¦ö[WWZÏ«}dúµxޏîÇ�í6Åñ�–ÈŒ0؇´òS;k]Ïâjíé暑7n¨¨aF6Z|ù�ñØ FPCf¹Ot$à�BmZû€1œ‰Y‰Ÿ�.Ú)k„Ý깉˜ 4Ì«dNîŒAXYÔº*ft±;ˆbö.AŠJôÆñé ÖeN`lÌÍØ›áh ,L[1 çqº^o8ÜÓq›Î=Xïø7ÌãÓ¹°3ÅIÒ&5X_{(�™_«P¡·lwÊÌ ¶ 4«3¨Y™Ý�…FÁêâ7®d@ýŸÕ:j&¨�^تfØÃvŸ>aîpÛ£‚·×–_ŽÐâzpl;†2O¥jUÅ¡JÖ¡­ÄeìRgÕcâ5€pèÖT‘õ}œÙiZ3L°i©ÅšD«Tj³z3¶äÓYÓ½lª¡iÀ|s»îW\Ç=Ó±í›ÂƼböêØØ®ÀU¨míyi]½‹�ªÝ³‚ÙÎZo$÷bXé½ë^Øh=G¦1ØBc¼{zj/Èmm �EŽmÜÆ¶ i;«³Ø¬2}ÕÙÙ¢fGI¥ RøiËbï…& Ο{ô® e-(F µß7=€Wí†fo›¦ðõ€˜ï„L˜¶F=ôÇ)�7*׈ ÛJ+ ŒN÷êmÄo\¯5�ä5 [q–Q=Ñ�gÔƒtQ‰ójîZoU…‘¬î½¦£XµÊõD‘i3wå*3�!|G»nÜQÔÆm±lÈ0žÖÑ. :ªgT•Ïl&p 1¥0m²®,;·¼rù²Ç­·»Ê+6K¶T�¨&%/aµE£¹Þõˆë]µŠñ­ÀeÃ�?g­A •Ü-c^ѧ¨e®Ú®ÍdÓŒÃP"ÂÏ«ªÙ¶ÅTú®ëcÔÄ:‚'\äj0WV u@^®b¼ê`ºŒIbÑ�„W|õبôõXËîèW^¬Z[X¹êYk²)‹Z�£†K(3O„K?] Þü¡™ ù™‚ÎÀ´bÖJ=!ì;Ïvï“iÜ[p.J¢’m³k×,e,v+l­˜µ–›²;‘¸q2  S!ÐÌ÷Û‰¹fäÁµ`¸žÅ–Yr,:…�|%lIZÉž¥!ˆ�‹¿ —ž ×‡Åj±ÁÅk,Úæ›È˜íŒEÝ;ï¦èÖvgIJ¶wF*Ò­}ŒEL™ÊÓ7bzZ,+3ÔLo €¾ºð!"+×´°xɸÏXnµyúªÌ:ŠºŠé:ÕdØ›�ÁE]«³P ‡%-²á)±žf;Œý@û¡µDêÚÅ܉oLoï[f½»N£Õeªij;½0Ù•VeÖÚ�E¿UƒRþ7¥íö©öµörÍ3ËûtŽÀ¸�LøÎbD¬š³±÷7ÉÌLÃ¼1»>¤-’꺩¤colŠÓw|™ß:|bͦŠÎÑXÝ(LP#fytÌþÊXJÛzíÄé6˜Fbà¡A=jÛÔÅ�&�¤@²©y iìÚè–[±§u<ÃR©¸ôì?�Wé­—tI·+S wÏ©ûÀeg"¶Å›…mòÖ¨-c#vhµæ2w+6�3N€­á‚iýH¢vÆ3ÈóŒ�Á_Qæ&ˤ¶YU»õ;Ä\�Lò?¿•¬bmî‹ê+;ÅIgf_*¸7m›rtúq/¬n¬˜©Ùq›Ð{�*Œq.²#í-fáNqbÄL•Óâ(f­×Òé��@ŒÈàêßxÑ ›X)êRëÖÔë\Í=YWUª”õ³¦Èb÷{*mÖ!Y™Ý¥UAQÛ°K„®ãÅ93–¾Ý)Ó�%ÇDK¬\©qÔÔÕ1úuH·°l�£nÙfD«l©Ã’Ø«;朶3Úyjì„ï€v¯²¼Ûè§À–FF&;•kÌF"u VJ[Óý�e.;¨Œ¦o1m\-‰›HVfBX)‹3ÙNåõ3 Ú1v+†îbVLÛ°u0Î¥Ñjl5D°^Ê2•SÇô®àEý§¼ ²¶Ý*\öœEì†òñ.³j NWÔºŒJåˆÊÐj~E¢ÕØýÌì&!žÁ<öŠÝðLBÐ�ñ;˜||S¸8yÜ•©’YYÜÕB Ln/XË‘Š)\[V@§Ó¦@,Q¸ê5VìÅb!f¼U¤êNt5à\æ1ôØ úÖÌ˭ވ°l,uz«l¸ª†²m ,¶+zè}µ\z­xÚ ­•V»§TJÈÞæ»{uæsã…ba~ûác:²õê#&bi›?J¤µn;­§r×IJ訪j­u:­zJ­®¡ãpå‘70ŒlÂÄec¦î}+úóµ+rÓ¨ŸºÖr³©ŠŸ2…kTÔ£ÆôµgÔØŒwFM²³Û1¼ ON[$N£ˬGo\DË*À;t”…È�\CÜU^ôèX [sêÔkjD;n f†¨NèÅvƒ²iìÝ`X Ïψe¾ªú?ÆÃÐØFv…²@ ªØ,øƒF”÷€d®1€ ²îÊÜ&üŽñA³2vfئ °Îã 1ì;²Ìø1½3O¦ëKÃÒ/N‘ä{q:áO[©5Ñ]G%ª-6––ɇ} ¿ÔKãëRYlA¾ÕÛÇmC T€v«¤ˆ2Øíƒ^ßy'«‰ÚÀÛ•´øµ…d ¤ºVpø‹áÂ` ¡¬¸­›$zm:o:Ož•Ùú{²)º.ƒOnñ¦ZÙ餺S]’Ò ›´Zqc(ìHXÁY”lQvõÈ&ÌíDDµY—¾ô¨*íƒ1˜ÒÐzabBwU9pKca ±V5ŠÒšYÃ%‹»?vÚ!XÒŠö*‹ê æœ2ÖæwSa™ÜÈ ªÂ а+žöU-Æ` $XvW¢_EkÚsÚ¼uó»´»@оÚóܯ{; wªVØV·lë·Íù˜;SÀB¾¯iÜ'‰†Â®!©÷%M¹«1Pç¤fŠ;¶Ñ bnX©ÚðÀ»„« tÙ·éì‡GkÍ6™«&’ÒÅ ëÜl§u�I‚Рߧ2µªõ«FTý(Âi é}iNEÄéœÛ¦Þ55ô]u5jév•˜}ˆŸC~>ŽÌ��>ŽÐ�÷#á}‘]Ù@ŠªQËbÍ8ª¦¥«›PÌ eHâºFÕ�¹~cÏÙ¯¸Ö¬æÀÝæ–ΙGk-¸(^œæ^aî~˜'+JÙ`E Ø6 ¦÷#w¼ö[7M€A¹l,I^êV:.Up íz W`µØ'ÓÛ¸iÁ]>�}€©Tè–'H'шԸ5Öw‘eLÅí M°¨0Ø„öudí§7[‘åÚ‡gØ^ XÎ��U¥ª¯bâÛ¾ÄC–[‹XYk°Î�’ÒÔÊɼ­m‹le†Æ0÷�0cÙµ LˆÍ™»të0†ça¸ÍÆiU¢g!J„Ì=Ó´È™ÄÔëKmg!ˆ<;W™u‹.c}ºJuø™ŸÔKÛe6Üö6™j-]šZáâ oÌ;î}™«›y§šÏ§â ÆP&޽´v—ÔN«·÷ƒ½VIó�³ä6%:‚%vŸìùæ<ýš“êovf�1M—Îp–?‘¬Û+O¨b€ÂN:sh‚¤Î˜~:—+mR�ù™!ñêŠ3€‘7rZÀ‰Úv‰Û–f&OÍJæ0ÁA¯+.>žúŽa&&ëï_H¢·©Ø)kÄÒä¢dW¨mµèFoeŒ²äõì�fÞÛ`Y¶bÛ„gÌ2Ë»ÔÁ™„{U!½šdÅæÓtQ*°7ØÌê ïx�¡=ŒÌã´ÄİìF9?fyŸÇ‘ãžÝÇL§x½º�RÖ5–°æiS©~�EUuq"…Ô ¦ikí´LLFöã‘‚JfèÓõ:´¢}}ÌûZ ÍOcDÐé¥D�Qgyÿ;ÆkÓŽÔ,þ¼@ú0f'�È °Í�»i€B ÉO~°<É™™™Š{äÌ™“2eÈï>™ÉféÚ}6ÓªÔæhI¬ô&•6T|1ÛåV.� ©vµOº�iü|8þSKG«ø‚ ˆv´ØÓcB¤/ªz£îTÉwNãK¡-N‹6ÌzöÌLCìa•Óã}h1°B«ÕÖûÕ2�+2סcKZ@ª9ù11 ƒ-Ó«)Ñ�i¯o3ç˜óË30˜9ÞØ-…(™–±¼ öS‚_²àÅî²SÚi%íÞšvÝ%Þï0÷™›¦bœžyƒŸxgyÞkkÉ gI°Tͦbb`ͳlÙ6@…DªãY®åy¿òØä°ÜÐiî3én†«DË(ÞLÜgQ µ³õ Õ´]n ×,¤�Ó$¡Œ3’aÒÆÓ°b×Ì­ š´á`Y�ÈN%ú€³Sª-<¬ÓišÓU!/©=º[18†˜j)¾£[¿Šu—U‹4^!pµX=¦ffb´Ý3QBÉb`@â-³H¾x]{ìÄþœÏ´ûtçýŠÇhn³÷V�l«DÚ¿³ûó>ß°û¹¯˜Æf…à<ŒÔŒŽ'‡½öU@Ålø„ú+3¼4­Î-±ËTÇ©¢ÚF³Ü§-]ïåñÍ~Õûõ‡òpΓ™Ð²}=“鬟Kdú['ÒÛ>šÉôÖæ¶}-¦}¦Q¤5Ï<0‰žfÐϦ¤Ã¡¤Æáê!á͆á–á N#öl‘Î"êŒMX•ê ‚ø½7…TÕ~œÉ}ÔiËÅ@£Ç+,×Þq¨¼¹ˆ2º]b&9/º¿l¢ÌŽ/¢ê­£K§mC_¡jÒp·Ý¡<­¶ºBëôìËˉêz“ Ôtжè38»Áçƒç ³¿éÌûHžÍUpˆÙêU£,È¡DaéÄÇ?ïÌû~ÏïÌLöf–Y  S:‚-€Ë»ŽÙZÑ5 ìªe¸cÄ[¶ÜLA�C6õEIfÇÖŸE<œ÷¸ú‡#í9”WPY‰ˆ¾jör¦ÍëÆtXn Fï­ÒšE©4Oòz}ºŽ*HvgeóÂìßTâ�»VªX¶�Âi—QL³_°j-kÝ/ê٦ä'ý9ÿVñ©Ü¶RwUÍÛf%—×\»ŠUµ¸¹Ÿåž/ÌA"븼GØ>ÏïÌKOg8çyÞw ßç}¾Ê�•ä±nùɪ³€'‰©¯¸�æ" B«î};©†jG¡lɾ>ÁãîQ ïÕXm« ¦á½á²ÈÖ> ¢uëŸSLúº§Ö Ÿ_½¡×[Ud79…‰å—·3ã™ð9Ÿs i¡ÒR£‹iS§[5VWoVÚíeÓ2Ù¦�VÙ·W®--l‰¥Ñ5’ª–µ>É™‘ŒÕúù†[¦»Lú[´:´Õ6ª”e^´¦�H²Ý•Åúf¥±8AÅÛ„×wÕpê²ÛTÆí.Q³YZ ôþZ›æùŸVsÏàøÕm5ðæÎ—¼ß©× &£‰Yd/º|&&žÆŸEtj]aí¬±5®²�Xx¯ø×¸ïˬLs°åœ÷ ™jí'Çô”Œ½½—D=h}Y&Ì4¯ÇÄa�‚›b¡ÏEç¤Ë2§~õ=啪?h&{L‰‘2"žÙ"dsÌÏmCwíZ�jCªÌmJÆÕ´mEƱ  ž�³é®ŸKtúK§ÒÜgÒ_>ŽùôwÃ¥º}-Ðéí�+%m¨Dú�HŸYpƒˆY&’Ÿä„^ †&¥^)b=sL< Ŷ¼ØÓcB‡Jh�ÙÆ‰]>àN‚õtG�wE¨JSl×W,>¢}:M¦åEÇMaE ÓYÓIÓXb¨˜Ú&ѦÛo«[Uš{tZæÝÔ¬Ö-ª`Ä(éÈ*ü'ùS_üÍÆšfjýVjI{t•tê£ôóþÓ7´�mî®Þs¦Æ³PVXåÚªšÃO ŸKZTb*�Ú5hÒþU‡UÂìHõ•> ¶Q]ÙT³0_ß™8RgÍ+ÛX¾˜âšo7øÓÂ?eÝ­ÓŒ±geo!!í ìb±&–-4>´±v›}Ð(›Fh˜äƒ·?žF1ÿcŠ\Í~bUcÄÑZbðáCP‹§©fÐØP¯4£µò‘� ÷ßût§ž¥—f�2p/u\ ;*­÷êAóÜAÚ>À~Ïž_v¿[ü™¡‡–9|sióÌùæ|sWÇ4÷so|ÒûÿôGñ§ž=÷äò`khèòá·tî,ös9˜d­±8¦�ª˜+4Z�àJÜ¡âø:�lÖüXwÝÃ.±,7ƒ5º¡]LÆÆÑUÓ«âŸÕÏþ‚V{âki�0g¢Ëµ[4:n³V�G'öýŸÚWn%•‹ˆè6ìh¹ªzÝlJšÛÏYìùÓ/yhÍ ¯4£Ñ|¬¡Wv×'«EÈLb[nÕjÊX{2÷ŠfN4Á‚^=ù��ãšxçóËãWÚÍoò&ƒôügŸÇ1öŸ<ÏÙñÌy'nCßÈÃîšoÙÿ£ö¤áߣŸÏ=Mbŵ 8=ôõj·ÙÈa‰ÈDzù)Èâº]…IS¤¿¨³‰'¤ûÏo§YÇäo:»Û ¯©jÃŒUúùÿЙ˜þÀDÓØ'Òá묻éÑRd ‘2#ŸNá7¬Ü&DÈݸLʭĽ•ñS²i,èº>&üØn›ŒÕ˜1�7³30ŒYß§)í^¡»R3 «ÝÄðh[ò#¸QsÉX¯K¬Õ¶¡ULiØ¢öŸ5ç}�™g�y7„öó_³ûr5³_ûçý?³>32&fDÈ›„Ý7 ™žY„ÍÓp›„ÝÛp›ÄÜ&îá»n›æè§×¾0´.s“4ÌzŸú’£¾�Ó§}UiIþDO®Á«R¶L´ËÆ/�}†ÐÛѹÉ5þIù&”Î(ŒiÒ^Åððƒ2ÎÒ›EÓk@K“«N®ž…´ÛÓz_zÙ_Q.-ÌhkÅ:Ë:Uym+Ø'LJ×)ÓYÓY±fÑÔ &Á Ê6í úJ�&²³—<ßÙ‰ŽÛ�VvÔÕ½x†˜ÔóEfú¿*žzß++^F–:£ày“Q4ÿÀ«ö\�Jtèët¶à“qgØKWf×ÂmÑWº–HS½¾“ˆ½êÛ�5§,p³lAèÛ6ÌE牎ü„ÖN¸á÷NÞ¯Žc–9ãìùäaû>>Åöæ`ý™™™†fPß“ÿAÞÄ÷~ΓØÝÕ´–ïª7½€#UWJßAwSL&'ˆQ5jÔjtö jåôáë¶·áúÊØ:ÍÛW‰é…ô¸ÚÚMGLÔû¦³KÔs¦´.ŒävÛz�éêZ£¶9Uìé61Ëþ�OíåKmn5¦êUÂïÝ#“ „¨¯Õ%x’“]�À÷óo¾åâ:}ébì~ûoOÚ�r×y«Ü9Ÿ1äbÕjM6¨�>�zÇ~Z�@X‡t®˜ªáè %™©ª,XÍíÀ1Od{¨æžÞkö|òu~Í.ú~9ˆ>ÃçŸÏ3ãŸÇؾ9ÿnmÈN&7ÅÐ9Uá‚/¨ÑÐ ¦±8xã4ôuœ;õf[}hÖqQ¨7rӾƥï$8ªŒµãÐ�™{Ž_7+†\34À/ÑåÌÔݶlß( !30ÞvÓuµÚ!«;UI$½Ä§ÛV~šæ‹ÈDöóóùç©�wëœ/õ|sGŽgÏ?íÌøçñËLó>yŸMyõmüCÇ,MíÿÒ~ä¾ÄV±Úg:kv”ýeu¦¾úÚ«–äJÛÇÒš.ÐÝÖ¦zmÛ8ž�®ºKº‰gëÚÖÊõôî_:vͱ˜*ÚåÛ‡Ó¹Ö,0Í þ=mùqâ×�žÎzs‡ÿÐSêá6öåHÅ|ví×HpôØ9·¶P{qzwTGz}ZZºèºûgù`âO‰ÁÄÒ}uF.¢³7¬Ü&FyürÕ•k÷(M뎢N¢AbJlT~;¨K¯˜ŸÓ%Ó‡pª•6ÖŠ»â:da¤=+wÊíØu®«MAm¨[ý[åN!Q¦ÑoR“fÕÕq.Ä’Pz«R–dÍ}ùŠ µô©Üf÷›ÞeÌk:].÷|¼ËÏ_S×ùÞLï=SÕ+܊׻K£mº„ÝŽðv§]fëÓ.ÿH:lJ¶�ËÀ&&!ì²¶ÃjÓ}Z�ËnŒïÒQàø¿N22ò]í(Ó�øN?Ùa5ÊwV3ø�G}>‰Õn>¼(š%+UÛŽ«©‚u ^fX”¼Äü‡k´ú�3&w‹ºz§®wŸ=çyÞc¿7öع§Ó8gë±1„F\�¡ª b}: ÑYÒYÒYÓQ4j:œ~¥W&°yé¾i™˜çÔ‰ÕiÖh/;WYˆ¼Abkj3ªŒ£ƒu5lÅœú�=qø�b[Ä.bº{Þ'¸Äá¢}IJ&Ø€·õÒå zÓS_OT§²û´öm~óõNì`ò|ó>~ÊNÛ?ô.1áˆΊNšÎ’NеõªÙU]F:7Êœ6?é¡ [Yáâ>�¡ÓÛZ‹m®WÄêÔê5Ý;·PóéõWJødM++­UÇ6ò!åoé‡ôñ%ï_p=Ð8zÉ:=h`üѶ·Ó®¦‡R�¥ÙÔUF÷êîë[EfË)AZ?·�î4úm6ÝÏþÐr#¶9§vâo³KHÍÕx—ÿ߆q1‹ø[m¹|ro-?·Ž&5:#·Q§‹øû?±±7Ô#j’j5Ê58¡5 …¹`à hcѳ;¾|Ç ~Á+ì�âÕy�³û}æZ‡«¨¿„˜>Ážl{›C¨¨C¬¤F×Õ†âBjõ'PÐxቶ¾uŸÃÅ;_¥l_îkS5”¨¦^ü~V�GIeº*ì-+¥ÍR4¥GOšþÎdA+?P”û¸§êÒÙº±ïåÅtýJøeÿevmcC¹g¿r‰Ä¯Ùá”mA,ƒ• –ãWî~^Í??ûsoo=2Oý¢pÚ÷ZœŸ¾žñ‹8éœ\z´ý„ñɽ¼´ç¿þ„w ãSG…åñÎÖÛ[XÌÓliedÊtëÐ]&'E–L™œ¯$È*aðHÛ�¼{Aá¿]¾˜û?¿3öÿÉâ)³YÃ[n LÆÔT±µÔx•b[ĽMÄl�­¸ÆÔZÑ��-§—ô˜<«4&Ôä&—½�л\Mó|ê@Þ¼ÌÌÂffy/Îí~�uèo©˜jáªæŸOdúkgÒ[’ço¡yôkž¡R"ãi•ëúJçÓ׳ “T¡iš$Üã3¼õAºhXÎ;^jí4§5wϪj{Oë ¡µ¦Öެ 64ØÐ!Íhvì›&Èk!¶´Ù6B11 c=!-¬l®+EÄ;iËaªÔVEüB;³™ý4–í±kB:I"ªÂ©¨§SCQp¼Ù¡ÓªUÓIµc¯m‚UX-ƬíÃ(¨íÛŸ÷çg²UPšî%^œ]mš‹4?ZŒs«ÛÆn«‡>N*}:/ä×ã31�§•þ>}4wº±ØA>NÆáÏ瑚¯)úÄ_o-œ‡š}6ürÆ^8È^ë/¬˜£rîgÝÏãìoZa â ÅêÓ²tZ’›ì@s˜•»ÄйŸB!М¹Ø“úÎ"Þ™ÃS�³NpxŠu4Æpöü2Îé?§þ²„�Å*ø£�C9üæ|Wú̳ÙÏûs>yŸÇ&•®QD¥×Šåº‡³’TÖµ:DX;BÀC¨\ê5�0úö$kšQª[VqÍÊ2hM”s<{éÕ.Ëøsz¿´øowõá‡4K x¾7΢¬úºA:êVYÄ—'ˆ¼m}íêuý.¦®cÙ4ˊijõ¯µf«øÖûÊ—4hI•iÑÙª¯©S®Ç¢ÃU”Ø,­ý‹íå¨Ñ­ÆšÅdLã•� ·¿§OhbNfa0†Û™™™ñ4·tn¬†X?g!Çõé9ð•Πsoo*½¼jÍÚŽFÄj�çŸj%V‹gn™­6|ò3Uå=¿aí «»jïÚ)°X“x±{,aƒ—Ï3ç™ñÌLà.©ùj/Ù ,f–ƒi •úµIn¸fÍU®;±£ImÏ ²´Ñ© /;­Ñ.ëÿ§Ø¾4Ç+ƫ٫ќ\=ÙÄS/»úðËÖ°Úʳ^“ëI�¬µ§VÆ›,hš+ŒúbºšÊi+¯ÃpÔ¬Öpʵ+uMM†ýúI¥?†?°{\3¦»ßû¨æó‰SË…_†obû`ƒÇ÷ù�*í5ÚŽ¶£95èëÚš¶�ðèxi� ³oøÆŸã'øØxx «Òt†gÕ`Áû9 gµ†á­Ñ=Oµ¢Sc�”ÒvÌr>9MZ ÖêôG WY^-Û16ÊË#RâĘïÈ™©îÉííh&Á.§ri‘rbgê7vÔß¶º¬V\ÇÎщ‘7Ý‘2&D,&á7 ‘ fyÃr×Cu³/·b¶IÁ”×½Ój«4×k mîiÓ=†­ k*Í/fÖß²º;µ‡Aœ10Iôæfn›¦é¦³×ÇÓ2¿K¡�fµ·±1+­¬dÐà *¬÷_~ö�öΧpæe£nÜå÷V÷$ÔÒœF‹kjšh÷}?䇩„êmç«¥¨ýšÃ�Ó×?$mñвê*éX�µ´×µ¨çU„§-=Si6€aRfÓ6™Åmú})š ÷ܫݧdÛ6ÌwÛ11zYrººÞ§ê4áú±` 7l`›D~Ë´F­X6‚¢kÑÖ³bïL ˆ|b|ëìééô€½©ÙÆ5©šàçU†¶­ƒ«Jµ"Ë#K½ãÇ<òn_ÊC ãP|\6¯ ¨tØK=£M¢{[lY�6�09f`ñí¹g>f†½µgˆêÌÉ3G¤€s£Ï³óh¿Nµ¶Ñ4)²Ÿ�±|!Ãñ„ߢšc¹'AbêéZ¹"–::1ýŽI™…¥‚|˜Þ|ýV¿é¥;Ži…ºyÃ�ú±ûÝ_²׫í~—÷¬ŸÝ8…=Dœ6î�Õ eÛ1 mˆ',E/Õ}F£3AWN‘æ¿o=àØZWɽ¿Š…‰jÝNÓÃõktßÛö|óo‘™Æ.Ý4•íU÷�c÷_ŸŽzKv9ïLË`�-ýŸûîäy&;¼·ÚÞºôþ•i¨È‹Ïç™û�°xšÇí>Pnp05–mK[qáÔonG•Sˆ6u?ãñõP»íA�ñö'‰xêiÎ�½<¾5/Ôyéì%ÖasÉHí2�ÅçýÉöS)Ã&®®†§…ÿëFôDý|DcUIÅÉÜc•žaúznžî©êT9¯¿’ ·ÖC44õn|×íÌÌÌ>äR{ÞÑËY¦ê+©F UøLò>ß³ç›xÆöÕ\(¦�o¹F"ûªýDvoÆ&9èìÞ¼š[û><.{ý�1•ð›ã7sâµWé¤ÍG`9üó>9Ÿo<Åñ5-›!ó¤þAšöÊÍ2téåñÙ©;®ÒÿRÛîቺÑ>>ÅåOzµk³Q¡lYËTû(ø­wºz=®öˆe~~VT�K¥¥¥ut»wò}•{³‰ÆÇû\¿ EöÕì•þ¾.1ªW°rn|NåÀóM­Shì6Ð9ë‚_aª‡bܸ}Ahgºøç�^Ù¶b0ô؈f¯J-!­ÄÐñ²·WÚa²'Èæ}P•¥5W6®ê+³æ±„Ô>Ä㑟WÙt&XLcùO�ÜÌs1¥6 [®\QfS1n6j3Ø6"ø– uñòþÜÏŽmíç¬lÝAÍVœ#œ´>tǹí«ï§Ó�×µ»iß»gfŽp´Å_fDÈŠDÈšfŒ.Ým'Ø‘8ƒä|påü­hoIJ܎ ›âÙ:™žÜ3nî5ª6]ÞpíNcºÎ¢ì®ÅÖ)^1†œ)‚‡±vo­ÆÃfe-šø×{ŒÓ>j Âù=I¬Õtë9%WÕF�ºèI®µi¸Ì�ÛŒÜÓX­fžîF™«ÄÑÞtå,Þ¿+ï7BÇ~ó7™¸ÆoH&dÎój4ýiv˜Õ=2�KRkâA‚Ø^z§ª=Ө˙…ˆš­zÕ4ÜM¿XuOE[LÌA–ºîšÙsXyn›¡h ' C+Ö¦±ˆ³½¢ ?gxNÀQ0²Ä² ‚¹Zéb?t {ì…&&&&2â&#/`&&ÑL¬êÝOdÌÌ>Cw8)èÒÿ#`M¢b`MG£Ežú“�0É:zÂ×�Èx˜˜ŠÚ&œ³ÿ@˜a)9®k›7Î6ÐÝÃìI•™îf"‰¥üZ+ܵ’‹6Yœ€} ïí?^žCR¯àJý’�oXÓ‡Ò90–¸­/´ÝdáÚn«éÆ*ŠsþÐrÓÙéãœ?¦ÓG©45DX€yŸ7ösÌþÌ N�1�¡o k¤¯ˆX±8˜Ÿä*`uÕæÍurÝm�æS[Y4ÚqXä"ŒMSïµy|}�ç@}.¡§L,³Ózø0bffrÏuø¬÷_ü…¨’/ˆ9|sø9�Ãéä|Í;n¡†e'm£íâ]¸pó¬>½oÔ/!å|s^H}|u7ifˆæ©yÍ¿�ºu^ØÙÚc38j‰ÇL(Lªmœ0 Ï©¤t>4ͺ�èžçð!û„«õÍ<ãcð´áméÀyĵÞi©7[EB´¬z9�3<�ŠØ\œ_@t¶Í¬ÑeD:ÈÃïc“ûG>#{S_×^­þJéþBã÷²Yã¬0Äï¦Óµ¦ªUŽiîh|òøût'òÆ–̼‡#íD"ÀxÄøDöÃörøû�³YÌùš— ¶êeºwêSËâqžÚ*ýö�Öp¤õCÈñÍ|Á5ËÔчÃ{„=…cz÷Ýi\RV:®ä켫â‡7D3{ £ M«ý»¿´rÿ óOêšÅ¡·-ÇmZâFöžðr?gõ‰¿˜ñÉlV3Yã‘ó4­¶ÝJäk—)Âíçýg?ë§c8jí§�ò¾9-��HÏ%õQpÚúFÛk{O•÷ZØ)`'t,&œ,µÖ!©ì™Åò44z¦¨bÎüfŸígŽKËOúe>þ ¹®É¡8Ô �®îµ“…és$a=œ“mk¸»µÔÞ·×™‘ ôÊßcq*ktöi¬®Î“Ãn²ƒÔdL�Û„Ü&áåfà&õ„ƒ5)²à7M: K(¢ÈtT²�ž�¦�®ŒI´—ñm=a±»M·¦q´�¦ÀˆØ-²Ä¶­��;NÐv�§iÚiqÖ>=KgfÔˆfcA1“ M1FÔTztÑ:RÁ¶ÊtÛf¦¢Ë£Òíixm€>?$HwO\ü�n�»<Îb{eƒ)QÛoΨz`‡�ìs¾¶XwQu Õ¯bW= ï(M©ˆ0‘á÷ÈJWYÊ®&Ù²iǧ‰×³T½˜Ù^Ãå|Ú!Q •s6+Q6,ZÆÞ5ÚŽ;bkÆ/ákºž��%–T»EJ!EÇE!¥eU!¯¥\ª¤ª© Ôz,©¿%`c‰Zg¶Š“}©R(¸ZÖ".Þ’M- ž;®-c1š-GNЈFÄ…T.Õ›DÓ¾ÉÅôU$©Üg Õ÷í?é‘Íý°°êªjé3R‰t=Ž�öÜ©¶g5âc–&�±ãŸ©æ„þóŸ±|RØ6Ö,Kk5·Ý¢–8€·ˆb÷$CÚ|p•(35)º1*IqAæßað>ÅöòútêM@Í"z7š…̾¾²èoèX'ų�Í(´G8 Øg4 °ú˜ íËMîãÉ‹¹ˆé¸-X„C�ÔúX˜©èÆÕÞ;úxo²qßÂ?O+=¿e¦/�G·‰ º¡К{»Ö¥ÎŽ�MxçYô(É×Þ4ºWmÆ­9z§ÔoI·m|ôöfqž�ˇjº©ýù¿·W¬Z¥º‡°òWení0Õa”#£}š~ÇŽ�õZpÓø ¶êê–qD¸¥±x¥Ò®(%Zº­”¾WQWUJòf�{]¨ZÙ\:ÿúþZGÀ†rf{�ta„Ê}°€f9ŸÏ�ö'·˜–Œ«y‡š�¦·êÇ]�ª§xÑj¶OŠ¿gmÚ¹Ã×-<žKŒöbž ÷r«³ñäÍ8&m3i�àÕÞ†Ûµ«ôhk+6âm‹ú½Ê£ÑÆ;é8aí8‡ïàÿ«•žÙU;ÖÚŠš?O+WìÇ´µS†Ñ€9c3â¿×¦øî§©u›m×SÓ²‹MVS`¶¶ñÌy¡…Ôñ� Ó[*s[émÌ �ˈê:hI'–&ßG±,rO¿þeS‹ èOž³]™Ø(´ÃE« œ÷‡ëž·¦Àã]Fáö4&ʵZvg©6V§ýÑ Ç/žF9ô¦b\½öV§rÊ=UF€ó>9Ÿì_o1 ¸aüöVåO\Q€üR”iµmPúÚÙlbí8bþ«–;Û¿·/ž$½M/ ÷tÆZ¡,¬2 ÖTŠ–9üIë]™F¬Fô§õ¬zx�«†ðÓëšÓ›¸Gè®öM1ÍZ¦õ|Ñúùy£�/ª §¯©mchû(;«ÖZ4º;»ðʰ¿ÛWWV¶[„jv;{y‰AÚ¶Öšª5ÚVÓ]4wô,S¸ME�*ì°ØÒºÙÍ0˜8u` ÓÅ*è“(M=½J¾ÄšÑ»@Gqc-[}\?‚n ^ŸOÖ0’gIjxz[/Ó½ONºÊÆ—R5jè*Ø3`Í%[ìäÂUüß°Âa†WÜx v-«�A/4¶6ÛYÙx1Ý[ä9Ý:˜�H,†ÎÛšnh¦ã�œs\ã¼ï;Îó¼ÕW1Ï@½Üw×;¸?fˆmÓŒÎó-=Pfz§ªz Ý»Õ=sÕ=ôÑšõŸ–~XwíX‘Kt4§7 ;²bÙù¢ & £Ñ¶ÛûâÖÞÜ/GòÏË-êlüÓCž—$\æ Ý=¯64 O_ÇÚvœ:³8õL<ÃÀ:$bxö§}Õ ïZí^û§«k+€tw›¨ÃL4Ã@­+š˜¡×醦›Yªsg~ªÜ{Î#©=N©a§6ZÚz ­ ­gN¥†’’¬"h°i 6M³Ã:G±³¹¦•m²î­»2g~Y3&:ïÚ�gMªz�[.¯SOLÁÜéê›DÚ#+þd<ŒøÇ" U˜X½Þ:îA€ šn�n{—ö Âr·ÛÌûGŽkã–¡öW¦·©ËX½¾îúŸ¸u—i£#/%îjíXñÍ~ÁîçIõëץĺÇñʎ꾎%W³–byâYFêì5ÿ^úy]úæ�ÇoÌ<Ñú¡=ôÓ‹Ç*]璘b¿Ø"¿Óðû\Ùg ¯u‚y}bÊìC[è.éZy‰W²RøœoCÔVð¬U©Õ‡Ó;neï8}4š‚ ­Ó³6žÞ–«ìX½è³ÝR}5 M'Çݨ¨[]•šßƒ]•ÖŸLÑU–ñT­dgÝ®æ``<±†=¢Ï†•ðøSÛ•žß±|s_µ º­3m¾^2Ÿ'ÏÙ¥·§a—¬#³ 3X¶˜n¹`ñÈEäyw:Î5v¹¥mÔË=¼´ó[èâU~®uûµ´õk`Q 56iù[úæŽqOæ,§õòÓŸW¯y3…Ó˜±Ï?Fæã×íªh*ÙDþâÄèÌ_o Ôõ+ä<ÓúùVÛ׌ézÐ1h)ÜzyžåRÇÚµnƾ–¢Í;o§šÊ¿]žþLø˜æ>Î#Nf‰úZ–Ami¥mծшš]¶Gñ¥qO³8åˆgˆ§¿öh�ÚÎÅÌ«ÝÂûyYìbûy¯Ùôã­Å£~í;o¨Æì&°æî¹¸Aãšxæ=ÜÉüšôëixkþ8ÞÞU{¸¸Æ³Oúy×ïš­ ²6ŽÀtzb¶ À‡SX6~©£óÅ?ž<éÿO*Ž,ÕUÕÿ·Ma#ŽÜôÃ×Ä­ëk4é¾Þ¢ úªgÕS”±[“®åÔTjj,5YE‚Úà”~¾C±ÔÔºªõTµ6‚hêÙ¤_ŒD"í­�0ß{zŸSRØ• Uæ%GgSSMbºÏÚ¿eë½m;tmºŸµüiÿœ>Ï<Ì1F ?—æÀS•næ¶Ã›5�ÖÅÇUgQcX¥‹:‹:‹7ˆŽ¡z‹7‰º›¦á7‰¸ffj½ßjÍ)ÁÌ´÷̰æÎä4ÝÛtÝ3ÌÍÓtÝß|ß7Æ]m¾ªÿ³©ÎÝC7™]‡w³Hÿëî3tÞb¶|ß MÞ¾¤/¹iM‚Çü{ÌÑž*Çüˆ°æ—nž÷ÉvÀ±åÙ+¯ôêël£9É›Úoi¹£ØiÑ7vˆŒäÔ‹é:;͈&º‘e[T©6ã6ic³q›ŒÜÒ« ÝÆ4‚êñT¡j. ‚ØËL¼ÜñKnËÁ¸´lÎðîž©–�á-+ÒŠíõOŒ´É›¦è ÌÏ#5¡EÜ-ó@& Îùï;Ë3�?ó¹·x;r<—tPa¤ïÚÓéóé¬*94_Gö/Žiíæ>ÏžZ•Êüý‹4¸Ë|Úv×8r⨾Þkö~oû4ç¿]š¥ño³�óÆÇ£‡éy¯¿›~Îw{ÒûµýøÄ«ÙÍ}IÆVh_~”˜ÿg·nŸIÃÖêG ¤N•iGR£8ž’»©±pxW¾Ç¥ÑlâTme8�±|Fçó 1×1y·µ=¼ÓÛÍ>ÏžN2,·B#FšÓ�8ó¥¤EöóO³ûóo}g ŇãÓ¶êìör�.tœ-¿1ïæß³�ß­fš9߯e^Ùã–œþN3_ááø£ýœFÃn³H6é¹c#;´ú¡‹x_îÖÿ{j±uZ{Öü:þ�ês(ý\ÿìº�ªÓiÿÖÖšŽkïæÜñÉ>ÃäÁ Ä9™Ä¿g?„r9<Ó7ÿ‚ø�ã�91¹]í®_ íæžÞcìþÌÁbœ‰©_WÛBlªÃØøâñÖ2õvAÛÍ>ÏïÍýÓˆœéxsæ«?_=xÝ¡áG¼Ï%ýœÏ¿–e߬J;U¡n¦°J}�¡åIÆ«‰&êxKbá,?e Õâ4~“ÎŽíÆôâ»8gï×ÿâ› Vq àœ&þ¥T~¾ö”¶ÑdpÍFúG‰RomuÔé â”§[§´ò¶¿ÏŸ°}†qÛÁ‡à‡ˆež4ßÍÿà¾#xåý¥ž%ŽòĮ̀ú37 ¸Jϧ3"dOœÌ‰‘23¬y¤· ‘.VìyÐê1kO§ˆ·}(Í ‰¸E#nDÈ›„B&fff}{„Ü&á†C,Ôízxsí²Ö.ªN¢N¢Fe}'mºž¢F± u›”>õ›Öu3®î¢N¢N¢ÂÊWzÍm� *°]\¦Ô Ö¯wZ¼uk‹juõ ¥4秬.«MË7¬ê$ÒÖ•_[(«¨“«\ëW4¶)»ÿ@»“CéÔkÎt¸íÒmºº§¤«èÓ¨¦Äéõk�Jæå›×­ÔH`Ù}:Š[Kª®ådÞ²­Eu¶±U®nlm1S¤ÔÛDªúìWÄÞ³zÍë7¬­” Ë)‰L¶ý=µô;+«rÄ$g#–%�¦¥Yìáè+ Ès·Û¤?îð¬öŽ{oQ:«7�Ùyj¹±\¦Å3¦°"ÊÑvôÖlY´@ªfÚ&&ì �6‰��bö{«(—&ÓÏCÞì xÃÛ´c6 ‰íÇ, ´M‹6, ˜mXÀgjŠFÞž­Âôp&Ñ6‰Pü:t?]…˜`u6,س¦‘ÐoØ“¦“bÆô¥ ¹ÿô7m¯†¦)ÂÊUq�0'hTF­XÙ­«Ú|`LL X0 L …š@QÇ¿�¤?ìñÚPN4ôu¸~çªÝ`êT¤ç†Ø¬ ´L ÿ|r¤ín5¦ßG ¿kÍ]=j­[tö/¹`âªÒ梁Suš{4ú¥ÔWöR=rU¥âœTÚÉEÖGÑÞƒI©z‹Ôžf%i¹µ{Q5ZÁ²¬Û¨¤a û,ñ¤îrÏÙ»•ölc¡€Š9hþ#Kä\ƒÊ¿o5û>yŸ6.åè6åÍë�y|#dÖ˜ Ü—W¶»çáãÔ9'·˜óÏûóo<¸‚í·?ëŽzfþ�嘿³��ç�žÊÚø­½}u+²±)ð|D~j=œ]q¨Ñ�ÔØ}e?®Tö»Ž�õtÿ¿ˆÿxá?ÄâšY¦·dzö? ³eüÿïÈOÙF¾“¦ÕhíêÓ,©\? Gsš7¹Mš{k”ØÔ6“PºŠùÕì¨N-Ä[Tú.‰³û«¥m}÷psé¾â"ì^5«Ë1Èáî´vAÎÏ?æ™äâs1߈0²Ïo/íÇ"'!+öó_<ÿ·3ç™�.\ärÒ»-º÷Û¦3‡O%ñÌ{¹ÿ~mç–®½õWüqÏM8˜Û®NéËçã¹€K<óEÝ5÷ôtúêjG*|ŽGöÐ}\u;p³š­ýyžf;Ö{iÿTÎc6Ø�—ãôuþÞ#ücìá?ű®¯OÓ³v²ƒ”åÿè#0rFÄâú~¥\2Þ�³}ÜŠƒ5š Þ/WC}6 kåJæèµ{H•iÞ1‰n¾ûabÆ´f<>ž•bUì©18¦°Q]ŒY–pºvUöY`­[_ݵ³†Ù¿Yä~ÑÊÏo/íÇ'8³<ëöó_w1îæ|ó<¬\ÇLr°Í5L‡Š¿¢h_$ñÌ{¹ÿnoç‘ðã�´ç×Çé[vŸ—ör°ú³Ëä�XfÛĆtiïâ?ÇoÕÂ{if¦�jYSVh\Í?°_þŽvœ-£uzʺZ�3õ)‹ïçoºÚRÕDØ9i{/Ôuu˜{®sÅá�+ák)Ò¥p&ž½©¯Õ®ž½E­s™Ã©ê]Rí_³ˆ96b[íà­·YÿÀro/îlQò=sfe»�û'N åI‘ÓVéöEïÓ›&Ø£Õ¶m›f&Ù´M‚XÁá�Y²[N&Ù¥HVq#›f‘IM³l 16ͳ;DØ&Á6 ôÄé‰ÓÒtçNtåµâµ¯#§bT€YÇñðã»O´M³¬B™�# ÏDNˆš}8ϸUMJoººU CBÊ«tÄé‰ÓîÉù:{¨}=-³RÕ�¢©ÒbtûÒ¿Œ×6E±ùuƒý<÷×äQŸO LéÂM†=¥T6¶�3:q«ü½)ÓÄéǯ Ræ®%StøUîÍ´ÅC¿dØgNÄ›&Ù®Õ4ú]%¶Êôª�$Ç|´ÅBÒº¶Mv½iê^ÆVìŒÎÚ:šµËNó¼ï;ã[S`»G8áUmÕæXûWÁ`±ísa›XÎ’îþÞN?)]Ðr§Ç4÷sþgÏ=hÈ­Ê5m½#xÚ" G�gíùÒû9/Ø=Üÿ¿7ñÎÿÒ¾Þ|[Õ¤áMÛ—öçoºT»�¶ ÓW¨:�F†�‰Îˆyy û±ëFôêFÍB�Ú~CÈóG°Tï“îÔÿ ûµÿÆþœ8«Î¿o6ýüíýzs5 ˜£éõc¸AêåˆßnÀÃϺ%{¡d¥x‡È,Y§vœ?I¶ÇÚ¾d%{eÞ4+þïߘ+̨�ì'ö�í†?ìçWŽkîçýùŸ<Þ6�K�ÛΩ±^¤æù¦Õ  b?%û»™÷s³ÆyÚøÏ>!gúº;º6ƒ‘?¿!,÷ðºÕ_Ö›Û‡Õ’žË,„;Ó¯6Uh>3ù`3Š.5&Ý¢ñÌŠ}¿Ú|«Ú�â~·øŸóÑ óAôs?Èçwê¨íkÝ@Öìk´m»N¾è'ûWÇ3﮹¬Öצ]^ºÍA‚*–š-©{7¸Ë ³Y>¬Êu’»ijƇùŸqä¼›Ú¡a½ë×:õÏ©AV³ë±ºÈÚ›˜yÓ¨d‹­\ ZO©C5:‚­e¬ñ¶ç—Ï"1Èùæ}¸ç£b^fÜ~i›¥Fͤ۟Í3lÞ­¤ônëlΗúiΜÙ`�­›­”›ïºoºnº¡»u³}³}²ÃgKu¸ßd×5�cJŸ�m”š5}`£¹Î盬›¬›¬�ŸÞa+èK] ¦JÐÍ>�f•GÓ/Œân0“5·‘7ˆmÌÜ&ñ7‰§ºjme£„eµ?~`ä|éë,Üå¶±›DögìëóÍ=üÿ¿3ö7ŽoíäâX�¶C§6’3CKÃ[ �ÿÆ~ÏŒÀÑš,¯NîhÓªK4ÈÄéG˜‚ô¹=‘ò•Xí_ ìÜ.¼_£²¡ƒÎ–¯¦LÌGc°”û䈠Ì~KÿKû�×_ןvžTøæw;ÿHåªëüécEb�£Ôuƒû¾Äö�mO[ˆÇ*;Í>˜´¦€�DÓœ%~9:“ºÜL}”{¼§u¼ÏØÞï&í+EÛÌ1}�,ýƒš{¹¯¿Ÿ÷æ|soßÙÍ–*úvͳd5i†“ PÔ3ÑIôµ™ôuÆÑÇÓX³¦ÓcM¦`Êiß+ÑPѸbÃÃì�¢¼G©ë˜•Óe±Õ•´Ôï?L¸m7¬èâèÌ]�Hmâ±Ûh…gO¸¬gKPDºÍ³êZuû½U]5ÚLW�wu¬]eÙ:ÛQÿÈ\ â7Oò7G×Ý>¹š·îth-ÒYY©twšm­Ã¯*¹à`þîz�Ð< ªý�rѺ’"�UýeûÛXœKSÓKK1© M6Œ©ˆ‘éA� ´í„äÌf0ìlM?¿�ó¾~ÃÈ0Ê( É=‘¼Ãá=–GýÜÓßÍg?ïÌøæÞ9¿°}‹íû±6ú¶M‘Te•a®tV2mL¦}8¡ ‹ÞyäÔzieCR6òÿ¾&&%�òÏedl‘Š2÷Úµ+¹raÚ¶dn¢•·‡Z¤ÕbýƒÍŸ³›{{òá¿§]^ê<û,‚SžMüŽwþ‘âkŽ4óOîÓ.*ÖSŽTÙÒÔŽã�>ËîWª´Øáw5,Û‹Q”€<õ>Þ@Æö§ŒJ7³E‘¬Ÿ³ÌîIí�æÏ™fþ°êÌÛ3lBû³dõÏ\õoË̼Ë̶ýÏ2ó/2ØðwÏT;±Þz§ªØ±ê�çx¹-74ÜfªÒmÜósÅÔØ±u�×T†u3¡';ŒÜfè[Ó¾š�WnäÍ)Ź™ïCbn?plÚŸ›­:³«,|άêN¤PÖAYT Ù*Ö¢5²Řòø€â 'S³­.WGM‘ô ³éW?G™ôSé'ÓF«·B ÑVR§ökj]ëÚh5 ©L×z õÁ©®}ES¯Y»¯TúŠç^¸ö¡¬\˜ë×5úšÌê×4åw¥ˆÛQ”Gf]ú R5]d�t�d‰ujš½@±»M*Ö"”Þ`'Qê+De ½gQfõ—a«Îé‘20;5 g·Cüï˜~Ð1¿’x–0~fÊÔ`Çýãšœ8çÿNmû9ŸßÛÌø_o5ñÏWŽ¯Ú u,úǃ_½g××ZŒ£Y\ÔêËýš3‹çÍ>G-E¦Ý+y4©73zkë VÕˆu¯‡µÞ7»›üLj¬TÓrÜ�VöùäµpŠ� À\GÆÍN”2ê)5:§p£Ä<�òf&³,v¶Å­\ï³hœ=]ˆ&²¥zì>€ì¿ž®Í”M{¬¢¨*U|ÌM¢b/·™š­?!‰Ú̦‰]@ Gmó¡ï÷ÿxÌ+’6¹†µ’{LÆšþÁÏþœÛösøæþÎgÂ{y§ŽzÐ6(Ïÿ1ög$ùÓ~þTöiŽV&m*D®˜›3v c�ŽmîÏ6û·’ö:{÷@¡ãTÂl•Ô^v® œL™c�ˆÓY¥#Òjzüèu1añù?38—~—³bÚæÇ�g\s##T›/\¡]q‹­¨Åº¶š§Üf‰%KÓR/ؾÎLp,Ô±z˜X–éÕáѺ3* (•¾Ýκ¿q-‡0"‰_ˆðˆž‡?“šþÎõæÞîßÙöWìæ¿f³¸¹cÿ¹ó¦ïxå_¾Mü‰°G¯ÓmGh® 5ucÇÇ'÷AɼòÌog5óE�4ÌÜ9 êhŒq«Ó‹†ÂŒžiÔ½r­BX†þG=]¡h²ÓdAÜé—v„râ ùˆ„LB ñ‰¢LB{ŸÙö'³–¡ˆASJWbsíöè;k&~ÿíÉ9?:üXác³o ÓsMÍ›©¸Íæn3wäß:“y„“7æï»#t$ÍÑŽWtÝ7LÅl/PMó8•·§tÞ&ñ Ʊ}yÄ$ŸþYçó¥­k^¢ÎªD¶±wÔÕ�¨ª6²µ†õêõÐϨ¬C¨®=è@¹ ê¦MÕaí¬©¾Ÿ0w$ˆçÕ™¸MÂ1p›ÄÜ!a·wmÓpŠÂn®í±\4 !oÏ‘ŒÌ÷ÔiÈQÛ9j¨Ý¤ä@Ø‹¨*~¬õ~²}_gÔ9—’j䲊±)_^Ñ{MBï‡K˜ÚW•– �ª=Zq†ùoÛö'·‘›'6`‹F¤Xü­>�óFG/�·þœ—•“ ù•®FвïÚ9¯ïæg3ößÙöWìæ¿gÌu :¥ÿ×I^÷‚3mþì)˜né¨'®Ö6Eýê¾µ¶Ð:{lLtÒ[Jtè­ží<=¹7»™ñÏà111LJHè$é××zSOIŸML¾š–¡¦ Ï¥¦.žµ=%–éVõm(CÑ® 5 ÕúJçÒ×>™%”*Ö(\&”4«F€.˜aW%RY@ëtDèÃD:43èÎ+Ó¸²´Áéä”�&Ù²l€fm€LM³ךּQC#b`ËÆ“ù“?yýœ–³{…¬KàË¿hæ?w3îæßcøæÞß²¯×Í~ÅÎG%\-Úv�WŸÇØ.p¡¡ó£¤XÚtØ�Cˆµƒ¨åFš¦ïohp5¨[_iÌøš‹¶�f™r C!RÞþlffa‡ÙÌEòbn‹7¨Õù…€?�Ò{åŽ Ê{×jŒB„ÿ±¿3t̰fªªô¢bŽUþî^ápÁûÛÉ;Æ÷AÍ=¿üíñ þgÿû‚ÍäÀ›ˆ�ã’Ã-ýœÿïͽÜÛì³Ûͽ£Ç:ýœÓÇ?íÌþÍU{Óÿ�T½¦¤Ç:¿g%ö:ú®«°\-eDw ¢ʃ�8Å1P,d MG~9žyŸÇ!Ü¢WÚSž°å™©ýxfÇ-/ênð¬uÌj­ÐŸOÊGEc�»äòs sAÊ¿o*ã{ùg¼OoßñÎß/N°wÁÏ?‚™kUä¾cxä±¥ö§Q`µgQaqÕÞ&ñ:‹†w‰¼N¢ÆiÔY¼Mâ1w¬.¢ Æa·z㨓¨³zÄeÛ¹fá7„L‰‘33êÌÈä|ÍE dtd0mƘ2fž€ŠÉ¼( ²¯o:lÀËÛ²ŒîwïeÒªs]ì:ƒ�–%¢Yj©[J�å(­˜TˆÃ¹Œ{bP šl@/‘1�daëš“ø3Ëà¦ýC8�‰�ω‰‰wé ±öC3-û;JÂãjÌ,\FnX‰íÿço·Gü± Ì|ç—Á÷r_toˆYŒ)™hï/ûso<ßÇ3ã›{G·–@6àM«6,E\mbÏ@l àMcªÚ䃠%­À˜†¥if‘ �O¤xš9ôÉ·¦¤ ×;NšD]©Jt“Ö¬~�sôë*­ëªÅª¸±ö)s5Yè­" –V5 Š©3JËŠ­(ÝgÓ)Œµ©«K(ƒL'Óˆ(íekèf}<O¦Ü)¨™Ò Û"«3Ón¾Ë1ÒyÓ²[]�>›Î�“§d5Ú KfÒ–ák¸¦Ö˜´]‹§æ�ÖQÖâùùæ/ƒê%=mÿž¼üù~®?4ü¸ü³òÄß´&l€Û ³vm™²eçM�ù`7<ËÍÍŒ™–›šny–›ŒÜfã/gÛ¢?îDÄ‘óÈ{¥®Ë´T&]2�íæÞy·�žMã™ö§·švÓž'Íí¶»}Ãh;_ͽ·ÝÓ s±Ò3²ÁïĬÍuÎ\4ÐXÍ*?“‘�]·uKî3VH§Ç6ñOzá©r£ŸÛg°ùÓv–{³Ù¯9[»j=J‡)¹ C�Ù ­´-4ÙÜ3Œÿ° Ÿ:‚z‹�³Oì0#&f¬8<×Å?³�–òÌ'e^ÎBÙ˱ä¾9üã™ñÈËýº?æ/3 ø™�ç–ÿ^¡P©É}ÒÜAär?·›ý�íÏ6ûµ=¼ÓÇ4û3ë½wWjæl3‡ö»™öëSÓEFÆ^Ã0xçVÖ×Ü©œ56Ö„uaäãý“à&¬þ>gŪ|fWûHí±w\Ø}Vxw-ŽïÓ©å§ñýö’g4®9än19j?OõÏiŸVŸÛÌÿ"g 5?£ân‚Uû¹fZy³v¯o%3þ€ò—ÛË3ûç™åžZƒèПöÔö·&ð Ì>àõ7N™h€)–{>"û¥Ç MÂn°ëoY¸MË„Ü&DÜ%‡° &fá ¬2ADöó¬úy§žcöMRˆSÓ¤¾Máý•ã§…öòs°R�IР‰ë®žÖg–{9ÿ`AËWúù¶LÓõæ`í+ ÛžÂiüȹ€ ËÎ)µw¨D�ây¬ú¿ÿ¬Ï‰©oÃ< âi}¹‚ ü�<òÔÀÛ37@}[¦y çªöhÿ”†|Áäró˧ëä=ñýƒÁ›ÀoSKÔœÛÎÀäã°`LÞИj‹6¬*¤`AZJÀ)µfÕ†µ1+¤³¤³¤"Ö7l`› :˜ªÍ‹6¨r›fÑ;m›fÈÛdØgM¥*J5[ŽâÑê%‘OP£B�:mX>Û&ÛfÛ¥¢Ý¤_1t#Q—]FÝ:ÚiÙ~Jß6ê%+oP ÌüóóÃÔëfÐÈÖ˜MÒÃoK6ç7m^¼&ìUÔ uÃ~Y›Dßg\Ûl[,3©t½¬)Ô¶o²²u,”»¨ê<¼´k Ü/í×3ê ¶ÜÖ5uç[¹´Ä·m�lÎ´ëÆ¿¿Ô,ú…�uƒP"Zª>¡g]gXgª»ºªbÙ`(ù™›ñ7Ã`�A7@ân�LCnGUgUgYe÷.Ý#cSWp<ÍÐLÅlÂcóþÙîþÞ ‰,ÄÖýn÷aˆŸý�ã›{yü¼JýœÓì_?úOœÃæV{~ʽœéöó_äs´~Qâfj�á·b1ôhÿ�™™“+ý€â˜Ne§óü�r.EÊVµîŒ‘xž™˜{Ev&ÏäX7Lâ|júpa3ãšnbžòÌuÄ ÊïÔ¾ÜϘŸ·–e�8ÝžçÛ™V9æÓ3331OlÌÂf}Y™™„öÌÌfš‡í¤° ë´@cAä{Á3žïÌ\!˜W€�û5ŠÛpßiûÎÏìös>ÚO~Uû9×ö)üœÿ¿6÷AÊïgÙWëçW,÷ŸöÌù–ÉË3QúG3íÓvªf;Tß”4Ì-·Y]yžØªZj*ßOŽLcä‘ê�¡1|±üÞw p—ŸÀ|g¹=—;hö+f{X?4^VƯØ74ý°Å2Óõs©Æyf3ŒÌÌÌú³°�¤öÌ&Xò÷Üi”1YS䆙³3ß1üBã,7Z e~dž¬Û³òj ±ÆXÁý–x>ÚÜ“,ýcž{¯t3<«ös£‘8à?—Ÿ÷j�GË{¦éºZ}iÓ0©£èä"}„þy™ña³7‰º[ê¯1ŸŸQ("öR¹;@…s2[žìÐñÔ€´EYØÆ÷jÐö¶H$mÌZñ:sÕ»~Ž,/Ù0N_úȦ`ñG�œÏÃùs7MÒÛ}㎣a}¹î‡òОVOúLöS˜ƒ(­¸BfryŸöçŸW6=³¥Ïõ¡ˆ¸‰Ùƒâg—À=÷G°‚`íî_¿fqîŒÒÏ6‰´K&Á6‰µc ÀÀ�íNÐ�6¬þª@‹6w¯Ú�A,@J“3¤Dfk¨Þ›6À“de;Ê´ÚÓ6Av2Ÿmöa«ï=U°ß’Í�i—{T»M¢á6º�h'¼õÞ§Uƒn°Áº%jÇ¢²Å`äxbT†ËQû2%žÔܾêÇkØôÚÒ!v3¨¡(˜`@{w0àË,Z—ž"ŒCfÆWÞY¶­gÐÃj§©uþ?¨Iõξ_¯Y”\ЧP“êBG¼uM•´ê¤{Ä_QQ+{9`%n7ïm RÀјB@}Âf�€ú³ªg×™™˜O`}9™™Ÿß331�bc´¹¥g6Uîß�‡°1`8›¡p!l†nÑ;Ìþ]Þ˜žÌÇÂLõ%Äg81üC0Òß`æÞÁË<‡´Ç=·vS諸 � Œ”&�ªº²LóLΜ*Dv*UËB �—[‡U6L-ÓßeŸ™ † uµŸ©|-âÍaš†~µ�D n©�B€ lVÆà “ƒ—\“_{ѱYšsê|õüÎÐŒG|K_uU.ñ´mÔ¦ÙÃïÀæV%÷U@³^®4è 7¦(í·]LVÌ×úpÆÓ¤%vb!\Vf°@ýí»l§;0eJB“ß#9…7�1´ÙY­Å¦93~î1ˆÙPW=$ÇN¹Ò®5i�Š'N¹Ó®të•¢é¤é¤é¤Ø½M‰6$Ú�…ÆW’e ³8m€ÃàMù6(NÕŸÉ�Á}¬Ø5´Ì 3éVÁ»À`yÚƒ0¶ …­«—jÚ¢|tc雈åo°AÉý£Áƒ°ÌÄá0d X È úþ¡Õ‰ Öâ¹VÅ~²N­bÐMeÂɧRGHâê³êÊGPµæã2gY•u7µªQút©k˜‹ªî®º—_R³Ý•¬ŒKrÊþ‘CåQåv÷ÝÛ=»KFØö¤âÀ{VÛ¹)}Ǽ6™ «™eaãéÁZuã:7^ßFõÔ°1ÆžÖBÆevŽšËöØšZÔ ÒÚwÆ•–RŽÐ8 ÕCYÚl*Ëx z£V U ÌÄ+ e¹\l*¥€Ü€Nø™™a™› <ª\Ã`t-ùwÀÙ.JË-‚ÌŸ1ñ‹©±•«@|‡llÍø5þGÆ"ŸZ œG16fgx[ìÈ)ÈfÅ•.T EîvÎ œ­¬:a¡3pÁ9™žæ «Ú}5ú¹f3dV;³fbvV@ÊPåSl«¹(¤êScQayS€ ÖâʰÉùÝC]WJÕGhÕfµ¤¡ ¶ÁY•°2ÄÈút “v£ñÖlk¯«�éu +$8þÍÚhí&ke³Ðˆí+=7«G «‚UfgÀ÷ºY¢VšŠ§îDËûíb,]aܹq´³ñÀà�â ÝY‹J ã‘­U{Žšøë;BÎwm*o}¦|÷š¿rw‡´KFÚæ«J;ï Vì!}¨7Ô¶v½[„´o­@š¯Ukè²² _CVåˆ9d@õu«*H(ù?‡|*ö(ô6-Ø$‰v—1ƒ#¶uwB½‹>&ÝñÊÙ:.ÒÅD}©µôøjt÷»ØzVUb•9ÀÜÑhô”Y´ÆSË=¥@‹“,æ¾µ¼ÝiÝÝ’‚¨Î:È}1pPãR©.e‘”ØÕÔ®6˜µÎ˜Â¿LýQÅVõ%m“{â!ô³zÒÌMCnœ fŒÆ!ÞÕœf-v6d¨ëËnÈÓÙêgÛ*ý˜�1‹²“ê[qÔuG¤i‘5 ¸êË+é½€˜7,ÞJ;“P…;/¨Vèמ…S骖PkZìWu®`ß4ÁªŽÂ±¼X¿KI'B Ù¦c›2ŒÖ[l߃ÕS+JÔ�=dÝ»M)Ö%²óWNlTÝ,¥ê‰é`¨/¾ŒÒI€Lfk4%7F[Ä{X/ã0{t¬eº`ÒÆ kít{,l3�ô¶Ú:M:&&�&À¯Bµ[Z#Ê4È‹`PºBP{ò·i©_p …[ ž§ã®¸¬ ácSßYT4ájÕt&ðRÞŸOJåÔ&ÂÝÀ;bn�FSõ ^u:zëšd[@ÓT"íI¨©54L¢¶9¶Ø/Þ›©«²!hÙÀV`}÷rÝÑ÷4c]NÇt0<0áNz¯/fyâ ›u™ÈSÚ¶ΟPµx­÷K.8P^Ýžžˆib •ÖXõŽÌ{².ÈoÌ{šÆîeˆD°Ç”ú¾åÐzŸ33ÌÖQ]c3Ì#!O©2ñ¨®j@=.êÑš�„mdšq½7b5˜‚ÿQ•W›Vªö_WHÚA«Qs^ÚrštƒuÝPêÞ—¢¯Ée'mÈÉ]zv²SEu «U%C€‚½OpuTÓª`ršŠêP©½lf¡eèD¥e8b _3W¨ «ë¬ëˆÝ=M?Oѹk.G¦Xä5Ê·©»îÓË4·!´Í•¢íµP,5Æ :Û·LÔ9xƒ±³»w±i­VÍ-6K4a®Äçk{P²ÄÔ÷W[´+‹´ÍÓ¦”E²®›Ó©5*ë*i©ÚÌkUP+Ðô{b7Qrá0ú›v¶§S[¨X¼JÐ˨gâ²Q^ÐWj© ;úlö)õj='{.Œý•É,ÄÈHò2KúYG¤v³©é°ЬÎÇ�ÆMʲ¯·^±»�[€á÷Åm¦nÙJö6ŒNÔ±²ˆ3n £bVIÕy§ì™�yn¤ îó`˜å핬%ûwnÅ)Rì±ëêKÄlQ¨&b~FLN¶åѪ½›pdZ›JŽùˆ˜˜0¨rOLÌ鈲#‘´5�~§r=ª0šuÝôÖJ‹iì}8-Y(mcéºrv¦¡«‰ª×b¸ÖÙÿôQû©ì‰¨qutY€{Ôwu}tGõu0z��)Z„K%—¢Ái²Ý>Y_F÷E¢äU9YuE›kUe¿’Úºë�‚s165 ˆ§±99Új¾Yp½� Â�2Ĩ²’l^˜† zÕàÓÙ]ÕºVJ¸FD¦Æk´¶WYµŒ¨h®Ú×M¨¨­æuH�HÖfu¯OºíIè11ã æv‡9ôÀÇ5œÅìädVnF÷¶Ø0#ÑÞ¤ ]w¸Ê×[n²¬�EB=cj-‰&1ÊŽÒ¸€r mÃk,Zvî½åg × :¥ÛÜÃ6Ó3¥ßbÁA$0ІY¤Ú”ûïßmÛ@ˆ…šªÅjѪXõv¹^¶WÁMSdn5ýZ8Q˜äN%þ»÷Ãge|ÂLÝÝì=W´‰Ô}ífù°õæuq,u²  ÚMÐ(iB¨,z�¨Ó¹@ÅJéw¸Y_°ÀËZ¾êÛ¢®ßë«J}ÇÒÌñ^hÜ89 s…U•bSf/Ô×¹ÏSdÕ;T•ñ2î– ª˜ä0¶Â, 8“”jíVó·{&•eTVIÉ•Ðí+@ƒ^Ê•éð¨-=n¾@9•89Uîéº>� j�øÖ"‹ª¯h þš°’+RЩ�S]¥/bþ0>Oƒ¸ÀÙ‹Ú݇¦ïhSÓq vn ÇlvÙ¸l_"©¨Tèé»6NJÌF`ÆÇÁÎej‘«õ=6G í?ª|‚Tên�Êj6Jê�¤¯x¨bÅZÆø^h«ÈÄòí;MÂ9-«:é5gýjÆ%þ‘ELñp³3È1–`4m"4] ¬ Ó ­⧬ µ&úLùÝ+ìll…fa‡BLµ{@•zÇJcéezjÖ_§^�lÁ±“�’ã‘]Sé“mÚzض‘ÒÍFŸ+h)¶ê¨fE97c gU™0kó«³e­k¹•9ËZvŸTO²Ñ.Ê�BMè`¹wÕ¤E;f&" ÚZXFêjÀdXÜ6 Ï¦jÅnûúÝõúZKC…„ËÀ²º«a-²¥²‹U³0Á1O&+ošÄ°EQš˜ÿªÝ½ÍÎ*&äštú†gžà}¾&Ñ Ãrfæ-f–;­Èh2ªéj…OéÎCrˆéH©,~ç+mu±‰TÚ �’ÚC­T²ÄZ|j½M’vU-¥È­ß n)é]+áIk�“©.|ÇìC ®­\s ·ê3 €ÊÎéJí±‘lO‘5.á7vVõ XÃkAi Z n|åw*Ãjˆ¬jléÓ¥YÔÚªëaÙ^Ò‰5Hi¿0M6­U‚ˆy=`Ž›×,L¦˜¨wlAºŒâ¼tèÉÌŠ‚@Ó\Y¼Ø¹ŸÖ—ÍÖ驲[¡ÁFèËò"9"´üxVQIίIe–Á¢&.—§» ©òÕ9"[Ü”©"š,j¢Þ¬OiSu"W|ØvË5º{Ò ù]Féf£tìeNõCxÁÔœ°^«LÅë¥'ÓVGÒ�ÁY&ò ît§)d{K^ 8úeIJÔ¡K¨Kó‘ÄB²V˜šj­T@:]쭌ų$Mþ”ÁŒ�3馥Ô` ´¯´gÞ€äªa+E(ÔÖñê5Š,ʵ�ÈžZ·õ–³`ÃBãkXhfx��:¤Ë0Üváz%ÊR2(ÄTÁ‰ˆ¤m±²,~Ý¥•ï }]°Í7ƒJ³½% ÒÒcéö…�nX¬õ²jW o­P-Àm’¦Ü œ.úÀÊØP±Ý Ÿ’XªQ_NÊhܪ6‚ÒÅÜÒs¸'µw5f›’Á¹LÞ¢YÔ®k««Üä•Û¸ -*§`†¹Ñ2¤—Øšì ù�B×MŒ š–Ü[�²ok¾ãšò)c†ìЙn3žíçªÓOi,LÔàßPÈL"³6`˜5=tiVÔV-¬Ë)W•îI¿±î êL¶”y©¥?¥ª±…zmPSMÉd{UÁ¾Úôõï³N«,sSéŸ|Ö?N}E5Wmûæ�Eˆ(lÑ£S.Ò u%MQÏ_¢¬»áFR,«OŒŒÛêtÀf}ÓÌNÑ\reX …Üþÿ1K©\•&j*ÏNؤ«-àÂU�…BÑIJÀ‚ßÄZÜųdÔ¹²UúÛbÊ÷[ªÖÙê ìÒ +4¡;êjõß[téP±;œ"�—m‘çø(ÑèÊ»âU¨läâ‡ê͘›s:rý*¼M)¬me™Þ¢fÃ-ÖtéÓ± slcvi¤ ÌÀÁŽÍ¢í-Íä•î{cÔˆVx…¢IÀ—‹º’Ñ.ìtZ`Jö爞%Îev¢µ„)³Röißê4ô +¡7F¦€&»Hˆ•^,_ª@~ª˜u5Ãud5é¥ Ô •êkÍÚåÛ»qÓ.àDZÎèÂb[^@š&Ë[íÈäjc“ÌKžohš{ý5`ÕV,Ôðê®ãì¥ \¬ÁªNÍÊõt�•bQ¶½;S°ßoÓ#Zü5cY~•ôŸ’ž˜0€fɆ‡~À ÙœJð§3Ò1{)íæf{¦r´W™e@†G{E³ÜU±ìÌÌGÜ€Ð��šX©6] .«5µ!ìš�•2Céñ¸­Ù‚÷ ïxˆñMB%ž¯¨]Áƒ- `£äêUuå¶³E@ Ãe—ÔöK-Îɦªû&ž®�s·Ø;EDÍ•²©aÔVé­Ÿì2Ô+]@E·©ZC©rë× $µ±+qm™ŽŠà骖iÝNš–šdµ5ôÜ�ަÈ]X‚@ia]ª‹±@&x„Ïh\4Õê]/³På«iÒi%¿‰hÈ|¤ÝÛâZ‹m .�N®Å¥Ú&٪ХÒÝ%ÔMŒY4ÛfÕÀ ³eŠ�σ᜙]»¡–VÒ¦jÛRø 21ؤº› 0q+îÆ58~¯Lj.ÌÓê d`„~×t÷0¿O[ª1Ý-¤[P0.”p®ôi…7-£wc1ÙWhÔßzj4Ú…±7 ÔY©¥:U�Ð�-ì¡»"ƒÕ,%�®œÀʱŒn¶Ô¯s” 1·H›¬Ò8+C´Úw‰ÝÛ¥´‹!°4ìfþÈë¾ÛÙQ0â¡Ó�º–j?ml%÷«j8­q(e3¦®¯VÉ·²ŒC´ßöÊ)&ÅH àœÀ½À8'ò¦1öf&LÈåƒ�~Ä\Xhð¶XáEëׂ€ Hþ çl6æ½"á &æµ;¼�jo¡m°¶ÚºvÍR¨Ý•ÃøŠKœwâR{qFÿrš7@U&’Ùª·}‡†qº)€ŒL÷âÇbè‚¥»FYÅ�áÓ%Œ3-!CZ!r‹–ÊÆv<):L"†åF�®6ðÝëe\ñ2!=ÎH(¸«K¼ÛÂíÙm�iîk‡ëÒר¢±%ª¶¯…P\.’Çðøú•é«NV.ô²–”QÊý=N¤„¬j=C™¬Ñ²E©ÕmBE+—ØDõOT´`¹Â©�Ù«¡D@êÌ‘û_pgT@9jáR#ú�ƒÚnÄ"5„­ìlÜÉ)Óxk¬�UJ‹¤ÓîA¥Ã<£[J ;+%«RM=4�0gNj\‰˜ÏÚ²fpÙ/§}®©�aŽIšg±U.ÌÎf};¡3zãzŽâݦ½Õ®M:nÕf“n¥ÞVÛbZE;±È„Ûca#œÄÄ1=ú0™©\"/*—sqC·MEâoõPã§ÔÉ®ÝÖú�¨�Ú�-¶jtÔôë³M]§§f•ôÍÔ¸U»[ÈÜC'~O‰Ä¯-(9©oyå×Þýç}£MbtÃK˜¼ª�Òª«Y¬ �“r4ÛéA€N›A™ZÑl]F�’mîDUfm.�Ó]kX—":i_(¬s«m&’ýõ—õ&U§7=T*}‡ÅO¼A°1]ú ãt›X³&Etl–i‘Ü6fµöÕg¶ßvul·l*†—ö]¾�ÛB÷ˆHt»p6Cq‰q3WiZô�Øö™ÉnÒÆîÇ31¦;yjëéW}zJÔ Ð Ma¨ë4T‹€æj“Þ†/]~¸Þ™æfYîòØôU~Àw¶´UŽÄMKw 4ÕŒÿoïm�M©¨l��˘þ”¨nŒÌ‡Sy®ºÓp¯Ý©J)9²$RVgxf,Ü4fX{±ŠñÌÓˆ[‰œ«zY{¶â—ñQø(bÚ”žÃ =§y‡²yƒ—ÇÓ&u™­°ZÐYènΧÓg�QÝu …´Êm`ºvê5ÌÂû’» é(èýn¤hµî;Q•³V�ó³Fí¹{Í™ûu5+×§Ó+JëTç¨r²¶Þ‚…R`¤§7jêT«†éñWÓ¦üd*(¼´+·v 'JÒp~õ´´ÿÄ- !01A@Q"2BPa#qRÿÚ?þ>›©!ÿ± GN2í—ÎøèËk5¶ßXÝÂèZŒ}ð”¿Ö¸'FíþÆ«Ë_ûd(Ž#ÎáìßûÆüV^(ØÅ¦>‹òIß+¿”5\뎛‚_ìM¦úÍp¬!¢¼ÔQEb¼?~Å"ÉiÆDá_ÎOø´QD[‰ExRÄb;F×/äí(¼Yeæ$ø£¢ù^,¾I›¯4QEQY¢Š(¢�¥QER(¢1³N*(r’bœª�H›þ%ÿ.¼µÇMnd¡´ªˆÏøtQX¬_C|ë)ÐÝâ�¥J6³ëfÇ…†²‘µ”QX¡D¢Š(Úm²«‚6 P:º)ê*ü?b]Ðâ�±6ÄèÜ„ÍïðlM’—D“òï†Þ¬¯;Åq²ËÅð„¶š“rFì|t¿Mm4ŸFÞ?–Yeãiõ³écÓhPbÒ‘õHú™õÈú™ŸYõ#bC�ŸZ) ,¶Mv"ñÞ"/XÜ7ˆ’.‹7�ÆöXåx¼îe³{,ÜËeÑw†ûÊ•±f”ÖÓ¡²RèÔ—áX¿à²#ë6_‚èr^w�Þf¿×)›ŸéyK…–Ye—უÿ¦áÉ›¤}‚™ö v9Ѽ‡&,7‰û,i‰6%C#Š6�tIæ¼W›ÅYõQõ#ê^/R®ŠCq�³W[ÿò_ñb´JHC(D�G,‘%Ùë²Ë=úâÈá®±¦ë M±Åá ]áóè¯è¯ x+ŠƒJ=F�H®{‹ó/ (± †$K]‹¶ližˆÊ�ä¤A›’-±ÄÜG,y¬×Ïæ+‡ÇÓÝ"RÚ¬†­«.ÊvKNI’UìÜ91Fý–�œY$D±È¾ÉFÈŽi –)Qö3ìdd™Ðñ§ï?ò96nÐæ6/�Ã|+6Y^ ¥gFÚ“Ô¢R¿ä^%†w‰2Èû$‡CB�ÙxC)ýŽvY¸ÜnÂ…‰"Š/4m+‹áñcJÉ/±ŸTR%©µQJ>ßìœïÑV4Dp¶=ìÓ·Ñ%±C‹gÖ8•Š6â±El=bòù_þ’ËÄeBÕ_¢Q™©§· ²Ëå|†ŠèhH®X‹ÄwŠ+4U•Š(Ú4V+) ˆx¾)–7Š+„;cÿHô)Î'ß!_±Ht7´„Åö6½").Ù©4Ý#Nj&¤÷z˜µ Ñ©«eå ±ÑhÜ�È´o‰½¢nˆ¤Ÿ¡—šÇ®>ùQE22¢SܸE y× ,x²Ë/Y´õ›E�±fäZ7Ye›ÍÅ—ÁY¼rL¾h¡á¢ñ¾�/‘^Ïò -]ìrÐþËÐþÏÿCÿÈ­ìŒ~?ö�è�ôÂ�ñ¡ýDáô@ú j|dýšˆì¶Flsfæ[-—×  'áCÅø:þe—”'Cw‹,¼^,²Ñ¹Ѽz‡ØFvJt}¤d_ƒs7>R,¶^l±rH¢ÊÆÖmG±DØm+”—ËK¹ ×�ÄÕøª^�M÷ͧÁeáeø%èR±e›�æóì>Ãì>Ãì>Áêiö³ìgØ}Œû¤Þ7Q½›™ÌúfÅ¡#è�ôd}3”Ge±É–^/�r„¨œ¬Œ…%\«�õŠàâP¢m6‰p²ðÞ&ñ¸zÑGù(†¢–~$wO2bwÎzjhÕøÎ,’áùáÓäðË'™zÂd™|—Éøö¬ÕÒÛiè9øñFÕÅ!Á2?F¦‹ˆøWŠ(HKø7D¸Q\ÔJ+/‚eñr£{71Èz±D¾Gô=i2Û~Ž›4[LDÑGÀ�ûYe�³r7#z>ÈÿgÛìûaý›ãý›£ý�ÅšúÜIiÑEQH¤*::::¨û°û>/Å/XD²¸./’4à׆èÒ4¾2�¾ipœ•ºn9²Ë,¼,ÑX¡t_ðy¢¹¬FX¼,vvvS6³iX²ðÞ5w%Ñ=wt}§Ø}ŒÞËfæFNȲ#ÇÂ�VJU*(“Œ}“ù‘_ò‰ü©Èsl±²ÍÌZ’FŸÊš#ób×f¶ª–8/ }ðõšðKÑb(¡QEPÑE#®}QfÿÊ,²Ëe–&Y¹�ŠÍ]±š2‡±‰r¢Š(¢Š+^�æõàn‡;áB\¨k‚“>Ã~,²Í‘e�™±‰z•’ÕžœöÈÔTùÁz¢†3á¯ÿY9ÇO¹¿5¾¢nr}ñ||?8,,m+¢³²8ep®Rõ„?#çñúÑhû"¿OºÙþDò`•¦•¦/•¦“¦“¦‘§ýŸäé¯Óü­4kü…>�ð�Y|:(¢ŠáEpï—*¾5ÎðòݱC,ÿúZËt± SÌÆ@×øëUšn<,¶2 ƒ´@g_¤¾dcÓ'77o ‹à¸þpXHK-M¤F„,Þç/XHcÂð¾˜M¨º>É™~ZÄxY~+……О%èx¬¥š6›JRÃ=‰ŠToCŸô^#ÚÄñ¸Z”}¨r¼E|ÍE'µÓqö!ãa8Ñ ý4šh€Çå^E p¢†„¸·•šy²JÖ4É/æ¹Ùxìì¦mfÓi°ÚW–^l²Ë,²ñe—ÂB\ÍÜʉT6Ye𱱬zÃ;;Ξ%ì||�o­ôøÿÿ9)®Éü8¾âKãj/šö‹C¦lf‚i�x|ì¾vYe–Ybb,¼2³PÝeçQvPÊ+4QCEQEV(¢�¦Ãj)x,²øYeò¢Š(®l^°ú7"Ëä°Êð$Q%BÆãqbxÓĽæñ%Kã9jn–>Vµ¤}šq�føÞÓjc„bØý&Ô.žÎÒ³Ey—±,I�x~ñ""Ë 9t?Y¬Ê65Ll²Ë,¼·Áðü#ᢊ(¢�¦Ò†±ce������âü,^±©‹¡L²Ç*!+Êe ÷„²ŠËìj±(á1†%ï5ˆ.³Ù><7Ëì‘)mV|h9=ìÔn1´i¿¶‡ÿ®oM’YbëžÑ®à‡± l‡¼?úÄÈ‹/Œzô\Š|µä|?úÂC,ÜYg~=¥QExh¢ŠË5=”Q\c+Ä^°‡™FÏXœp�dpÉôn"ïá8oTȺGÊÿ�¦”vƆ­Qñà੟*µáº6<¤Q·�žÇ gó†ž&ñx¿öÄÈ‹Þ.l„¬Ek:ƒð?áXCFÓi^ ,±<¼Ùyìììì¶[5>C†¥[j¶Fv|½v§µMíìû£»hÅ�O|³èNð»Í”^"Ê+¼9 ^eÄ1xÔÄ! •&,µ}[UXB^I.–ž&ÎŽ‹èêñ*û„<¤"±Y'|5=�(~4"°¸Ñ\hÚm6‰ä²Ékì�3å«jhÕ�ÙAR>­úîLÔê=ã´÷HbÄ•±@Øl,q¬tR ë¬'CËE‹²„‹6”Ia«bÌålмEW$PÑE4DCñ^Ö_ <<îë,‰ûÅ.)—‡™Ÿ™±²Ë,l²Ë,²Äñ…æ±aó¢Š&¥ø}Ú°ìB{•šúq—r¤R¢_.ôKç¿ÃüÉ‹åά�ÎkÙ—Š^×»Âg²††…–o/ ���‘-OèDU /Å<2ðñÅÈR£ Ì•‡ÇH|¿ #Pò–Í‚£b6"]<êz?8>š .6_‚…—àÜn?dõ¡¦jë9²Rép�¢�ù>>«�³EB'ïØ (Öa†5ˆ¼µˆ1ãhÕbQñâ+”<.Tm+BÄøEòq¼¼<é |#ï‡é,%†ø£ydýçSÑ]p|kš!…ŠÅx(\óe›�ÄÿÙQþ5þ�ÓP>OɯõˆÝáúà½a£âG¡G¢±E]Ú™\lZ”-Rï ¼YG¡JÆPó!‘VĨBË$Å‹/ –[ÃÄs?|W)®péâpþ�¬¦meÑÙ{%›å¿£s7>ô~/ȈûÂ,¾$‹,²Ë73s7™|/=�£�Ÿ+ã¿hú§ýLÿ¡è·²—XíŸ-{/¢Ë/й2ŠÄ¼V$„ë9eâ®ð‹,±±‹ŠÃàÄ!bXf÷…šÅ’íað²È΄ï–%ëgé!�ˆÛРmE†5 èè¤t:::::::::£££¡¸\,¼_‚Bç|Z³j6›G¤™/‰?…ýâÉKQ~ZR”ˆF°‘GFän(Úm+ ŠÅÙ%…š$ˆÈnðä�çc"­á,Yc$,Ùe‹…añ…ÂÍÑe�ñ²øD|fºÍ�—yŽ_>ÊH¢Šú&,´,^OXœqßxBìe–Iá2Ë,¾„ž±/x–"!"¸êaø+Z,ÜYx®ðjz¡åð~¸~pŽ#è±HÜ[;(®WÍ—†2±y\«�ðY|"òú¼9e±¬ììJ„2+ ¼¤Q´¥”Ë,Ü9æ8²x–"!q¢\X¸ï7…„2ÍÅåózˆ””ˆÇ£i´Ú8›M¦ÑÇ¢Š(¢Š(Ž£y¹‘¹‘¹‘¸¶vmfÁô}ŒÞÍÄ;x\f…ëöZ- «ÊË/4(”QEr|ð‹àŠ+.<"Š(£i%XŒ|†7•B%ˆ‘÷‹,²Ë'ë‹Âš¯Âáxcç?xŒ†òø~p\žk†Ö(âÍæóy7ŠÆ—¼./ÑjûÊ÷”XÝ­–EqXXè܇3{.ðòø¹�•â#Í•xŠÍ–Y'o�än,´Z,ÜoC˜û(Qã5Ö\D¨‡¾4Q1e+µ¯ õ…É’ç?bÃó‚à°˜ÙcdSb�aº‹ÊGÔ}Hq¬i®±ùËÓÆ¯„Q1 ‹-2ÍÑ~'†èsþŽÞBS6ÙU›,~dù!޲â˜ãX•PøGÖ7Î~ñ×Î ‚ÇÖó_o-ÐÞ(ÚmÅ›‰¾±BÍ–^%�OY²>±68¶(Öl²ÅÙL¡¡¤zåEaãP\ ñâ…ÂYo;™¸Ün7�Æãyö2¼F\V\qB�rd½âñ XãEQE Öáœ]›X±EÑX¢Š(¡"Š(Hí]Bo%š(ž$%ˆób¡”Q¦úãXbб´nHÞ�ØdêÅèO‹ËÄÑ×ï…ˆ¼$5ep“ÅæËÅ—�DexLEV(£bX® ÒÄÙb#Å«¬8ezæ¼,²#fæneô[-–Ët^W5Ø•fO a"³2&£4ûx\ر5”脜³2Cćì¦Efq¶>¢iw•èl—o/Þ%É:Â*ÊÃ#–‰fRì¾V†Wv'‡ìc(\bï|bd�fn–,²òøÆT.ñ_‰’–$Æ""ç5Ázð/Ý,@yüà¸. 1õ™zÂÂã¨"^ȪBÅ”½ãUu˜+xdz,–Z?GìBDX�A¿õ4½âH�¢L±aû&Ëãû„'x¢ŠÃõ™vÊ/�P‘EFT'xR‚r¬7XxHоrV²‘ùà^ _xƒáùÁp\4×D½‘]ð~°½‹–¦*å…–Ëã!V±F’ÃÅ�å”4$,EšŠÊtiªx�‰"ÆÆn;-›�ÆãpõÛ= ²È‰X•x%Ó!è—†ü¥‘Å–Ye–&Ye‰–YbÔ4ýòý)ûÄ=á>r%ï~±}�+b°³#ð‡¼5bTK„‡ë÷¬J²…ß9,µcC/Çe›ˆê ß e²ø7C�ò„¼:ˆN‹±zãExµqÉÿó‹ÂำKŒ½øýbX|èXÔ÷ˆúÃË%ÐäÇ6˜»w‡è~�2Ňï„�Ìj,%ˆ,"°¸²ðÕe«$ŠÃ(¢¹EY±Z>´%ᔨ»à…âÔõ•ëÀ¼¸�‡…Áqf—¬EõËô~…èX~Üj¡ ¸|&nGB'ë2•!¾ˆHBÇï Ö&YdUæ*†^¡Jù5Y’¼>/Œz~Wï…a2/Ã?Y��x5q<. °¸mk\_¬@\cìxY²Ë,Z¶è¼¿xÔV…ï6XøM wˆ“C]…ú+³¤&1pdq5ÖXK ðnÄè²Ë,±÷ÁÄ¢Š(¢ŠÂÊÂEQFÓi´ÚIe¡"Š(¡t&'à—¬u\ï7ÁgT²±ÑÑÑÑÑÑÐŽ±ÑÑÑИûC4ù±>ôG+ ¼Ê_ƒôF6%Y–¶Wë7‡Áº7"jcOÖ(¢…¢ŠË#†6i¬Å²òŠ(¢Š% bËËÂY´Xˆéòšë2ö&_EÐ� ß9úþ®#ìy\ƒ{ª§ï“"è‹ÌýʆÇ!4{bUÂBã´K66ô_؈š˜Óô. œG�½æ(®+ûÕ6?x¬Y©òT]"'Qú%©?ìZ³þÍ/•(û!¨¦ŠÂ|&épüþ#ì£iBEŽ„†³CEbŠÄ=s–\V6•›,²Ë,±ûà½fHŽ%„Ä?d½æÅì¼^bX¬¼7E–tBW·Y‘dpŠæ¹KÞhùnP�ö3y¸Ünd5d� ]Ë)ÙX“ï‡çšðÉÒÂö<® ‹Ì³R5�>sˆÌMy{,±ˆ²ð� ’#š(D–6ápDÅì|³ËÛÆ£Í ¡;(¢…‰+àãÞW*"WûÂV%GÍ�é>z»nWˆâlfÌþp^MOX^Ç•áyƒ¦MZÄ|Ú±ŒEš|+�QEI¢Š(¢k�‰�À‰‹ß!b„Ycxm‹ï)ŒÓ—æ/”â. Š+ü*³yž ‹5»ƒD£Ù\¾.§æ¡ÌnðçÖ?�©ëWÁðßÖ¹ÍpÓõÂË,²Ë,ÜYeáô'ÆXXxBJá¹aÈ¥ÆX~ŠfÉ$SXD]â³e–]�¯éd�E2Š(š*ÉÍiÆÙ/—©©Ô£ OüÏ‘ ³Ã S"íaáðüá^MOE21Y´ÚÍ¥2Š(i”QCEQECœ×èX~Y}XÙcx^°Ê,o- ²~„_ï-�ƒ÷ÎqKuˆ¾m_ƒ¼vP–_%ÞͪROÑóôÿó7"ËGD³EÚÃÃÊñnCš>Ä}§Ú=FoeáÀø>zoœý]áfŠ(¢Š(¢Š(¢H�Xh¬ÇׇѸ²ËÍ„Q\FYcâ£fÑÆ¨•ŽAþa;ãEX�,²Ë,¾M×lœçòeQôié­(’Û¯‘©§±×(Ÿþpðü”Kß…1øÍ ”ðˆ{ÊòØÅì²ñy�Xû(¬YeˆÕ >2?!ñ^³()#×B5=÷‰*v"/²Ë,}�¢/QEQ\kޤwª4´Öš¤|Ýj[ñ4öÀùÚqöRBË"|ùÃóË߆$¸>ƒâ••Xƒë”�±ˆÓÊÅò²ù5سEb8Õ×Z~ÍÖYyyÚm¨û">,‰6Yyü(Ú#QÕôiûÃVA×XY¾B#†Iˆ²ËÍ–n/‹>‰ORä%GËw©F¯Ä¸ÜM­tǘ°üò÷…Åb(|E?’5÷ˆuÅú(b!…¸_ (£±bË,±‘,ùZOSQ2sZp¶|YÊ}²ñ|_oÁŠGY²ÍÄ»5hÓ]æK÷\ßL³qd±· Eø,Þ[dZ,k~±T�xAºdþ3CÒc‰št–(¢ŠñKÞFÒŽ„ѸL~‹-–6Y¹–[,²Ë/Y¦ðÄÈ»á/X–!ëY²Ë,¼QEÁáQ/dµ#¦®GùÚDua?G̶Ô6´4Ï�m·à—¡W/ÞTW ¢ô~’ôiûÂ] uÖEq’†z7�Þ,ÜnEâŠ= Þ(ÛˆèEKqf¯ûkÐôѯñ·z4¾=>Ä©aáøë«- —Áfø>ƒãFô3ðƒã°hÚ,%š(¢Š(¯ã3_Oì�ë¦)WhÓùVÖòPŽ­1š‘ÓVÍ-O±^+„�¿ Â|šÅt~’ôiûÄI"Q¼Eø§ˆæ�¦Ò²‹.ñ'xônÊ%Ò4ãz—–Pÿƒ/x^Áð~Î(‹âŅ㢊+ƒàÉc[þØÖ4¾CÒ>Ôá¹ NzîæB;"ÍØD�"?ظ®²ÄDyD°„ì²ìýxŽÂçd…Ùn'¬Ä“èX®—hŒ(eeñÓÒzŽ‘ÿ«²_WF¶žÎ¼/ ÈüŸœ¢Äø6,,Yfãq¸²üW‹/B>J­VnCŠ~‡õ45ž› Ô•¬Ð‘cvzñ"#åBÇî4ýâ/ füéŒ\èk2yÚm6•–IJðø|5ÙeŸ-[ð¼.YGEŸ…–n,ÜXÙe–6Ye–Ye‘ì}nïe‘åEg²Ù¹›�Æãqeó’èGÍ[gd¦™ �Ñ?ÿ‡Å×ïk5~ßü ?»ÿ1"†%â¬,ÑEfÈ»Çî ûÄrãŠð?gá¹$4$Q(Š&ÞMÙ\.ðÙe–|=uÿ,¤7ûf¾¥ú=øB‰H´n/‡áu—Áù4Ƭ}<"Ë,Q\¨¢Š(¬Ùe–Xž³çCt/6Ò�ùviKto-‰ H¯c^/Þ!ï …q®"zcÊàñe–7ÃvV[áE ‹¦OY³s/Ãeø8>ƒõà‰öeaafÍÅ–ZÍV(¢Š6”m6›M¥b»$·*5a²T)¶�"G•Ä�×D.¿Û(±Ê�ÖY|߃¢Ð™/x‡ýafË,²ù2#øYce—ɼV᧤æéû?É©ðo¸šš2‡¿â£óƒàø~x„!rè¤R(¢™ÙÙl³q¸Ü=QM2Ë/�ÊøûûCƒ^ÏÂñðåH¾4ÇS)��òbå´Úl"¨—¼Gþ°±Ef³e–^Z,²¼VY|lo„c¹Ññ´Vš%5jYf¶šš5t¶¿áí:è´Z-‹GXe¢ÑÖ:ÏGGGB:ÇB:¡;ðQ´ÚmfÖmeHÿcý‡¹›¢ÊfÒ¹jhFd¾þ?ÅgÆÓ¤/à¡çq¸Ün,²^ñû„ñeø¨® G¿5Žb|~�ÿ±LPe2™Lù:OÙ]’òí)"Ñy^¸>‡ç�pXX²ÍÆãq¹_òhKT9Ÿc¥Ÿa¼ÜnE–�æówQ´P´¢Š%ï¸_ÄNøWø69rGÇ[`&^5¿äÕöKÃE\‘ùÁø?< ‚ðÙy²Ù¹›Ù¼Ü‹,¼6nföo7¢Ö¬JTn7ÍÆâðñWÄ(Ù°Øm#ÆÍÅ–Y¸Ü5‰:��ù,²ÅÃu<ß'ÁÈoBΔwI"1¥‹¡2Ë5ÿä˜ü-åòGçÃó‡ç‘p±ð¢™O7Šâ‹yZR}¤}þ‡¦×²³ë?œ^b> Œx´n/É©ìÓxX¯ y~ȼ/ Ÿ ãñÿé ,Y¯.‰û…åòKû:£££¡ÑÑÑÑÑÑÑÑJŠGGGGGGBGGGGGXèègGB£B DØ¿£jþ‰|xKð—Ãþ‡ñf‡¦×²±EqÐø÷܅ס+þx´$WEV(ÚmÅm6Šö›JghÜn7›ÍæâË,Ÿb"ð™e–Y|Qe�ŠxO—‡šËá£-²Bše¢Ñe’šF´ìcõæFßìèoœ*ø~püð/ áñ¿ç‡î)1èAþø�Âþ™þ þÏð_ö?„×éþÍСܲ�“†_Î žð¢lW–K ÛÁ,к¾Wš+”³Þ,¼±ø‘ñ~Jÿ™‹£[Yš›±|:+û:Fì¼]¯ç‘x_ŠÝ—ŸßáB5ÿá�8,,AQ¡¬´%Y±Ø§Bï¾ë–»¨1áðüàŠÊ}ÿ QÂåauÂñE s|!Íáø>¸~y…ð~ ÿSãjì—|Þu5ã¦�]W7lyN‰gOÙ/X¼>�ÅŠB—™³Ùú_ÎË,Ün7qcþRâ¼=O‚ËômfÖmetQFÒŠ(ÚQµ”P‘L¦S(¦S(¢Š+ÁµçCå8tÈê)z,m›�–I¥Û5¾C“¨‘ÕÙÛd¤äíáðyÑíš¼®—¼(¶5C˜¦_‚ËÏçÅâü_�ÿ"Šæ³_ØŸô'ÃóÀ¸/ ,¶[,³²ñ§ë�…ªãè‡Ë—è¾\ò`KæH–´¥ìÝC•£²Ùe³³s…3s#"òØ¥fãq¹›‡#p‰>Ç#qÙm Fóq¸Ün7‹Ãe—Ñe–"ËE–†Î‹FâË- ±gGGC£¬u澫�çñ⎋Ìx~y>ƒã¦­çW×hèïdt£GÊQ‹¨å1âˆÆ±¨‡Á:Fñ̲</xÞðÈûÄò 4Dý6±â¬¢~±ùÁeáæìü฿ýñÑÒ/ŒpñùÁp\…ð|¦ûί®øš�Ñ­¬ ‰=ÎÊã}‹ƒõÁzá—¾Ñfæ1è²R¶D†&°™¸“¼~ +ßÃó Öà¼ßñ_�#oö]zÂãEQøQE QBC²ŠcY¡ð|Á: #MÔ�I7.MÞ,—±ð^¸C‚%ïƒõÁz,o‹‡Æ¬üá^e”~p\_â²Ëç|Љx7\VhôD|o —„Ye–[-–Yle–ÍÃfãqe–Ye–)4}ŒÜÙe–&Ye—‹,´6n7›†ú,´Yj‹E¢Ñ?Ô¸—8’«.%ĸ�¢â©þ§GC¡P¨³££¡ÑhèèiQH¤t*)ŠC¢‘H¢º(¢„�¥Q´¢Š(¢Š(h¢Š(¬QO�ãð¢™ß"Y¯(I#ß³a‡Íe‹Âø?à./„¸~p^‡˜ûà‰{àø~aA³ëGï‚�½˜ûÃó‚ö_�áø¯?œˆ~ŸÂŽ�ÏÂ1±®º"<>+°¸±eûàø?\?8.âø>œ®÷Á÷Áúà¢(ÖZ³|?0°½ðcW® ¸·åüÂÂá,5…Åchº]eˆÜGý„¨K+‚(k ’EV”‡ë‡à²°•’ƒ‰™±Ÿ[6±®ø>œ+ѓ잛‰Yµ ,lBŠ6¢J±D`W�¬ØÍ†ÃoYü#!éÊ�­ ß•Å.Ϩú‘(\—! "9fÞJ'¬/CÃÃ肤~ôn,±™e‰�âÄË,²ñFᑃfÔ}i“ÓH—GHü? /*-e"£Q~Bá(Љ²Ç§GGGáõ‹NϤú¨úÍ„ ±ìqKÐù?Bˆ£‡Çß8Š�‘�aŠ=›Yµ›UXâmfÖmbE2˜¢F5†2Q(¢„Š|_ÀXBáÙgEtW9Ò íŸ¥uÁq\—²�Ü_XLÕ�V>É3ó£ÿ£h´›>’¨ØCOûÖ:)ࢲžX£q¹1�žÜ¾ÏCxI–ÛÆáHrú8¿dcfÔ}d—a´\(¡Ä•ÄÜÍÌLÜÍ̶[-›™eônfãqgfÙdvYe–X„ŠäøÄj°½EXúô6F_Ùf�îÃép¤ñèm‹‹RqТ4ê�ŒØÏ­šp¯c•ÏbÃ)b‡_œ+ÅPãfÂ�Cì^V¬¬_�¼'šÅp¤lk4P°¸MZÊÎÖŦKÞl£ó 684$AwšLPPôÍ´$/Åâ>Ê´1!ºËeF=�m+ ¡‘6›0‘°ÚŠ+J+Žæ‹¿±÷…–4&,1 òxX¼#ê�ÕaI‹²ÆÇ4^_š—®/„|‘=…߈£oêáEQèSX®uÁpx‰\b¬—K'ŠÅ2™›Årz²eÞ,üˈÕà³ÙC…e:7>/‚,¼¤>Kn-ò|’6”VWÚk5„>¸_� 6l+jáB€‘éx\,Q®šáßï-¥bø.‰¾ì¬Yìj¸PÅá²ÞWE±!Ä¡²ÅšÌ1(�s|(¯‹."ë‹ð&náEafŠÅ󮢸¯yjÑõ#ê6ÑY|Ó¡¾šÃÍø—Š# öt³x’µ„mfÑøR²J‹Í1@QH’(®/) VV=—›Å…ÅðõŠÂw�¢ƒd£\¬÷Ír®uÊËÍòqàù_ðeø_ƈ¢†X¤‡#q¹æÙ¹—…Æ�¤zÃÓCö%Ëi°j¹u‹,¬úþàºÂw‰û þ cb�:þ Y~‡Ír¼®ã§„GÙdå|oŠ÷š+�–oÅâËfæ!ÈnøWʼnð\/’à¸DŠ¢ÍBÿŒ�awá^ ÍwÎüT>Wà\’¬QiWÂÇâK6Yx²ø²…Š(¡²ù¡‰qo4<< ‚cš#$JWÆŠå^+ÂóÙx¬¯åPüIâÅü·à^°¤�ÚfÓo�ó•p¬Õ¢™EbŠÍø*¼ÝÉ>wÆò‡Í<.I¼·Å X\+…âËãY¢¼k Œ‡/ë)Ñ~$Ë+;‹7–«lJ‰l³h¼O •”V,¾�q²ðŠÑEƸ'‹óÑXx\žhe‘Žâ¨bCèX¢ñý�¡ð^D_‚ùî^Vù¤Ñ}‹=�Ѽnñ~$°ù'†2²¼7ã¼2ñ|h|,¾›Eåâ¸>/ÝFâÎËþÊ+fÒ¸Ö+5–ü(y¾u›b�߃ÐÝðXFÿèÜ9žüU›,¼,>iñ¡a𢼵Á S)¯àYeóyHe•B‘´¬n#l¢9£hãÎ…Ñ.ó^$<(”øË4VW�Q\¤…àŽo1VUaèÓS|>Ór7&,&ŽŽ°¸_³|k- pE—‡ŽËhS73s†ù&°°£cÓ¬Q·ƒÂx¬(ØàЗ�åpCçc¨Ý~Šá6"ðŠ+Ά¼�g®9421ÍqxCE4!ð\^/+yY^Åa+ÌÖo‚BXhXXqýù>kÉbÃEx+pø,¿,PÍÅð³v,qÃG¿ ÿÄ2! 1"A02@QaBP#3R`Cq�ÿÚ?‡mþ"Q_Yó­vy6—¥è»|~ FûWeEþ‚õEúµõ£ù>�­›‹(­(¯ ¿Ë/F‹½y+KÒµqcÙEôk[úöYz=h¢»%ؘ„KÇÔK^ G} ”¾í/ê·Ýeée–_Ñð]œ?'qeiE"ŠÑ‘Õ3q'zRï®Ë,½(­l²Ë,²ô²Ë7�Å–Y¸²Ë‹e–YÁÁÑ"´M.ê(_Cvª¿¢þ…ëEô/¶\j�Ñ_‡eézm÷ PÓÓÈíظÖû- "7"µOKÒÖ·¥�öÙzyì§«eprr{†„«NOqÉLØÍ¥M¤Qh½'ø«(®ì^šû{>KúÔWeQFÒ„Š+WÉ´‘e÷ßÑ¢Š(­w£Õ7Ži�"Dz†äz„¤z‡¨Ç&ÄèÞËe½(H‹Õ´cÓiZHZí6›M¨¢«J”Š6”WÐh¢Š(¢„QzQ]éKÒõ¢*‰ø ÷jÑZðaÇ(¾HxÕ«6ö?¦¾�w¯:¾ÛìÚm(Q6›QÁEiE¤–›D‘HØl6hQ³i.ÚôZFÍæäÇ$†ÄKK7=eÈ–·õ(­<Ç�õ âº(KJìäKOeöXõ]•ÛfEÁ�s¥÷aȦ©ž Æãz7‰ßç.Ê+Zú´SL¶'§QÀ«F‘HÚ„’88e#‚‘¶'¥¥iemKTQEÛZPµ²Ë/è4N5¬ö7ɼNÊ䯡Ek]­Ð¥zY6"Ë)-/[,NÌQæÊ6�V‘]ÔWæQ]Ô.û›‹9,¾ÇÙEM¦ÓiµãÁ{h¡ÇD_eiZÖ–YLÚQCBzm+Z(’²\SÚ,¬õê—z-Ý›ÍÆáHæÈºòn7Y¸Ün72Ùl«›Y·KÑ­V´3o<«Vm+ñ«ñkè7E—£G‚´„,–•�V•¥�’†Ñ1±2Ç#Ζ)¥›�Ç$d^—£‹b�jØä.M…kz­-ézÙdÒfÔQEm(¢Š(¢´Üo71s¢ä­6•ú'íÑBz±1‹U¥–%«ìB¿ÍÚWg�/[ZÙ}õ¥›l� “䢅hÜÙ;²ËÖ*_‹~JîåŽFâËÖŠ+ZÖG"‡ìCÕö|ézYä²S,EÜõ­,|詪�ô^t—>KÑ¡=ˆo‘v½9.¼—Ù_N„è¾ÖÙïè=bû(ªÓj(¢¾£eù(H­(še“‘¨S:UŠ%R7 VXÕ›D†mÑ1!ê»7›‡#ÕFë,Ü^¨^t½+IË�=]Ž]Õ¢tHÚÄQFÓbtH¢Zù)m6‰ r.ÄôòËÒ…«î¡wV—­–q®îÇZ$-làe} sÓw:%�‚\:ÙeX ØáCZ"‘E1=,hKW¥裥¢ÑäfL�À¦92Vü‘�´CöySÉéŠI”Q]“.‹b�ò4P–¯MÃ<÷=/¶ôÝ­j»½+±ýÇпÀ­ZhL±Jb/µ¢»á-®ÇÔ69܈±BÅ� ‚Îéß�Á”m+GÛZøì²ô}‰“É\ª³$·2+ä|Š-•B%$-¤ÖãÓ¦Eáòz±Dr¢ËÑð|œ;#ZPù#lJŽ hQcEvÑÉLÚmeͬ¦S¡hìWòYt]é�ãÇu›�Åèÿèõ¡*ÖËìZWÒ| EòP¢F"´neˆàÞ’%•!Îü¶PâÇÇ9#ý–QLÚÊ6”QFÓhÐÚ�‘äˆòÃözñø2eLõ"¹!(Ø¡g¦m(H�E’Éý¯éοCÎ,îùdsDþJýêÑ�©«E Ól�³*g¼÷�yê3{#6zŒõ½›Ù½‹%‰ê—Õ’¾Ç£,JÆø"ô®ç¥²ô²Ë/èße—Û]•«ìQú4m6”Q�§õ �?¦l#Ó9‹¥£ÑHqFË=3hâ�I‚?Ž�E!a‰éDôâŽTnmŽ<ž w*bãE6éÕ²2<›Hã–OµÄʹ¢\2Γ«+~¨ê°ï‡�y8:üˆëNŸ«xeýòG"ÝÚìÎGHãý‰Wâ¡D†3j$‰#Ód¡C´Û¤G$‹LŒ/ò«Z(¯¥Ekzu®£¢(ŒEŠ"¹(£“$䙦H�VÅÕ!g‹B’~Ùe{]�Ëi–Ôxì£ÁzO"‡’}Fáå=c~âòp‡–¼?Qê*z#íc_&l *?�–Ì_ñés6F**–�t6Îôè£XÄm2ô‘Èø×~LXV%Hº:œ›¦QÐâpŽæG,eàzî#+Ñ™„GžÎJÖŠ(¯©*ؚџ%#*THŶ2´”µÇ?�oO%jÿ ŠfÓi´ÚlFÔR=¥£q¸Þn7ÙÖ»à¡@HQ6›M¢ˆâm6›L‘ ¬\í7QÓÍìõº!Ôü1æM=PÞ¹úµ"K$²2c�é±b¢1dÝ ¶(6B90åݤ•ùq-kÿ!VlgL¿ëB,²Æu3® +‘ÒôÛÝ¿SÔ„H¶Ÿ ÇÖ8ñ2=V9|–Ÿ†Wö.>t‘‘p(‘ÓiZ9DM?=h¢Šú\ˆéÝéþExC1. ¤ªŽ>IvI–%bˆ‹Ñ~FË,Ün7=£Ô�ìõ¡û=h~ÏZ'«Õ‰êÄõ"oG©ÙêEü›âIb—“ÒÂ?‹øËöû?Œ< ×Àæ‘êDõ"zˆ”Ѿ?£|Cšý•x=Eú:i\Fýéi<Š>O] wàRÕk�µhò;!&zŒS“kÉ&ìÞÉÉØ›£uÈÈe”‘ƒ2Ȭd�YÉ€�ò„ïOù·N—ÿ%Ùr£6MÓ%÷ËQŲÙÑ`¿û$u9T¥í=)mÜo’ðC&I:Lÿ²äÅ=ÊÆÇÊ6�‡ïIdPòdëøž´äEܹ"Ò\¢‹/²ŠïDV™$tòä�ß»N¡ð3þ$|íbó­”WáÄ–’ÉùQõCêXó6o7›�ìÞ9³{7³ÕcÊz„2•›m€‹=C×?�%ÈD²Áù$±¿ö‘’d’)Q^ÒŽ“äú-:¶Y ¸òˆgŒ¼›�äó$Œ9÷ðôjΣɾ B¨DçdQ(’i!Í£Éþ ¾“1ÍM Ë‹åiƒ&×É(»:åìÓæ´½zÌ´¨ù�0âõ%´êòl�§ß$޳"„V4`JS¦f^ŽN ÿöãY"tyÅ脆ÌÙÔ<Ý>XȽ7³s#–Qù#ÖWÜC4gà²ô¿¡�[ ‰ºD�˜]L‘'ïÓ¨c0<;c’‘kñâKÎ�Lžâ-±A³Ñ=4m‰í-‹ÊÑŒ³x²pzŒõ½‘‘lääVJì¶[,œ�#{=FFVŽ�'“ÿÙ§VùìshÞË®L9w­:¼[ãeé´‹"¨Ë’˜íŒGø��'Pàé‰îC3á®V˜³82R\Twce•E#&Mˆõâ×$2)>èê'¾Bò:²Ìyv;D²nå�^çðgžùYm•�\ÔÚ’:,¾q¿’Þ,„%¹^½FMQ,–ힺª–^›MÛ|:߉žP§\=﹃4´ƒ¦2Oß§Pù‡É3þ›²1±ör%ø‘òKÎ�WÜBI©ê2ج¢Š(h£k61À”G¤|IER8=¢q�ì+²é£OHôˆô«$-7ØÌ?õÉÙ8¶ü›Ô0mLÅ|�Nxµµ*÷ùݦus#ÓÊBèÅÒ"}-“éöy6Ĩ§O‘/n�N%’$"“�q‰ÓeƒTl‹|�D9â‰äLiy#M§å7ôF|ÚF ›�ÉÃr&¶¿gµØ�«×>_q…og„u·HÞÅ6nfönc“7Fö)²2=F,­;0eÞ¬ÏÑ2&„õG,qhEŒlQÓuâ̱ùF»øÕötþà›ç_U(Qò?´—‘�òI�–ÙY’JHd!fÔ‘zDq(Bü4GÉ6YÕÍ–Ë,Üo73se³“‘¡¶112Ëe‘fãy¼S#8_¸ô±M{IÃk£§œ£ÄIâ“ä�G9y#ÐÅy?‹øÐðK¡‹!Ò¼r±.t¥ÙV5|c¶Zˆ�§¾:u¶ÎÐ�vBTÌ9·¢K|L±p• гI̸·Æ‡‹kä´¼2ÔˆNôÍ‹y(Ñ�>γAü™z�ˆžY‚buYvƆô‰ò.šmY(¸ùÕÐÖ‘FÖQÓdÙ.EÊ:ÜUÊž�ŽçHÃÓFÍÓoðK¡kÁ(8ùÓqdYÓfõ#É(ús´'dGÙÓødüµý…6zr!…U“ñ¬1Ù[Iä¬uò)þÇ6nfâ?†…äž�gÜ"ÎJ6›Jí±³wz"%kÑh¤(‡"¿ƒO’~LXT—c,òIPú•t>­ü!õL}Ki3¥›n˜Î§î(Ž)J<éÉ�ÇãIGr:˜m–‘f ›Yuxw-È£ÁÓõU1;:Üä„È:d:‰.›¨õ8zfÅ|“޽>=Îˤu7ËN³¾tEQÔ5»Gàc##y¼ÜΗ&ø™¡½Q—Ñ-:[ÝÙÔbRVMRÖˆ˜szr%S�˜eð&>Î�óD—óÙ›ä¥C2HƒnFeZc…ò^Òy\Ÿb‚‘FÒˆö?Áž�oÜ&n7‹g'%2µlløÕð"‘µ ô‘鋃³ù5â&L�#:n•}Ïè£+às÷’—%–o:IÛC%Š2vÅ®Údú8dvÌŸñѯi<2ÆééÓÊÖÖUªgQ�Ó�•‹´ÃÔ({YÄÕGNñÌ‚¡ÈÇ)FVŒrÝÓ:­¶B;UVJ�zÅrtx«Üd–Ø’äÚ8ð4=1ÄQED¤t’©V�f?’è³¢�c²VŒÊ’Õ"´èrîŽÑûe£°–×b’hÍŠùE=)é9V1Í–bûŽ¡‹–RŒIÊû"FÓi]¯ðeãN±{�¢�Hà´nGºR¢=ÿ&.—ü|£ÐÇú= _£ÐÅú= _¡tøŸÁü|£øøÿGñáú?�ø°?‹ø±?ЇÓgñäz36I;0d♹¤Mñ/»3[Yµî9YéKôzr9ŽdËì±äHLÜn½:Ì[•žŸ$=²ÜEîVŽ«©cQù¸Ž?ÙÒæ¯kf\~¬G�l©‹“¤Ì=s!*•¦R:|_ä7J̲SlÚ¿fØþÅáé�#©È¼ÓÚ=´=¤¶¢‘ÁÁ†IMã“:N$Úý £ö!’’Š?’÷ Vަ¢9Íå·§M“dÉø²µ£ìÅ›o’3Œ¼‡²>L¹“ái“ÿ=qýÆsÜe�Ç�ö>9ì±ÌÜôŒµƒþ'XÒ��éäÚ†‘Áí?’>¤yOTõTslèåÏu–WТ¥û¦�ZKàY“ò,°ý™2Æ(Ë*Çb“ÜN|›ÛðGiø#ÐÍýÌ]$#Ëcê1Çä—]à—^þü™Ê,y%û›yÕY¶ùf<Û_&uq92=§GžžÖy:¬[d%Pšå.mñ:Ž›ÔvŒx#�Ɠ˙3¹f8o• R£«Ë^Õ¢FÑ$t˜íî$ö£#ÜͦÓe¢XÙ. "ÙzY�û‘?´È®&UÉ&/´gS/�0»‰×!½cfÆÅŒot j´}¶z’o\¯Øµ^LúC?ÃÉÅшñ¥ k_à¯uÞE#yêÍæâËî¾—&Ù—¯Y7ÁêÈõ$aË-èLfIìQd‰}�NgŽ\Î#Ö¯’ã"¡"]5»GT뇤ßî³ø¸£Ì�S?ºßþ(—S‘™¥&�ôD_µ’dDˆG’Hè²Z¦O˜™%µ“æ�õà麫U"if‡“I¡¡2¸H„·-2Ýp6ôf {’{“““½È&Ýa±QÖd¥E³’Ù¹¤zŒ”¬²2,½0ÇtÒ%ú2q*ä�“Ú3©|éÓ?iÕÆâ1h¤zƒ›:î…Cú*g£6CÅG¤7 ФtÝE=¬»Ó¨Å\­0bÜ÷=:¬»žÔK„D¡#¤ÅÎæ#¨÷HÚzlô˜áÀÐô‚ìè°×½žYÕN•b|�;¸!�GݧHÌÿi9r9-)ŸñÏ–µz>Ø+tGV›‘)£$Ñê³ÔæÏQ3Èñ¡Æµ‰ZV•Øÿ:˜n‰é1`dp ýÇ‘ügû?‹‘tÐ/ƒbýJì½$éer,O“·@ÅÃh’´K†=0}ë^«îŒ²ÍÿeÉ‘»9(ÚMpŠG?IJ:c\Œé¸˜¼f;V‰DðbÃ,¯ƒOH”w*dú}’£kd"¢tùïÚÏ$£¹Q, JˆGj£<öDŠæÙ•Ûb‹1ÇdhË-±2JM‹r7LÝ3– &½¨XåðG¦Ë/�t~Yøô¼³ø8¿GS‚þÑjÇD*Ì~;KÉ“¨¯ »üéÖbÚíƒä|±{L]K„¹­Z:¼»#Cv2ŠYÓcÙ j<érÉØºIÙüV>šCÁ“ô<3£ÐÉúK‘üèr2yd:hD”Ô&N±/´ÉžR$ø,±³¢ÉS£Ê$­Q<2Oƒ=ˆê�@“,Be›�øõÍöbż—J¾ a”~�ÏÑ�zÑþ›‹,ÇŽS!…GIMGÉ<íø½(’%Óîù?ŠŒ˜\4é•Dn‘’[§¢Õñ!{ñ�ðuK‹Ÿ$|iÖq#yÙIòzg§&G¦Èþâddz)|ŸÂ_"èñ¢8!ðl®Ü’¹JÇO Âøä—’}R_i<²—’ÌsÛÉnVd†øÑ88ºf5Èô’1õ2ÇÁ“&þXê�&ÑGƒ r•ñõrÃ|h•§OGãVctìÃÕÆ\vu²¨ ¡!m?ãáP±–YƒìÒ‰àŒ‰ãpbòeŒxíùú)w­à®I`’W®;¹bU¦\» IËλ¨Ü6FJN‘´ê¢WÀú‰Xº¦/ú?—ýÊT-Ìþ�勪fûøzu�=ûÖ�Æ­Bµàéú…5OIIGÉÔgߥ8ÙÓCl&èŽFÝ£¥Ÿ¶‹,²qRFH8>ïŸÀZ?Á‹§dó-ºbǹ‘T´œö«%&ßdò¨™:™¿sgC§RF-½:Çð(Ð�‘FÓiÒðè®I«D‘3 ­Wdæ ­�«çƒÖrùÉO�"óä”7 $m�ì�Q¨Œ”_ „”–¹¶ïv{m¾ l.&*Û§SÕžÓØ{m I3÷¡«àÉ�A•Ó‹2ÒàI3…c”HäQ=R>þ pÛÓ¨žØ›�Æãq¼Ün,eاL×z'S�ǘ’“G¨ÍìÞÄÛ71d’ð.·"'ÕÎCœ™lÜÅ&rrtðsšBáòR7´Äí,¹®Ü�SD¢â鈖z1yü'øiYŠ5ižvë[:ޝüb9¶^ŸñþI߸À®ZuÝ1ðõ±2~L3Û4=3*bÒ3qvŒ9üèÝ+gS—Ô1ù «EI ¤nD¥ä|±ÖÔBm!+cÈñ´F[•­:¯ý‘‡ˆ’ó¦'ì"íþÞÅöéƒ.×Zu÷+%‘ǃÔ7Vfñ¬dtXïÞõê2n–�ÏcáL±iŽ{Y nCVu];�(zÄ£i´h²ôDV�«s$èÍ;zCí1y>ÙŸågƒù Ɔ1yúÌCÑþ_"ÒN‘'o^¯6ÕµvÿÇù$f~ã¥�d–ØØ–éûŠ+N ¡y¸^�Jæû1Gltê²ÿˆÙ‡´He Åq% %ö¢6c\™™Ñe¿cÓ¬ÿÐB—„Ms¦/üÌ/ÚeWð-"øzôù7*Ó«ÁµÞ‹LžCGO‡Õ�ŠŠ¥¦|›"1Ée–_ðIßn»Y)xT•3©é6û¢mQi‘eéµX7O½Û<òWzb~Ä@��ézç†×«ŸÂ�Zá�G\¿nŸ3Ïtï·þ=p3/Þb�Dë'Q¡:/žÊ'çNš[±‹ÁÔ«ZáŽéé'µY/s³o&=$+¹:>£ îÉ}¦/|™|Û‹m._R<�|}öF%{ŒžtÁÿ™Ó;‰/O:¯ô¸ßݤ঩™à¡:Bàsø7ŽGM&²*ר“”Š,}”èÚÍ¥ ÉHzbͰ„Ô�Ìý%óq®ÈÙ(¸:Ó‘±èŽ“™¨ªF\›Q9îzá�(îz>ÏhîZ±yüøX"¶“òA[#Â×'Û£ûLΠûºìÒ¯&�l®TSÙ3a°Ú5ÉGFøhFEq‘ÓÃçN©ûiÅhx,ÇŠ�M›ŒôÚ$™‚?,zu}?ÌLQhÚìœ[D`Õ� «³¬…²ù6rN ±c£ ë:^-i–ãa±~Å‘HŇ{­2fQgQ9XáýžŸöl_±B?³dgN¢²&ÙKL¸”ÉBŸ%"‘±"T È´Z88=§´ö› cš�±zdà ù'Ñ%Ê6Æ>Q¾Éÿ[#�|Ƭx�MºMܘ⠩È‘–i—ƒ.F,n\"Ô5¢Š<£,vÈÀ¢ÑÔA/óø ð£�ÅV˜U²Š×øgø™þÆ[999-£¤ÿÈlÅÌÛàË‘¹lÆo£y¼Þ6;:I5:gÈÌœ=0/n�SntG‚(J‡ÎŽM‰JŒ?hôÍÐhV™òOÀ¼3§ÏéLê³,�‚ ‹vOÎ�#¸/kN¥{µK‚1Üéà «LÙ¶pd{¤C�V.�>åµ�LØTÐñ´Çä²ôøì]—¢mºŠá‘’—�%Ž2òK¤‹ð>�ŸÇš= ‘Á/’8"¼‰Q)¨™3XÝèŒq£6Ä—z:¨ü‰µà”›ò/ÀZ?Âéüê´ÎªBðeW|‰­lÃÆ4?ř嶞‘]²e˜²TÐôΪB1ªŽ�™¶JB“ ïD¯É$…L” ª$�+1e÷é‘TĹ&��‘ð&GÁ$×:t>1qŸN­|蕟KŠ–ç¦\‹l–G)Xß#/Ie–ÞQÓçYV¹qn&ª]ŸV‹KÓ?Qò þ$OâÀŽ%G&UYŸf?¸‡’> úJöèÅø ¹ýnŸ·©_$4eŽÙ´-W’Éh�2î)éÔÇäK‘x¸bª Kú"ßÈùhÉd~Ó¨u.˜¹Flw�P÷‰~I_i$—%‘ñŸN©q¥�<7½£ªÍêH‚¹FI0¼²£¨éaZ°ù1äxÝ£U–6µÏ‡z´4ÑOO�- ]�<öKê3+ä]‘òBgO“r­^—Z-:�³F…ø ðœZó§Oç· êâGȉx1ÆÑé?"€£FKðFKD§|OÂÓ¸£©u�†J\›ø»%>N*…L‘äØÎ•53¨ã"b:…q)³=‘Ó«Ïþ¦c‹²We1A³¦À±Gû2ãõ#Lž BTÏIž‹&zR0Jx¥b{•¡=3c¾P÷$mtzr=9 Í¬QfÖmf'qÓ$圪â"HþTÏåLþd¿GóèÛyähËbÆÏHô�LÙD|Ù†{yF<›—c�»ìÏöé6¶‹ÏÑ®õ£úðòdŠ”4Ã粆­Ù÷#$-S2V9UHr:~r!èø2Í6) ¤,†ò^X²sà–Zò‰ä³rý ÿGG+�(PçÆ’ðc7 bv6)‘¸œýô|SÓ§û®U#Ôg«"Y,Òb›iÌÛ%•Ý£0ä{‘Õ7Åwi&Κ ûž™òúq'–M‘”™ºV9;=ÇK÷H‹ÝΙáº<,׫23—ÉêHõ$t�U=²?½saÿ"M#wóyz«bÅ6z3174꡺<Ë8�s¥ëÒN§Bzgû„Ë,± Ã’¸0äqä„Ô×Rýº6/ÀZ?Àõ¥U¦'îîêñ‘ŽtÉ-ÇUƒÔV¼�5§D¯!-2:‰7Él|‘CˆâÅíVÍÖ‰2Ë:){šžÆG&Þ–ü ‘d–â‘/4>]û‘ðu~té¾Ã®û„ô‚$´DW$׸d8’gWöYÓ»‚Ñã¹ÑíTJ[U³>mò±ÊÄ'l~Lw9Q?jXâ%\2íiiÖáÚ÷"Å+ó­'Q~É5ê1mv�ŽÄbéÜü�Åêâ™ànɧrIÆWÛ�ÖD-:Ÿ¸DqÊ^ô’~EÒDþ,ItŸ¢Xe í²mde¹Zîê¥ðC Ÿ$àâé‘üø�á‹Çl¢¤©™pld8ÙÔô×îˆÕþ„´ê¥J†xÕÚE×É.J:IÖD>i‘h´>Ÿ!Óc³Ó‰/k£rzKîö³$½Âæ(êôé¾Ã¬­Ç ¢#0t>¢Ý#/Lñòd~âÈÊ™Ô{±YÑÿ碅Jôêrù‰.H£Á#tÎ’+ï0­ÍÍ™'±Y9_'O“r2AN4ÉcPtÈŬdâìÁ�dáë(©*fL[x6£j80bÜìJ»Z(êñ_(~_lIåiÕ.L==ó!EGÆ›Yµ”Qé+àª0dÛç»,·HÙES3Osà/ÄF7kºqRá™1l,‘›¦Såúyâ•ëÖKÜ�…�Õž›6Q'Èän,¾ôÆöÉ2\Å3¬øb›#”ŒÚly‡<£".Ρí˜òS#˜S·d¤›2¿q�œhê—`û·ï¨ŠDàt¯ØŽ©{lù2ùÑv£|V¹%¶6IÝé·HEY,6Ç�XÑíTuY9Ú?)ìbv¬ë1Z܈³q¸ÞnäYvNÌ9VXÞ¹ñïˆÕiotBi)(ù2u©x?™!eàŒ·+Ñòeǵ½h­0;‚ÑãMØŠ¡+P’)‚cT^˜rÚ¦^–gɵjÅþ—àW¯:õ º=XËç·¨iÌàSToChq¿&Äl‰²$ �±6ÄÛ Kž)Ã’ {m�ap:|ŠQGWJ™6¬†Ãl FMœ;OxÜJ䂨ÑÕ(îä¨Â;Fàt”áÁ�/O“ÙdÒ²£ú8_xÎ�Ôë^¦KÁ&¾¸þ‡8þ�Ñý Jü:R‘s²oj²R·c¢ÑÓe¾¬Í�A¾ Ñý£ú7/ѽ~‰OŸ«Ó‘ )«Zç�{‘êÿFªôÉ‘A[2õ;Ÿ�d¿‚21ýºõ-©�æönfê:Yn‚,³&e�rt¹ÞiQZÑ%¢“F,»¼èø2Ïtµdÿ 7JŒØöiÓ¾{ú�$ýÜŘóü1I=%àŸ2+�ѽmŠFÔzgIÄhÉm°K‘ÆÇ£^éW~DoDfkƒ¢�Æ´ô#{´ë>ñA¢gAö³?þl^I.J6ÙÓø£nÜ‹IKj³$¯–E®K‰ÁÀŸ$#²ÿHªGU:U¤¼iŽ[]�–ågQ�tãq|™<éÑõÖyZ5|ÁS¢*•iÔeÜô±HKä¿Ñê?Ù‡7Ã:ˆn�—ÙgBî'=ŠÙ›+É+?ãåY{ä¬kN�s§Q’•húy(îÑ‘ÿE†[dgW1º}ù¡¹'QòÑI£m_´�‘¾G"Ë$Ë7‰Kƒq¸Þt¹i�”e{eFò/“pät2ò‰ó#÷ Z8™càé²l��èÝD·L¢ˆ.Ipt†fû¹&¹�&Ouç¶hGS“üIrFM¬PöbÇ 1®tê'ºZ?zt¹kÚôêú}¯rM¨I*Î4èº�ëk•¦|•Á'Ψÿ9NN�¾Ÿ¸Å•d�Ù5¦ÓiGCöŒërŠ#:xíšb}óZB{Y.¡W¥¹Þ’ê.5£#þ�æ{vèŒn×~xí™>U˜DêeQ�,Úl6�°Øl> ŒØÍ¤8Vc{‘ÖB¥¤|ëÒ?p¾Ó7ÞÄÈ»<_�³Tãä�SfΜx.Äz2!Ã$Ùÿü™ÿóä›ääÚÌÛ4ζ<&Bõî'“w,ÝÉÍ̳¡�ÊôË*‰²Lô'ú=þ‡¼éLÅ=èÉ êŒ‰ÂTyy'fÄzhŠxÞäbɾ7Ùšw2^K,Lõ#³“ÔF‘Ôå¾ Ž>;f:’ÍÇG‘. Ëj²1–y�èñbælÏ“ø'ºß!ùÑö²?é°K㿪�È̱÷ $#«6ðFÓi´”J(­(ÚlBƨé¾Ú:¼[�Gû*dq'ò<+öa†Ùù#àê!ÿc6dU|Ÿÿ¤Òir<ØñÿbÇý›}¾M¿Ø¸æÉd¿’)_’P_³þ=SfUq£Ò_²pVTbKö'Ï“:ÝŒÁO‡5d`¿dRý›cû6¯Ùµ~ΖaªE=Sòg¢ͨéçµéÕàÝî6Çö$¿dÒ¿%Göm_²—ìéòú|YçIºD¶·ä¨ V1ì?ë=UUdœYí=¢hਔˆÒ%ÔnŽÖÈåPðz�#%�o“¡È¾ÒŠíd–�µ‘ú4QEù8eO¿©ûO ÈýĽ:©\‹,R7‰HÜn7ø7›Íâ—µ�NhêÀlO’2£qî1ø:ÅY_dü"È-ÂÄ,~ÑãJ1y?ã|³©–Ø¥™%È™ä¢üGKÃq3²2¨…rpX¹f5Q£?XñÊ‘üé˜:î=äzˆKÃ.ôê×c¹Ñ>�ÅZ:l—ícWÁÔáxä/$üéfãw´èóï�=:Ÿ°O�h¡ÄÚ�¨Ú�¨ÚV¯XEÉÒ1ãÇÒFåäÉ•çŸTºv›!-Êûç£ídÓ/$÷u/à˜ß&r™ÜÆ=l“Òô~4¢…k0{f™.bd…H„y6² Ü/_}öOÂ(ƒÚ,‚—´àÚ™éŠÉñ‹†Î¹û®IÇ‘’gJý”AíÍGVªVHÇó¯ƒÙlÏÎG¥ N,éçº Œê¾ÓÞ´œ)ÙnVuX}H›iÑ‘{Š(Ú5í0äxåf9©ÆÑž;áFÖ¤6n7‰LÜn,ä²Äôz៦÷³<®ÙÿƒüÙÖæÝ:?ãòIñß=k#øOð’±ªÓ »³JÝ™tË’n‘?61¢Š(’(£iµÑLääO†[F ªQ:µ¶F9r]3x¦cw¯^�?Ló['´­!ö²‹hõdr&3 †Üg]à�¼éc:yQŸÛ‘Hëcq±˜¡äô×ɰª¶b&ýæóxÝ�îHê¾Óߤã¹Q‚[^ǧU‹lìÉ䢊öéÐæ§µ�†uxö½È“äGM‹ÔflI½°Cé$Ñ>šQò†´H¡DôÙ±Ž%id9dºˆãÇQ%+gB¶â³[SÛ"ï•ØÉhûYô�:Fx|éŽTÅ$Ë,dÝD‘›ô#§\Ÿ´”YLiÙL¶r2�ŒØÇG¸÷ÿD|>?9mgQ êÈbä–'~…žŒŒ?j:èî�§#£Ÿ§‰¯’e–gY�E%ã—èÙ/ÑéKôFkdl�àÿDbÓ$ÌQÙަ.FƉ§fÙ~�­ü$E5GQ Ê̱݈ØÅq7Kô{Ê™9ÊQH”$äzr=)þ�B_££N¦3:¸˜"÷éfx4÷".ÑŸø“Å+=)œ�NFÙm£Ò�¡$ÌRõ!É(ï�2];LXŽŠ4è“PV.¦ RRðfé#“”OàéŠÍŒØÍ²lq³c=&üúþD0BÔáœ�¤zrN˜¿ëÀ]ÈÁ,‰ZðC:bšÕèûY£Uù};憭†&b•ögûFf´Ë0ý¦oF_%ó¥I2™î7Hõ%G«#Õ=AKƒ{7±Kv;#?q)»FzŒéep3c”ÕDþaÃ&?¸èÚIÉ�¼Ò:œ«u#y½Š^ÖnfùØ­³¤ƒžBù£¨ÍÍ#ÔdæìÜËe±É¨‰ïÆcwŒ›{…lVX¦)›¹=KÏ]®ÏþÈ�Á—í:wïÓ.g�1Äâb“Œ¶=:´ã#{7³pß´²ÙÒçp�2^lêñÚ´rŒ^9YG*%ÑAø#Ò¼k"åòd‚È©“éœYéHi¢Å"SvAK#¤aÀ±-%š1ò.¢ É�LÍžu°Qvb[0—É…¹1e®1¾öG¾ôÈùúOðbéž²¡éŠTÄïV”¸%ÓþŒ¸¾è‘TŒî‰Êô—’ÍÌÞ9›Íæá¿ig/^–WGÞIiGEö [YäjøfN•$öå†;Gf,RÊê&l^“¢2ö³qcf?¸é±úPÜÈ?næN[¤$É®D1!«‰Ó?mÕZ3­²1¡#iB\’ó¤À脽ñ> Ÿk:¿N·ÿC£Ïþ,É Ü¢.ÑÖcÝ+JÛÙÓÏÔ�rÚΣÉi ¸øVâ¹?›updrÂ^8©ª2FXÝ2LQ±Ãi/'G‡ÓŽçänŒ™Üø€°ñȢܪ(„vÆŽ¯†BVÌÒ¬ts. PôâCÜ÷hûÙ¢þ“üTbž��sE8ó¯VùÖ^{%Ù~ÒË,‹áéf í�ß¼zD蟔2 Ú^™°,¨ôZžÙ$0Æ¢Mï|‹ x˜â3¤Å¾fgâêØVˆ›/Gö�4½Ô‘Õª‘�ÉBãF¹'ähqhŒ7[d�‚^ ~�oþ„%µÙ‡&øé5hÈ©éH¥´J�¦Ó¢•JŒ�dìêñï�¢„‰"Š-£U(ù=™âN;]ÉlÁ�~J*Œ’–W¶>aÚlBIxHê%½˜øfL›¸0aÛËÜéj¼öÊ[G•ž£ ÿ þ4%D&2šðz‰y:ŒªK‚:u?qBC…ž™é³Ód Í¬¢ŠööEpô¢ˆrÉDÚ'GG/pÈ}¥ þË3aY4âéž¾¸”‘éîð`İÀ·IÍ�T÷J´ø&¹+DÉ?i�Ô¬ù:ÈZ³lh¢‘hÉ%fâRM•2üûIx:¿Nµ\ôÕÁ�ȤNTŒ‘äÚme{Jebu+3-г·Æ™šgZ|iZ%ä†IAðnräN†Ó:<ä>N"Oª„OæÄ—\þ u�Û#mÒ0tû}Ò%+á V«·#¶P‘? þ$båàqÛä³q ¦ägh–¹æ“7‡:SÕSÔ7¦\ °8ѰØ4$_ôo7�“±Éß�Íþ‡?èé²Ô×1r¨J‰"ȳ©ÇÆê1Ïù¢S÷Ø<ßÑêÿGM72sÝ-¨“P‰,œž§ôzŒœš73{7›ý§«Á n�™UÀÇ‘£Ô=aæ¡d&ùð'ýi“ŽDí&Cí…Ü´ê§Rðoþ�ÿÑ�¨¯$³!å_£Õ=AdâÏTõê1d1K~3öd£¬�-Èõ üx73y¼Þ9‘ÈÇ�õYÒf[hÍÖFÕÊG¨Ù¸Ün1ÆYņ8Ð݉$9ß’5Ég$ þ&Lœ×$•:×qä¢C3ýÚY&Ž (~Kfó´Þ)›‘)QµбÄÚN=²G˜˜å¶u«I‰r£4vʈý¯N›÷lœöªF(mVΧ>éQ¸½&$�¦ÑÇÚIÒ£§�F™tJ©5§:å»6ºY\r'\¾Ä3ÞôêŸý�J(mßeûK/Hù:9|RÛ;ý˜Š¦R(�ÄP‘B�ãÀâF(Ûlh¤béwrÈÁARÑý&¬P¡‘ü7ø–,òJ†ï±hôËÓI»CÅ^M„ lfÖr6é�Å—í7…3ÏPõT†NIeäõG1˜rn�"ß(Ç-ÊÆŠe±|jVa®w1sö[U"0ùfy×µƒÜC �ñífÖN ��>IX‰}£K+‰š5�»Ò�“/“ÜT�’'©˜~Ŧý�GÞÄQ´”]‰M¥:(­#äÁ=’:�û<:’�HÏ ³©Ei´k[#o„`ék™v=+²SQ%•¿ù +^HÍKFGðßå-µdºxHŸHþðä‰sFùn�ÿѾ?¢áúÊ*Ø¿“Ó1ã6�†Ò{‰AÙµ� -�:j\éŽU­iÖAIòC Ã�Ø•iŒŽ–X˜ÈÇwJ�g•Dž[,„ö²Ö�IrûâGðßú+,½8=§´¤> ÈÜ�ȱ#j6#a±›^Š-é—&ÓÖg«í³×=t<ç¨Ý���"8ò$6)•> £lÇdð.™|’é¿FlM21¥Øáð<0ñà>– þ$áÀþÒ@�ERÓ4¶d²Ü­±ú‘¢PqtÄ"]œQH¤myFaûÖ¯-J´”T•3& ’(¢„†™Óã®Hñ£tdÏú¯DF-È‚¥£&øïùÃ謾ƅýèͨ–Å &c…k½#ÔB™¸²É½È“%ŸáÙ�˜ü“Ÿ"”~FÖŠ;™‡ÉÂðB �Ù»’QSTÉãp6›_Ôê¾ã§�=:Œ[•‹‚É>ÏŽÄù˜Œ¹ë“™r|=3C|F«[äÅÎ�Ñ“%éBƒ~tß2# Õ™½Ñ=F…”õ¹´mlÚP¢G³6­s»×ÁŽ[•’ŽåL—GúcéòD÷/(¾tÌþGb<‰W{t97ɹęè³ÑbÄ%Z2?†ÿÐä+ðc繡¢‡‰1`äŽ*!E"ŒsÚÈ»EëC\”QCìòeÅò‡hÑ]¹‘”‹ù½2`Œ‰a”NE.P”¬D"Û1ãÛ¬�!»Ñ­0?Žõî˜ùú9<YK½‹ðßú¬¢kZú5Ù×{ì®Ü9¶ºfäÉJ…$ÄYk¹ö=2a¿Uô(Ûb�cÅ<þ9üb8KVèœ÷Çû=4O´„¨Y…� iêß7ïÒ®ÆèŽKu«á¿ômXãÇÖŠ¿¡e]ø²×‘S) ²Ë-6_k2ùúŒ²Ë,²Ë,”Ò%•²0¾t±aµ–n7Å�¡gý�$Z#:�¾´Õ¢1z±~ÿIC‰_Bõб/¨Ÿf<[¹%ÓW3R¬Ú¬q6”:îlÈïMޝè'«�{³cdqWkJJ‰AÅ÷^˜¥„Åøoý4×ÒQ±*ú1òQ]ÑÈÒ¡»ÕI£oÙ¼ÜXÕ²Š(h­Y¸œ‰1 ­£ú›M¦Óh¢W|•~Ia_â85«×ü&/Ãéå ®ÔˆÆ¼•e}éôF8ܼ WHÉÄY¿bšfîE1y³xäo7›Ç�s¯[úwôo»i´Ú8›"zq=("E/�Âbü7þ�赡Á±ŠUõWÓÅ¢f­ÚÇ—�ª�æóÔ=Cy¼²õ¯¯z_Ö£hÖ±_„Åøoý*픨²ù>£ñª!ICMë™W&Hlu¥XñÉkîtG‰Ô%þ…£i´_„ÅølBÿF»fˆÆÅÞÿ{.ô‹¦zÑ¢rÜïN�+ó¤%µØó–ïöÏñ¾ŸŸÇz.Ö/ô±–ÒY[ÿLû¨¯¬ÿˆýnŠúõÝEQ]Ô»(®Ú+±þ ’mx=Jò9 ÿ¦YïŸàü“•åo‘ù‹¿ÏÿA²ÿú ücÿ­Ùj\�EõÛ¿£Q;üg4'cz^—Ýz×Ò­¡I~ãwú­} ï±{ŒÎÝá}/£4ck[ÒÄôó£úM‘Ñ”QZ_бº7‹7"O[Ò_Q²Æþ½—¢_èÔ­,½|“öªD19;'4OžÆT¾›ð/:1hÈéZ_5Û¹ôloD´ä¶[,oV.ç¢ZÙ´ÚÄ/¤¸Ñ9 µk´hHZ¶Y}¶^�²ËüÇõX�ëZX‰ÆÊ¢^4^tZ[Z1}¬J†V¯K/EæËÒÉ1DØxˆ½-Šþ~³Fê7yúµ=kUÚ–�^·ßeöÖŒ_Jþ��NE£z^�µ}X­RÒÇ-.‹/�"ò?ªõ½(þ‡ç¹1¡è†V¯±zP†‹ÕÄðP�¢QC"ÇÚûoY²>{b»%Ûã¾G�,L}–n,L¾Ôõ²Ë¾ô3Éz^”m+K/¾´}ÍØä)vŸ%ézWÑlZ½lŽ’.Þ–6"Nˆòô¡­/KE¢OZÒûl¥­:£ÁzQ]–XŠ,R½Z)v®ÆQZ¶-.‹•¥3iK[Ñ‹±-7^¬ªÕó¢czX˜Ä×zì½,±;—m”5ÍèµZs­ö9„Æû7"ܵCàR%Øù »%Á}‹±±è×cw¥›‹(¡•¥ë=„õ¾ÅØÙeèᶆVŠG�/Uô+²ËÖÖ–n,¢Šì®ÖYgžÛä~Hðn7$È·¥–.JJ˜Êï£Æ‰êâ?ÖµZ>Å¥’�x9}±|èÇ#pŸÑnˆ»ì´9ŽCm‘zY}î#�§‚´eieèû|vyÒËÓpçB•‹Jìñ­öWbÖÄ>Ë¢õ­¨»BŠÕ½"yðWs"1”WrÒõZ>Û,E$m(ZQEh×m›‰rxF!¾æÍÅö³�h±²Ï=”WÓ]žt|i>G«ï®ûZIÐæCJÒµ¾ÊÖµº6¡ª7}6-—ð&=^œ”-”PâV´P»mhÇà¢*»h®Ç­—ÛEDÏ%QEh�—eöÞ”5ØËÑöÖ�±öI�é/©eý °¯¢ôE G¥ê×"î®Æ$P‹+’ËÕè••«B]�U¢²Ë)±*ì¢û/ºOZ(­(¢»c™¸²Ê+½¡DµKFÇ!h´Zlý.ÇØÑ±Ž,ŒhEéà»ï¿£fí+²†«H±ŠEiz¶7§�+±=+±vлlò/¢Ö«µ/¦»ßb_Aé´I£qKÁåˆbÕËU¢Òé–™z=,zQCîz]ý½©�YZÖ­izY´ðôbïqÒ©÷­/±jþ­-/WªeöV”V•¢à½l½+è½$(ëVWÒh®Ê(ÚV·z] Ù7Ñ»é­u^‹J+J(GÿÒŠÒË좄èòXÄÒ7#qã‘K²Q¾ú<­é®âÞ‹GÛbÖË�ô]èÝä—b%ý 1~ Ûñ¥wí}µÞÅß)|c'’´\›D¾š»šÒ$KÕé}ôŠíh½+M£‹B*Î (ç±v4Yz|’|ÒŠÕi}«J%¢Ñ@q­,½.�ÅëE²Ë,²Ë‰}„´e5­oZE è]‹¿i´Q<} ,²õ¢Š»Ü{loEØÙzßÒÝØîÈÈÜ�È´õ}�‘¡-?²¬ŽµfÒ¾ŠeèŠÑ èµl±ëeŠ]ö>HñôkOdtr/G¬t²ôZ>ÖG[/ºúî—ë,}õõ¨£ÇÓjÇlpÄ“—S‚BÿM$H´Š>F럜*r*R+“Š+r+V9a;³uT´Å˜¼É$ξX(Z¤ã¤»‰Íx–*ÉÊdÒ}š7aù$�Úæ›h“ —*á¼<\‰rBE óäMß —K JX\ŸB�Ü$‘[#gÎ,ÐD¨ð©st—4*x¼’Âdä' åL“ˆ—"ŋɓS—ByrÆ‹¤‰E>ÅasÂgRpr7dN"…nDùÈss(XÓ-a\±DΘ\¨×S±b[G^£¬ŸR¸Ia4æR†ð¥Ë TGDD[ ›³G6K éHMÉEaÉæ' Y(‘jåÜO>‡1>Dd’ ºL}z ÃÊæ^…zt.VQ.Ä­2PÕs;w$‰DêK „… 5ÁwÁΤ¡C�Ì΋–‹‰ÌN^e‘KŽµÂ¸×J*räÉA²n"7ÿ‘ ‚” œœ(dÞ©¿E)‹Ë:$î,ÉÍ—˜º±’1þ%QØ_Élbƒg¶œª·äb®Ö ¥/ÒÇJ¡¾O,v*Iár…`"�¿ºXuXXND¢±5èèQ"T-ò)9¦L”4“.VÄÊ.4ªw!!SòHV–$Pd¨páräâÞ'*t™Wb‰²©“åМ0¢”ð'£äXÊ¥ÓèºPÍb¤0ôb‰›´ç„°°¦n�æ9–æU“”ÄÕ¦’!Kä«©š•ˆ›J)w!¤™D*pÉj˜XäU%GÿÐŽ†ç �âŠÊØXY–X%ÄØ¶jY�Û²qopÓ¨üÔ¡r¤ðï†ôU.›7J¶Q!8’øâ×+3CÉ6æMXyY6æÙGCò£ˆœO'có")µr!{'—mFEÒ±õïrr(‘gðDŸÂ}NæéX¨U�áÛ ¼'^øÈ® †òH´Š”!…¾B$q›*BÿH¢ÙÍ.dQw%9Lvª> XµŠPŠ:a8qÝ…�õÂÆR}¥byIå'‘´.Xeå†õ�ÙÂs7**)éì9ãV°sO©YI®EÄçIãC‘RI–e}´‰$¨9ß¹;æ>ÇtMÈ­F¹x)7úb¢’}†ÞÎ#wfp#†É™$êI¹.¥"©D§27',7a›7®K ¢JQ\›C±ºÒ/  (“'+àáR8Eæý uÒè*J¤2t$2l›š'.xK¿ùQB½‘ÄÜæI’“™ÌšXT¡(¬&ïÔ«‘L%]%!ªK a9v?¤§Üª;•%…8ªÈJåg>cQ(Œ®“3I¶I¡Á~å0�ë<*ð® ’©^.xG*†Íí&™&f…É:ÍXÞÝ^Hdî8¹u7¢—Á=¦Ñü”þMÚ}Î#ޤ÷�ؤ~`¡Šyú’ŠoÈ÷I³z Š3ÃÔÊ­àåè¼¼¯vPI)w›,:ØMÕø'†J—ÙLhH†Ф*k™ê¨ÿ­ô8J©±2îDªNt'Œù•ÑWBJÊ>C�¥vS™4EÝœ(˜ð®3íƒ$¢yD§r}0”7;—©½BxM²D-Þø\«l�ኯ©+%dJåÜÊ·†U ;ÜXP®gcz)š8J2O®˜:e…0¹z•Â…NxѼy¥$Y²h±µûûHe‹+£†:–Š¡MMjˆTC�a*¨C Jzí�ÈYU¢øpÈe þ®¤Ÿ6IrÂ…0šs*ÎÅäNÃ[(}“‰á\Åâ7vžÎÝQWa¹1<ËÁÃ%Üÿ²Å§¦b†tÂÄð™:Ï c9GR¶¬‰“•;ž œE¦/ø&è‰No±»³—–oÆRm‘>ä¤K™k ¨º’B¤qâm—ìäS ‡FôŽ4J%$Niù?©FfXOgq} •+=2Æ“V7¸‰árýÉóêf‰¡´KÙ»bò/3±–U$#Àôw&hÔ\jçC.V>èË [çaþ39aDO‘b…d—r˜V‡ü‰'²è•VQ¡-Ù"‘!Ô­I;ª&¬ËL²öW/¼(šêN8·!HÜEHlæ71?’ŠR!‹>a>9óènËx“±#,JÅé–òþIÄМdI$ª_*)¯C“)”¡2EÑDŽ$:Ì’IC,Ä×BË dI iPr$ÊT7—¢j)Úªˆ”0¶C›vR%HXO–g„Ø—1¹j®òðJ 2þɪ™ó?jNÇ?�fRð^†g~bš(ç2'#uÂ’R+bp”±(±å›¡cŠG.O1ÌÝ*I:�ÊBN(iØœó £mÑòè&®Œ±X¤uFëût8©ÜŸ>ìEHc ¥�4ö,StëÐpÙ›ÔðUrgê“èN\ÌèÎ,r±du%œŸ>îÄ[ՙċ͖,*PÝYNEb;²ÜŠª£€á\ÝJ)³¸ê¤<íáFeJ¦ôb[?d9[ÌVë™A¢¼… ¬"I7 H§„Æ89:‰ÄÌ›..¦x¢™s¡NC‘{*ð¡Õè®xVØÐ®k%ØÙìÿTæ8¶JDâ)�a�³zó' 6¹ã¿!u¸ŠÂpª¡Gcù$Ž*’œ˜·–bÖ' 2NŒ“«(VžGýÈÍI2Po¾…hC2œ‰R¤+,‘-™¼ä×Ü­�ÇBRðRT+B.˜Ýü&ÜMwbiÐju'r'½ì»ôFRÆáÔ}|�,"BXïY†m J/’÷PÔY–Å&VÇBæl(wÃÉ#¶7�ß9–ùtÂB”NÚiL'´ÝFéAg¥&<е1.”eTŒ°« ¢•eÌC•É8½“Ì…Ï•>WîMݹ,s'2o aADÔ‰ò$¯„Ì�‰ŠGAu.U“.V¸ì÷^kè:9aZ—.7ShŠUC*è8JÖÕ‰\IreÎ)÷7ªÑÿØÝW�´&Ψ™,¬èd…¿“-feäweg>¥Vo$¨¼›ì¬Få‰ÌüɘŠE ?ÔJ)#6ïÃ)üèR^jWÑJ|Ч?gõ̳ð%Í E|Ÿ±W¹?àYr¹ó$Õ×$5´Rî>„õ¶VäÇÔÏ“3\ˆbû$šr2%',+….Thøœð¬#•Êá"eH�Ñ%ÄI™7̤ebÂB©š æ*ϰÞQå†ÜÇv�êªQ†P$,×èI:.¤•I´8§ro>FïÉ ‘J²ãÊ,ý ’$Pèn�Ã!変¬j¦p•BeQbe‰’„¢Eä‰/²'?cqDÛòJØæ›‰EZ'’IÙõw37Qí"ý\Žø[áR‘8ÖîÈÓ$ý™¥>XIµ˜”SLb_ÉF„Õ‰"t3bC…O/ro R^¤°r'FQÌ¡AÌ›Q$oL•pœQx3Xw�¤Ÿw2“3IæòqL¤Kä²ör…§n¢Ÿá\îÉÞ\Š®Â†N„Y”æ4|�2 ɺ’Á"#¹+7QÓæVèâq”J†æÂh}K H©Q4:T�¹�ŠBO Î] ¤á~I1a¸^¤Ùq8�ùSŠcÞ™GÜÚ¯ü‰J[£h“G4ÅGèÜNÝ ÎDí -œæN&.²+su§„Ä—;Š"gºQ”ù$êº�v…Oà¤ú2ØM§“œŒð©v<›¼‰Há~N½z8¢�E/8 lÄ¢R™ù�È܉Ȇ(%.Œ“ëaÅ"qCLlÊÅ2%³_É&ŒÔD~Ióä›3$9Ôr¡)w™U$R¥nÙ(“e”°¤æIÏÙ'bJämQ§Czk¸ßêG\iWØÍ¦Bn¦nἦ¹›°ºu&æ4uò*H—CÉ8ˆ¸¨ó_¶"CæŽÃp•¶ÁáúMÕìß^™4Tꇅ†Á[›¥g…¦VR ”†FñaKÑi.R¯ EÁj³-Eš)Ó¯‚·'!ÿhç9yêoØ“f^]MÕ¡ÍDMÁüŸÓ̼ò+eêPœ×‰ à ‡T]2Ç3fò¶áR¹™6›)âQTåùHü¤KðÏËevlÝI|‰)‘n«ʦRG"Å UU$¡…E�æ‡Í>Lá^‹,>>Š]H\·RöXy¬EÚ¤òÔstÁB„ÌÌÌà‘š-È ã#7®7ß Ã…¢ÈÍ DÚhâ¡Õ$ñœ˜ènÂÎnRe(¡›�Ê2k3s- ¼“&›$’7¬>‡úŽz!e¤°j¢èUËÉ-ž|¾qÍa/Òe‘<²*†¥"Ž…%$ —YœHãë…Zh”ô%‘±7 eT%%,jæ\¹vIôÂ…™+–ÆPÜ«(J1í#rG�¢W*ÏêDEk²�›°BMC^È…Çw¥h‚.p¼!Â/ü°’Š˜/Åé^0®ëC>˜¥de…ÌèEÓ1çá3m8U¡,JDá¶Õ#ý˜’%0sedqˆ¬ŸÆš`±”ð¹Ï”¼²QUõÓÂp¢Š¿Uh~1Rº'þŸqËž8T”JX¨ŸM �å.ˆœQJ¦ólàE•…JĈ �Ϩ©DK4+ÅN6þÄWe!*ñ_´‹ãOƈ¼i_F”ÅÅSbçÔšÁ4‰~˜jÏþ´r$ˆÕª"œÈûë8Z-�(W]pzoŠó¡èq1ÿèÓ¡UŠó¢z²Õc4+ŸìÐô¿:!Ñ+ÅÐ¥ ÆÎlág…!(‡;˱~–,º.±±gëàÞxóË2̳,·îpýË}Å&‘X×£Œãû{FI9³wßžp˜ÛdiX‡¨�¢çÿ¬ÊØÝ·Ó™Lq2±8Ž#Œ†NÒVr7“y/ƒS'¡}n~Žx5 W…ò¹Š§.g “Âä0Å)å’,X°èX±dr®]^Ž/°«RèäEä‰Ä)Úz(\¿"ì».Ç„I–ÂߤCtÂ,°“�È´ü”…`ñ±9·ÕZbœ3‰2–O XòFQ]V®x[U°¶,[ÉL›ˆ¹råÎ#ˆ»._ L«re"6�t�ïì¦fp?gåýÏˈiÍiäp£„ªûE° “¡Ärx=T+W‡Æ(Ȱé $…†V5Ìp²v:tfþÉ? Íœ= ÊÎZ_œejd.5“>"õÂs<áqµüŠ]r37 ž§ÿ¡,,Îp–9ŽG#‘c„á9‰ÔÚ®Ø2۱X!ô~Z,×ÈÜ1DR5èäΰEë•BÞh¤™¾ŽC Ü8¢o„’XüŠˆ¥°ˆÍ´ôSŽXŒð-ä"PÙsIæK m1þ¤jJ1ùxe‡Š"¤ '»˜šÂ0z>4?Cç+å'¶d¡RÁéz�?F1÷)QNRè)”®“D¹—e§S2' »�5cgNºŸÕXÁ5ÔT_BåÑÄqH{È£6’»RÂ? ôÅ4®p"“FäbYgà¬Ó(æWg.è…nÜÆ‘U„)‹ ’Ùªu+½\% 75¡ ;™öj—fÒÕrQ¡Ê°rd|áw'½âD¶0åîÉÄæÄ8_é‹»P’!•YÛ¡ùNfh„•È;­‚„Ú!‹ªÂ/ è‘Z”€áFò‘q¹­xÓñôQlY *É®Ç2Ñy¡dK0“ù!–2wÅý~~Ž-Ó‘D‹£�ÛÚ3õ3…’[2›4p@~ŸG/G+„QuúL~t/“3äSj„árfËj”œ\XE¼�›NióÆ?O3&Ïva8é $‡�ÅT,.q!§+‰±ŸÀ Ú×iש•óx÷{Ÿ’›¯±ÕuÃhŸ<6žLïÁ³)¸Mæ§ûD虞MË¡“±ÂÎŽ‹;xºr*‡2r¡ÈŠR/ Ê9"£) )³gåƒí…&Tâ6Ÿ´¹råÙwbì»9éB.Cˆè2—Ðô¬’HïÐ[HaÞ‚â‹®X¼/…ñ¹})ˆ³gC›7`¯ï‡?-œ à?,ü³€à8…–~„ š^'þ%b_â~ŸER8K—ÁM¤%"„º8—£‰z"”r¯Có£óÆÅ¾ìqÄ5š~GRÂÙÛ)ÄR6þN(½Ž®EÙ™|Ž‚¢ts÷ƒ¡Âp£…C§2RE‹ Ær;g5ÕŒ³&¬5Í]Ó#ñ†×ɱîÛ6~p†•%1xд2]Q ²/݆Ѫ"l”(þ£ôE(KG"¨t‘8jЬ2ÅTMUhøÐô&"-ÿP¤)¹×SK‡–‰7/j—r(Z~z™$Ié±moB3¢Ãu’7£e¦R:}U…‘XQÀŽ™vR&N £+(Ь#ó¢ƒðDðš+F?8燄X'‡ÊÒüè^1i‘AvÂ/#ñ†ÓɰŽdlü“#ª/àÎð‡Æ…ãD^ ¢Ú.fÒnLn'$7e;|&êÁè£ðµN« ¯FmŸÊÇãCÐð‹Æû…䋱=0lœ ('^¸ÉWú%šˆq@áê'¡éçôùÐþªú±ùÑÎ0ù�èrxÉØRáÂNÏ•¥ùмa#47"êeŠøv!k™ Â8º³,/tƒ7RPó;‹|høÐÄÆ½n‘ýHÛ|(’ÅéxJ"£Š a8E+öý—l>4¸°¢WcOD¹‘5mxCá’ägÙÒ5bQR8hǃ‚;2(:�ãøÁ·Èq2ݳiQvÊ~4=+h¼ËF^KͧÇñªC´D‹3,e0”ë†ô¤~‚» Áâ|Žì—= $çÞ…‘("RŠò³3Äät8‘Aþ$¤8¶nbî-·ô|<üjqt7!HâûlãˆãˆãˆãˆÝŠ6J(âGæD=óŒâ.r9…„ªcMȤEÑsãGÎ)N³UŽ$q/g8‘™Ä¥2Ãy”*úl(öÛñ}�ÒŠHšC…Øæ9CÉ5qÃŽˆ^X¹œb…‹o³ÿpÜ*’&á’êÙ—aþDÛ®Ž©�ÃBH�e³8N¹Ã÷8~âðEµ”æY„ý6?O£‘È”ÑȺ8…¼GìR¤Ë—Â?&Tw_/à».˱—bÑÝ2ïÞ‰ÃFo,$¦N<"ù,C+NbðFGàÞÒæá½œ5Cn½ÊØ”0£—¢s6"«“ “ä"Ëkœ�ÒrÖrøÇ6Îc–¹2Å¾Ç ô[8AWÆÅ‹'’ž E–•9¬'B‘,WLç!ŠÇÁ¹³oÉ(!J}ŠAY#z6AN|ÊB–™ƒ¶ ü’v? «™_ ùÅÂͤC8�÷N˜Q«"DÙø�à^tLƒe–?íÐôÇà‡Î/ÁâÂ"5ô"6°öž¾Pxm0/ôS Û/BãBY‰)…al)„¢â2vžÐþ‚Ó8Eä~>ª³\ðcš8QbÅ•‡"S([B"Ÿ\(ÆËĉF¦.ÃÙ­œÉlÔ¼#7û™¿£†~Hä—ÿ«D#ñ„ˆbÂ?88#I›6»èr¸áŠâüEB–Â"œ(P¡B…çCcÚ>Z>4?‚"Â/ѹêK¬?E•‰,Ënrê6 r†ô°²7‰"ÒÅNåIà„ùèz…¥ËÉîF‡ãKÓX‘Ç Æ'Sv&Ô¥ƒ'×Bð1`Ë ¥‚>qùE‹J.¨Ìß $N(Sd>4m<ÿƈe¢?9ÕÑÎ.òÐçcñ¶J¼ðÉÖnðÎîð‡Î3?D=ë£ãCñ£0¶KäÍ‹°…ýBÈ>ƒhsxXáe��Z Ô19cÔž4*sÔ´½BÓ³îFKªÂåc‡ÙÅö(¢c–ÏîQBŽ)ÚD-ç…µHKB!bbøÆ~V3ç„>4m<ÿƈtE.˜±ÀȰœn½ Ò„1CtÄùãƒ$FxãW3¾DQEÌSáW.°‡Ét] ¶N+NbS.‹—3N’.\¸Îg2|Žü†âu9ÏÁfYŒ�É*–d<„pœ'ܪ,X± ÈJC÷8>å°•G,ÊŠC ÉŠ�xÁ•E4wÓv.gQ$´»–‹ÑÃâ̳,Ë1P±bØAF'™CRpÉËš+øžŠ¨ßÃ8"ôpEèàdÚöÊÅù+¶_«q•Ë8a_Í"Ç ¹Â‡Ll9ŽDŒÝ0UK‘×–0ÉýŽ?±ÆÇ¾ù úŒüÇö?2/±Ç·™ÆÎ&q2‘³�œq‹Ù ïÔæ]û/²'[uÁ š"Š6”¥r[eÝ“‰Íá>âÍÂXáD[ªÂ àŒpE„…™,Ç ,/%‹ fŒí_Jñ¢/N#.α“sloi} ¸áÁ!}HtæNš˜|`±¾=JébÂiËCоŒ™–.VeÊO •‰›Ñ’ÙûÃvÍæ�·ÙH¨eÑ Â8´ÂEã„^1‡ˆGŠÑÚFôIfì-�, rø%µ÷„µ‹¢„ö‚•§†H�VxêV%"(ß :œLqDé2Y¾ÇØãû˜�̇ؿ© ºŸ™³óI¿‚,›?eb—ƒ$1ÄþIíDEñ¥F„Ñ8œ™ØZÙ l$®o)—“Òô¡‹K%ÉêbúKé¦Ò™l;—¦¨ÞÞe ³vq”úLáE`GG„º—m_p÷ÁàðXHbž‰h¹HYD‹�­žh¢‘ýX"X¼!Â?ÁŒÝDöž�Õ‚…õ,Q!Dˆ¼ ™)KD>D…²†ñkQþ›hx(½‰Ãg„Z^†úkl‘›û°‹¨ åq朇¥\Ù$M`¡Å`þ‚úYkŒ¡¹7„ß (T–ö[3î^^¢JM9Ž}V2øÕ!÷Ç„k¹ò8cr?1©±ÊEäq2̰ß)ŽqÌáFä¸MägØJþÌpÆ¥-äèðƒÆxÆ%ØdZ!ògX~D^¢-ùnÈŠ.\‰!f†§?e"ˆ¤lãûìó¬·8Î3ˆŠ®Æh8püÝ9a™1¸!nÌ”0²/�ãè3$\?ôv&¹èš'�ð¸…ô,9\£¦œâèXܸ¤æð‹¤ðº.±¹qTº.‹êiΤºaK“,%ÈI2À™Y–’êÍíï%Û+‘>ãÁÄÇ�™fY’“ ŽBxXt3J�’�M�4ìpáÃ÷-÷Eìá^ÊB§.¢R^Éà öQ%¶„ŽèÖI+ sp „¼>‡k #‘x}‡Ñ Q'!¦&°¾ŸØâ"s©rç/Ìü<ÛÑ'Ó°·™vq3Š#Š!)²ñ{.Î&:²ì»Ë乓iÇüŸª‹#¦¤ˆ™6E„×-3B‰ ™e�ÏÕQuÂn¤SÁÉ,Y \Ë(²(Y})èÌîðË =¯¬ ”Æû�¾~5".ÕÃãD…'„‘[²-?8C'ƒñŽdþ��ÕðƒWbcò-yÂjë ;2ŸBRGAQ²*hüHí _§– wuÕàrÅøÂD™5rQR4¾‹Õ˜ü8pˆCOT�˜Ñ4éŠó�pí®¢'Ðò|a>Z…ôåƒêK ™â²¶+E„0�¬�q.°á-<3¾x=jVÁøX²-œVˆÚlú2"ˆ^1Œ€XÁçÊÏ âZ#ÆGÿçÙ¿8¥_èFß<_ŒirQ ª1Aµãþqí¥é—!±Ç X?:œî´CçôÒÆ·Ã°±_AýA†Ñô ˆV+ˆ¼á'Ó§ç¤=ÏŒ^ ,3ÆW2´D”GÆ1 ]ET5ß‹!0yÇðÕbþ0Í“!Š+ã1Æ®�ÛsÁJ³ç­xÑ�¹'‚ƒmUÔœ.kMÇ¢H™%ËÞ¾ØÒ¤꾌Y¯ÈiU‹“ÁSui›å„°_Aè—B ôˆ|#òl×} †7Û õÕqù.52.õ Âä0¬&ùaqáÎG9žFü!áG3.Ó¡qÔsgɳhŠlwôpÅèT‹ÑLßâYú–ˆáˆ‡v+œ1[ÎÓ&Ýp›ŸjZ‰Ë±ÃÂÎp3€ŠS©žç©róƒ¡5lxN¹Ã÷9u-÷,Xe‹}Ë"Ð�v•‡ ÆJ=Óv(J´r%iø7‰s.‰Q±¸îe…90G"È›‘½­�¹�вÿ»BÕR°£… 5ÃÌ›7[LY¯ÏŽ&^"ì»8™Ïs÷‹Ñ1j™´´ÍŸœ,XXFûa ë„+[òX±³‰X<Ožñ£ÅÅòDðÙ¾âc¼’WCÍqa0¼0ùQY'†h¸Q‚x½XöÛ%¸ïÛ ð (]4¯–Tœ¢Xn¶ŠÔÞEGRˆ’rEJuÔú*}‘TP�÷ÅáOªÜ$Ú®·¡ý4m!êAçSÁ.ˆ‡è?8"}ˆ°�x2S òº'Ô£æ| ä"1‹Î+|`Ï‘ c“ðá²ÁBŒ°ÚBÑ�‘ÚËvÁ'ÀÄÕ´/…–ì{ÉùE ?O£zZž=….«BŠýŒ`óô(±žš`úKè?¤´Å 1ù!‹¶”„DÈ¢úÎ1øÁ¡�» s*w%Fª‰f˜‡ä‡ã°X)óœ~0ƒÆ;A cN.XP¯¾ Z>Q48#W[“'ÀÙ5lW�Cêª<% ›×(ùÕ™p¿¢±‚x›ŠÿFJ�’Âjâ"‘è<7¤ûâ±’cÔ°†>”cÙ¿+L ¹<}rDXȉwðGÁ&/§!9r$Ç„R6$O¼áAL\ª±o³Z_’?Û†D!Gÿ•Eý¨–Ëc )B¬Þ�?‚pî²M2¨OœäÑšFX±br¢Ñ³ó©i̬îUŒ¬,jY´�͸bË÷-÷)^Žý—£‚#�œ àûœ%¿ôbˆšœ,J'E¦ÜŽE‘ÈäPär9Ç#‘ÈIÊr]OÒ~ƒôܼáô\ÚC?b”¬~ƒô Š°ÜÛ&ÖìVrã}ÍÌ·æ^EàôUÃu˹x=7Sg&q/B”R^?±ÆK16ç'Žd•Hfùœ_c‹ìqýŽ?°žmÕØü4è… ®$°¹œšBy«9JGØã~Ž7élâ.RY¹¡S]…—£ðârèqÄdNi 9 q³Ž#Ž?d3þÌ”œåBª¢Îœ‹¹§Ôâ‹Ùx½—~ð»"ð_ru¹(¢.]—eË•)‚Šé“\8÷ѳú4…C]4Ç*Qº<±ùÐþ„ÐÔWú1y$ÉÂUc.ßEèËØŸZ‹�]Ñ�ù­/8?8ü¯ç�–à—R3l¼`¡Dˆ?vŸÄÚ8�Ù›¦ ,›á�I­ ;‹³[Êâ&‡º¸âcð.º%ý¬ál¤Ùª¶däâÒü‘ PÃvC ëô#L{7ʨK Ï�Ì¿|a]Óo®˜Ÿ|WÐZØ»àõöwÃ6)"¤ôAá�m:áò±gûˆ|hÚ~ã¹'‚HSÇå8Dl0‡FÑu‡ ï?v„löùx,Œ‘Ÿ‡:!Ç,Dá[‘`Òç„q>P±hÚÏ©ØïМt‰“å;�¾Ú’1�hþç踻áRHdçL{=5ÑL¬bÅbô¯¡›é.ªš+è=Á.š“ ñ£iû¿ã «– ÏܦœÇñüá°Áhøê)Sv‰ô6�”äˆQ'+äüÈŎÆìIàÓ"\ˆc‡�¢‡ž0èÊúAÖ"ýºv�N¬äN?þ2bQu$´2)™W6(W/¥.ØC®ºk©®ØnÎ}…„SgI¿‚·.\reð¾ ¸ÑÏÐïèçèçèçëéÄ‹1ß˜Þ Œ³,ðç…™fYú-¢Ñz-¢Eèk+#…«Ôá�Ñã‚#‚!nDA�žë±ÂÎŽˆ÷"«8b8"8"!ybæpF8rF9ÁSì5’#‚!ÐÙSàü¨þÂþœ_cò¢ö�Ë‹ì~\_byy¥”NG çê?-Ÿ–ÏˈŽ6¤6\” ¿Þ†%ñ„ÔRejÑc¹v~Zv8³�ûãöp}ιÁ÷-Ë©øŠ®‡êö$”Cþ›J]N¹Â½œ üŽþD[«ÙÀ¿Èr�WýG ö*sêX²,‹!ÑC�@§ä²öX²*´X±bÚ!ʩܲ9aÈär!ÑM2Šö,ÌÙŽEb$XTÕ�+CÐþ“ñƒ"}´-yÐüh€h‚=P2hƒçGÊÁ�öZ¾" <~í=’æÅQD¦~¦5 2™Äˆ¢Ê”I]aNÈËÌêÌ ¿¹_t´ÊÌË‚"/cÑ�/Î…ôþuÁÿ °]´1}>¿Z(°c‡çGƈO ˜ôO ×G¢-?�m;hí„PöC}áÁyÑ/í¡³ñ¡®Ãƒiã ¯ŠU/�¿µÜL‡GÆ sujxÓ�ùÒüè‡é¿:áúÏ诠ô|)ôÆ!`´?:>4Aƒ$=x6‹FÓD: ›hñ–?í_òGàpá’–ÇýÓ ñ¢$f\ÇàŒb‰í Ã+º!ÑþÜ$~,æG³ŠécØYâP‘R:ö%ÑO£¦0ùÓòôCôŸÐ‡ÏÖzÊhSÂåô\xÜø™•½irÑ râ©|.‡^z> —.ˆ+̺"Sd[ÊÇ>Î8}œpû̬E3‰{8—³‰¨âG8áöC¼Ž(}œpû8—±ÕD}dFâiy?2ec†ï™Ç {œpû8áöO<6\Î$v™Ä…(¬Ë£‰{8׳ihw­R´¨qCìã‡Ùù�û¢D- dI42d[£]†©ì…Ò\êV%ìã‡Ùdz‰Ì¥#�Hji‘8Zò8‘Xá©QÂæé7ÈuƒÙX¡D¢Žàé2pĈkÌâGÄŽ$U«—(æo3z(KËÉ5z.\åƒqB_EË¢©V޾(",—ÉÅÏ’+6:4(áG 8W¡n¯G ôp¢ÈsJå‘eƒ¡bŰž Uz}¢/%‘dYV,‹"ȆœË"È—!µ ,YXD¥9E‘B9¤ìp¯G ôpCèÙî©Tá^Žèá^‡!l×:‰µrÈt\Où,‹"ÅeÃò-‹Ó–8W¢4•("ÈgúŽè‡m³ù.Kše‹íÐöŠèü8°pó+5æo(b%´Ø¦‰ìbü(º;…�¸o:­srîdzÿÇrÙõê&¡u&á)nhQC§3ä5¼‹ZÂzzaIT®Ñü‰ùe!X=1u¿:™°Zg Íåèœ#cB-!óŒ1�L}Ñƈ<èdØÒåº%Ó¿sþt/Ú4LGÊÓŒ'ƒ~0ƒÈüŒù?Á;äô·CLœ"xo$Èò· JF‹LÞ�Š8nŒÐßšÒ㊇àì'øÉŸmWЀßhŠ$¥6D°Xþ.×›§Ð_:k…ɉ}(ç×èEçCд-k)¯£��ùÐühdLO�?ÝÿB'ØÌüãîÎ ¶í°ùXP¡[�xƸ2'ÈÏ‘¦>˜O¸±ÿn™ó2EgŒ~t,›±6Wÿè¢\ñK¹þ<êÏÄÿÈ{ï‘-Œ,¬~жIðDÙ(xÙQ‹Lâ(¨6ɬ)ô_ÐqD­£çD^t= BÓR•&Èaú1hZ!ó¢?a}fAã�?Ýÿų\®fwx6EûŸò,WíßAÂ|­0xÐü"/!ò?'Î2h·1cþÝî°šÂ?:6¸”jd•±m‘íZÛ8eäSj¦ó7V*gúº(¯‚é«/%ƒÓxü) 9"­±¬Í#Š/g^Î(ý—‹Ùx½—~ËÅ슮ýKÅì»ö]ûÏÙÏÙÏØŽ~Î~Î~Ê“…—.MÙ,ÙÏÙÏÙÏÙÏÙÏÙÏØÎ~˲ìU~Ë¿gêö]ûïÔâ‹Ùx½—�ÙœVê-èýœQû8¢öC½²¥ÌðÎ~Îg;gHâ‰ü�'šýN(ÿȼäfsö>¥N(ý�~'ò~¯òîùœý—‹ÙwìI8­Ôâ~Ç{u*È�N8ýœqÏÉ%~Î(ý‹yüQQ{%657aϦo7äd/3]Ž(Ž(�̈¤r¯Có"?2?gæGìKÃñ†ÌfÏGÎ…ûtDHk©áá� Κè‡ÄÝáØÛ¨ÛÂFhˆ5¼�£X¢(�ô½oËÑ�BЉ’Áãœ% Ø“ÁùÑ…¡yÑ�hËÜ›±5‡Æ�Ÿîÿ‚Dâ¢2ÃÀE²B7‰¼#ýÌ”.E0‡öàÉž%üéùcÆ]ˆ¼a³"6~4|è_·DXfn†m›œÈHüè^~Œ$â/½Ð«§M¢Â&Í܈¦?Mâ°xPøÐüè�·¡hZ,�Ìñ¡Å?&ü>Ž)y(ÖhZ>tEàXÕ¤nÄ›ÌðÉ M *�MŸî(æËÓY¦$àˆN,ò\‹¿GØŠq«³�hãBÞR‘Æ�ÌBÉâ6‹Çó‚X¹ÿsþt?XlˆþÇØãûosèq}Ž/±ÄE¼qýŽ/±Ä\âû_c‹ì*ýŽ%èâ^Ž%è¹sˆ¹råÑÈJr�‘Tõ\¤qG"¥þÇØâû™ö?1Œã8Î2Y§ðP¡XÙVôq oìq}Ž/±»جFër謹J%*2Èá‡ÙñnCìœ0C)¿ÔpAþG äpÁìáVê9ŒÙÀȈ2­ÔK"¯s‚ò8aÿ"JþOˇü�ˇüŽ}•PÏ/Sòáÿ#òáÿ#‚ò"œ¥.§öp/òôéäü¿¹X)—I›�W£göC8yõ8W³†g?äpCþE ^ÏË_äp/ò*—³$ÑÏÙú½”†3òãùb”5,΄T©–E‹P¶$ˆš‚"o¿ÔE7¼ v^JÅè°µEçDz>4/ ôб̡c…ÿî2ÇrÄÓÔ”0ͳú±×¤&æÑ¯(¶ntÐÜÖao'ƒR‘1ù)ƒ›?Ú43gÁ´�V‡ûžˆkÑŒcñ„~pš¹'ÆAçèd�Ô‹ ã�/è._EÍ›°¿’®^:á+T~tEô>~„ZV¾}Ù£�û?QŸÙTX±l*Ô0õ?5¶nÆþJ8YÃ?“~°þœ-’‰I•¶{O • —÷hbÑ“?6M”DEÞÆhÄÙ¹¥u„^0¤M|”ÚDV)‘$ÕÏÓèý'é!sV%É™Y¶…‰òæf†¸Åûž2!ðôGã§Œ6žLÊø' ѳ|óWTÉ+ᔜZ†û}ô$9,Vâ°øÑ�høú�ê¼j+cJæ[ ™÷?0¹b°Cè–Ï©¼·Õ™,?ܴۢEà^49ô‰¼!&ˆ¦·bR‰ÙÊ8G›fׯ˜üèÙâü‘JøB›ÝxÅû™<`ý¯D~1}ðÚy�|á³|‰èXL’!ðñ¡¼)h~>Šú/L>qSfêg)Ÿ ´>Î}‘Q{-²Ðû-±Ñ[©Â½–^Ë/b¢öp¯e—²ÐœŠå¤Y‘ȲöY{²ËÙeì²,Xáûœ%‡*HâûœEæoBt(¦p±Qœ,ág G 8"8–R¸Y¿åGö?*2)ÃBÑz3(YXbË Á£‚?G~ˆ^H•QÁ£‚?G G�®pÄVì©Ù)·Ì›«ÂÄ8s9¢ìÞ¯ÁºÎr?W¡¼Ìâ~‹¿EߢÅð“QOÀïèÍ>ÅÌ›Gá•b)·Äù~™±± �$ù_c‹ìq)ò/ö.ý ßc‹ìE7vqq f!s±•º¢ÿbïÑwè¬R8¨\œQÂ)D¥"�Ñ"�Bª.q"èu9{?ïO"…tÓCÓ ß3v›ÏЩƒÑ��øúCÐrÕCˆS• ÂVp±©<%³¢Ð±Ú~üUhB•²èƒ÷hrè)ÅÈ¢$’7›gÂш¼a5rQq±� ] a)v)b\°PÇr/Üÿ�þÝS–dâW,ˆÜ¬Ë'%4CCÎ�8*P�ÎÿK4 ,X¶ý…Y¹ û›Ñz!r¬ô×Dz>4Cô•ô-Y�ë×1ÚÏû´)^Eqƒ÷c" ž—¢xÆh”W"åQâ”8_°µI1A÷ÆÚÎØÇà›+Ž×ΈPšº7àôVpù)>ĺa3¹ΕŒÌÉÐO DUèbùú;°û¡½¼©ó„>~ŒZ�ý¦:’iÿЃ¯îÿ…¡~Ü\™³ç¼°¦|«§ãD:"ñ¦$ú•ÅxÐþ1šâ*GäêŽå Ÿíñ¢:òÑ$m|¯ãFÉõÒ°‡>t¬\”̲¨–¶C:7õœ�ÅšÈà8Àȧ 8"8"8bë±Ã£‚#‚"ÖŽYœ,³8YfpÄ:2Ìá‹ÑÂÎ*?E¢ôZ/EŸ¢³ô~¯G?G?Cÿ衚²úoy—Eͦò«§£�hç�EË)HÑÄ‹�Ió8áöq"yáöD”PÕ>dŠÊÏ —>4*óÂøE¢ä^J¹—C¬_×�†äY©\iåfX±ÐŽ}4O™µŸ\&°‚ÜR"•+BÂ�+GƆØá”´CôWŒ_œ’¬ÝS*ýBÑ…¢Ћƕô¤ì6®§õ¿Ò±Þf×ãø,°‘†?©R­ÊÂèÚ8W£…ʈڅNW‘ê±8 ê^t?_œ+ È™,ªYgae‚G>�ËCjËù?.Gå¢j&ÖñXKa<žÎdMtÎeâöUÅìŠÅNç_äJoÙx¥äUŠýN(ÿÈã�üŽ(ý—‹Ù»B›‹Ø·¢ö=轉f‹ÙųŠ/g^Î(½“›8¢ö]—eÙv]—d”L›g8™ÄÈ~ŠÅ’U}ŠÊuz�ƈt/?AøÓ�:Êá!¨.UKèI[ÁË ÅdK¾5"‹§ÿX¦ÈܱîC³‰nÍIü”Ç) í„á”æWL',bð-yÁe¢ç…ï ‹ržãùÆ|„ù,©B¤¶4"ð)èÚùÿŒdÈg×èÃ¥}_Efì?,‹;Ÿm/£ãD:�+CÒ´|èz‚—_K·Q%§kåí"•‘ä˜ÍâODÈ<`åÍÌs6’äÊâ´?_�.zÇóŠó‡Ëþq°¼Æ>T�¯ŸøÐ§Ô§Ð‡ø/ ôö©Kk˜¦òø;õxEçKó„2eñMt9ú9ú?è†þ�ú?èÿ¡y%2åð¹VR$94q#‰HâBª.‹¢ã¯2åôÌXN(ÉD°«iœU:’Hœw% ÔIaòôm¼áNdk¨‰ÏD ޼´6Aûp«)cj»ÿÁ"˜C¡øÑ1žNø/Ù‚äwCøþE£åÿ%o�ûtF,'†×Ïüh‡ÏС3ç‚úªxËRÆ-cÉ;³}æ!мh‡Bó¡èbÆÅ‹#…+Ðè®Y(JJ~ "È‚|ÑH½1æm©sÂÅQ»BŽô›ïѺ¤ËabØ9¢SSòQOä�9É2ñ{/ù¸¦áîÍßÿ¤9áÝç#,;$—!æáîQt/ù�ü‹ÅþEãÿ"í?ȼä2o5z3iýHÔŸ^ÄÜ{Oò+ÓüŠG_¸ƒ+j½JÄ˳þÈ�lK4Gæ3Ž!¯Äˆ{í4Ø¿«™mbû�Ø_Ô‰¼½ùÏüQùÑzGç?Hy¶­Û’ê~t^‘ùÏÒ?9ú?9úD¡�vo—sóüOÎÿñ?7ì%�7—š/¢ðz'»âDM¸$R-Ÿ¢û?GËÑÿÇé›ZÁ<Õô_f_fñŠy.~ƒô ý%2Ÿ¤ý%¡öCH}œ0û8aöUCì[G˹DŸÉ½œ+Ù½•E!^Îìá^Ë/eÃ÷8~ã”?rýŒXK™ý¨ïÔ‹Îè‡Æˆ|éž¶-Ðü½/ãTÛ'üc\$Kôô7YWDm<èI^Bt(”>0·5¡�á9aµò¿�áVAä™B‘oRSL½pR"êe^+öèù_Îno®÷?ä­p§2ÚôE…1Û~ïøÐ¿rÆ£¹ó¢kõ˜»}ŒYw¼ÎK¢–1bñ‡Æˆ|ýãCЋΆR÷ÇãLÏô’Ó9coÁ´øÑ²~pK ©i‡ á´øþ1²¡ï„°�ö‹‘uÍ�üí-Œ]&¿œç„¥òEûŸó¢ÚðR³Â?$m¿wüh‡÷c\>t-+è=éC3qO¿#~/„4¨°‹Æ1`‡RåÈkȺ.‹¡W™t\¹FRX] O–‡QhùÑ�xÁ9T¡ñ¥ø!—L±užÚQ�ºôDI,¼¼ÂѲùпrÐäC£kðwÇf¼•†Gà‡‘?õ'ût|¯äb¤_¹ÿ: ý¯þ4GãNÛÏühƒ÷cUªŽLÍ¡}¡‹CƸBâ‰Å‹ÁøÅÌè„K"Å–E‘†åÈ[°ú+ ,Ž*(áE‡Ng?gêö^/dWösösösö;û?ì©bUáÿeß²ì»8™ÅÄżÎ(Ž8Ž8…¼Ñ'´Š†ô¨8”y["S´ª~cô)m_£ó"6r޳•N5þ'æCþ'æCþ&ôPÊ} EÇ£ŽCy¡ø!Ë´Ix8áôq¾(=IE jJÇŽ(=€‚nÖGè?M @G<²‘E³‚g >Î}ŽJgè öpÁìNI¹5r_†¿È–EþGåÃþCœ0¤«r›¹ù_sò¾çåùI½çϹù/Ú?*/±ùQ9ìâ³Gåí=•´ôWe´ôD¿ 4¥Ðà�üN §øŸ—´ÿKièÚîÇWӱã‚?ñ8#ÿØéöœ1ÿ‹-ø²Ñÿ‹-ø²Uô~¯ñ?Wø²uÿŸ¢æô39áÏO=qd¹ŒIUôD¢§‚PCqÍ D>~ƒú+D^tE£ãD:=i…öÑòôGáhÙµÍÿƈ—ŒPæC‹6Ÿ³eòw(9‘æé‚žSxÕ)LÙøe%5bxGûE‹™ïÉXSJó„•X³täSE+�5TêvB•ôCçBó…VxÅ`¾„» Šd^4/ÍbktÑ2Ç,!Ðüèÿn�Ÿî)‹XºEKaci>rƖ–&ê𣸲½þbx\u3NÈO—3) º'ÌsT#ñ¦/Üÿœhl¼=.¡b¸m|ÿÆ ?p´WD/èühz—AD¹èXîÕ›ÏáŒQœ‹›Ø[e+•E‘be‹0¶¨¿ûÉ3Š"­û*â‘ú½œÇ(ŸSŽ)\×#~i”lãˆãˆâˆR‰œgØãûï3‹ìO˜�—ê&¹Œœ�ä(“Gc¹»H‡6‰O{ÁĽŠDóC9œ%á7¾Ä£ŸTIÄæR§ ¥ß Ó,*66ø‡%3€á!™iãzÂq½è—*éì5(©Ø|°œêMÌÚCYÚÅߢïЫ(Wܸæù³‰8ˆè¦)Æ©ÜâEÑS²; º6µçÿÆ—.dç̆¿¨©}_"Ðôühz¥›RÂȦ ºPŸ|Jd§8„¬eé¡yÆú_�+زãä‰ÅðN9L….eË”¨¦nÕ3SÙ'tNÈ�Ú†E’—3ô²QM#ˆYÑ\ 9¢S*“±6ÙLÄ©þär—b‡mc+„5±'lwäªo‘.c†>eWÈÉíz‚‹¨÷¡k¹|7™rHÍ2|ú¡¼.†ÐæPYînÕ�2æðx&ùôRFôza7jI\[ª7Ü{Šea„àG"݆å!Hà‡ÑÁ£‚Bœ(áG8IJ’,X·Üÿ³þÎ~Ë¿lý_äsösösösösö]û›.9‰Õ#)eª‰ìâöeŠ<,n½äJ)3ñ6t]™>Dm–EñÑãîÓ\$Þ Æ*1†bD”ðÊ.xЋ1ã¥a\çà\ŠaFUGœ-RmãBO ¶ Â¥¨‹T’‰L“sc¡¿Sw„—1•…•Q(”�¶QA:ß©¸Û¤åÐ\5(ӈ϶¯beÎøO*o¹ÂŠ$™7stÞ›ìIÑtE'AC´UVfZ–fW|3§S¹cz­áØ©L%2gaån’+?"„¼�ø¹»ÌÞ†c‰ÉÄߢ§úz”Â\˳…Â$øPåbd¡R7°›²Ð¢êIá¿DÉìâSjM“¼.ÇRS¸ÜŽ(È_é‘cþ9МÚä!ïŽQ69ò$¹�E’��4>†ò–Â,ÍçV‘SãðžÍ›Äá|†fv> ÷5rpÝtfWHŒ±9K¡•6â7¡LžÆÏ‘’TþîC‚>$nĦJUìJ(hr8t3¹Z ^4!MêK•Õ5G‚‰ÎcÌf¨òT’¹z›2jåfQÍô.Ÿ©[‰$I9ùDð­›ÝÂjóPñHâ9"¼‰Â&…‹r¡4d�e6?ÃwäŽ#tpVbJ�ÅYÌ” ²nhø7¾ ~¡$ªPs~ŽŸ— » ¼ Îb+‰)¤C³Úʼ,œDáË.³&ïÖbË´‰O©%+“Nˆ{­®ŒÏ§C°¦‰¨xºlΡN¤²±Mö/<3ÎI£,q9­¸I2¬Ê„•SÐÒâå2ªe6i¯&]¶ÎS/RD•aæ„ön]Œ±Ü£›îI4×)•¡V'›vÇ ™Z"dšYE´‡ƒ§Cy"¯?bŠHé,bqr®.´U�©b¿r’3Cé�å†]hv;oˆ…,Í´r|™–NH�ðòV¥"‘¿1‰J%ÔͲ’\ѼëзÜÝR2ÇìiG™2®\¤$….WBË*òE}�Ç i\$‰‹¢Æ,?µQf‹ Ê\¦B”¦Žøf\¦ñY>åJ4K Bɨ7Š(~K%úPÜŸÈ»ÎHþœäC  ©v2E)’äQŸö[2ðMBÍèZ$ÖÁ¸Ý­£6ÍIÿ$⾉; CèMÝPÍ*Ü„á“e8…6,ðËE¦vÂ5'C… (loò©•·#z ÞRÙÃhEû§ÐüNV‰ ,­À7)öæe’ÊľçWÔ¢E(¬G*)“W3Ã5ÔMÕ"q)´+ªœÙUDÈ\ÔÕñ¡é,Q#CQW¦ BÊeŽýEhÌ�‰B›Ôš™jćZO »u…—̧#u?G 8qÈ¿P–HKKÁý8þÿã2Q¯Efí¡�gUú‘,Í6,ÒŠvlË‘>ˆþ®Ç)»³ÿqTã‡Éf;æ=œI™ …¨—6-ØgÝ“”+ ŸC~r3®}E.2Фá[Æù4¦V„DÊ1¼h]¯Ü�ØgöÂÔ$vrx[w Ê™°C™6Í×2Q_±»²R“ì&Ev¨äÅ2e0ì(”§Ð®�ÊŠŒÝ«'‹bÜ·lK™Ä(¦g‚S\‰:9�pIM�4T’7�êÂ7BYIS©6Jr!…øD’*Ê!R¶"�ûˆ\LÞ¡suTPí+ Tdöt??‚lüM›ŸUÐY¦‰ER¼$ás"wJ˜[ Ê[HlMÒfhl&‘œå–¸LÚC w7}àÕŽ¬­ˆös”\‡ýH'Òd-^‚xnD¡?¬æ»2p,«•OÍ‘r¯ vÂdÕÄ¢ö5˜å:sât9³*[œˆ[á‘E�—‘eˆmªvs.dγÃi™R'n.Ä™–æfpTR’ˆ¥ 93§|2º Ni”T8ŠœŠ�—,p(Q[’äHìRÄÑ&Ë|’cû¼ŽTø�$R²'33±ÅB­›ŠDÛÅÍ}1˜¦PÍ9 UÂzw7ŠÕ½ ÎK'¡Ä�Svh¢7·Ÿcú~BÇu•DæV¥*åB(vЍŸ-‚´U,OEi.¢j¢m’h¬Ù5F™Sº(ÜìCIEÔ”uR$›K4<áæfÙEìåàæ7ëQ§È–‰>N¹]К£‹ÑЉtÅìÝî‰H¥Éa³Íá’á‰Z)•zœD{X$à\“+O$1ÃÊh¢™Ü‚'çUÈ£)#-Ÿsz&Íë…n�Šðf‚!¨"r2·I xÌO™Z“p¯<̰©,79ò,C3:RˆDã((b…|á}Ó±9S arµ9a–z>OôáQ &æE+‘&X­I4‰cY’P˹JÂJ"DÞ3wì%2P¢�¯C±$‘ºäÉ:”„‹ ñ§Û—XÜ¥IOìE*“bpØÍá‡ù7T–Še‹²óޱ ƒRFô'˜šÂµ)ÄYú*™[9(äq—E#bYÜæ7³u„YN‘.¤ÜægÙ=ïäŠiV¢pñ¦®fƒhÜËUœÊ3±™ DA5K‘l4ˆ“òPÍ18nVçr¥¡+ľä›dáfYTÍ)Å¢nä°©iŽ-šÊþÄòÓª©»¼J(r±C7ÔüH¢%ƒ†.cq¼°ŸÒœ][$ðîsÂØJM>åif&ÇBpiœ”¦» D¤ºœHȾä’Áe±¦,’‡ÙU„›D¦Î°Šw7l9’(‰³™(F\ÞdùwêùT“'™Ø¢Ár*&\k©ÿíIX�ÑJ#þJb™Å$£8Šºà¤fЧ&Q ~œ$ÉJg8YfeJ¢�+2s7\Ç2·&ËBŠD³dbÏɵòM%�‡+r7¡M@¼¬eÈ•Çz}È»:LŸ1áBL}ŒêäÈ“ªFöÍ3úu]–R}4o}Ê ›Â’ œ2ù,s„šm³�œz)+SðT”(»‘/É9\‰5š)’©Ìæ¼áØ»Â;£¾¼Ìû)fèKh¥(ÊX›Ne¥ ºþOÌmŽg?)›±P«7¨ù2çr„k2….f\Ù×ryœ‰›»¬†=œPÅ–½ðY”æ%A<ÐÂûáaTÝ‘)P–ÊUç…q¼‡™3rèN+œ$à‹àž(šdÒ¡™Ø�ËÈ›øDS¤í‡4gø(.¨r™'r˜ßàñ„‘6Nˆ¹Ï ”Ew˜š‡‹ ÔÛ†nx'…ê:^†õdI¢Hœ.~ ›Æp¦K,R-•’„Þ¯sxšÒ¿Yƒ3‰9• úW�ÔüQ71¸ ¾x) 'BÊ6e¬7=×FR$ðn)¤•)rrË DÉL“tN"e™[“–-s19QšÃu)�ʸܫ ‰~§"ÜIÎý‰EAa$+Lϳkñ?‘¦šk Â…¡;(!‹õ;ÌÍÊk¬&üáx\Ë(óBC׸äÄó8…–'"DIs)|dádäâ…{¥!OK�ÙAcàD“*O¡)“´Ç³‹¡L_G„°~Éó:Ôš¡W1f†bNJvsŠ}ŽSCÍwBd…×�óÜáÁsU4Sçú…K…—4ly¼–„ª‘4è"|Ù|(TÝ2D‡ÛÙèQü µCàíü`¶–\ÍË3úžŠa'¦–èt} ¢èâGÓg”DÑÕ µ$“*Ëaq>£‰xB›ªÃzs"‹«˜å…¦Žt—RP²Âd´LÞŠˆí„‘Ü’$^E E *¡E:2éŽxtfõQS<èIa=£¯QÖSµW?hI"QÀ³u)1Íסø‘%6oBÒÿKP·òejhR‹á�eëY ¹ÈÏž�Ó¬É&¥ÜßsðC´�ÿJÍNÌáöYcÓfòF«A®fõtM³±( Ô¦;ØQ—E ×7Uz•ôMè™6nG1òI:a3f›œwðS‰–%ª¥bФ+ôÃQw,H¬I #s­K<(„�)¡½Rˆ«G~Ø$âräUÍ nˆ]T‡[•GòHš;Lrè'Îc±2¬„ãRxT”#�[°å1©>äŠsþ.C�ÉAÎâY¡CQ*Ÿ‰z-2˜¨8LËÈQCZ@�Dz…M�x,ÚX\ÉCÅДm&Ÿ3�gÄ\¹z -æfÃ3õ‡|'†G¦·‹¹¤I§&JcqÇ5ÈYâÌÇYì�Döo/„gØmbo˜ÛÌâ|ÏêÂþKГu&ê8ö2ƒ³2R(�Ê´Ò2B®Å œÉÁ´‰D­:™6ÛÚ8]8¡¹8$¼(äq}Š52§l,NH¤5,>Ú¦Î䊕á(J#wÞu&އiˆ‘Hæÿ‚x“¸� T”’îNþJ"ò'³M΄Ü.v¶š&–ñE÷dÍÜ' É7cuOÊ7åðPµ YIÁ?Fñ»Hz²W‹›Õbn�fe} ]yŠS•…\Ñ4nÃ>Äâ”M¶ü�E¬Æúa(ÒbÝ�òVϨŠp³îs9Ï6*TË)–ƤÈáI$(¢s7hŒïÀ‰èŠìC:Ã÷Õ¤ÚäRŒÖìd㔺¢R¨³'…RôQQò+�"R“Ã4 d,òO ¡D¥Cz°‘½n£iNDáæ,Ï4"Š{a …«Ô”Jdå–] U�r%hÉšEbO7À£�9�¼¹\«Ð“¦72æHNrì\âDQAº•8Q|+VÎÆHlîvC“-òH}plœcÊSy ÉRSHÍšgBDR,9©ü“T"Š:²*ÑÛÉJI’�¹Ã[?–oÔœ‡ºÇšq2EZ½;Ö"ÚÅ s±>g|*5j ¾9á jÏž¯ûaaNä'QC)ÅÈJ+›Äà‘½7!dB“‘1ÌÏ×E t;�'+ ‰ºÃñ9s6qºTšs.S�ªæeº�ƒ䉺’±——"Šâd•Ž¥ ÏE,AlÍc"æÍYÌQ©H»&ÑºŠ›ñön¹ùBØoa$¨&¢Þ\™(¨Kœ&ìÉÁ&úNº2(aÙÆ×d~D~�ëlÚƒ“|°‹ûÜJn�Æéà…ÊL¢7¢ôn±RØ59>¤çè”Sx·"ÜRCË_ø2íWÊ*Ñ›f¨9—$Þ‰±>¤�Ý.Dâ«*¦R}p’°§VQùÎdð�Ž¥!2ËÉJ Ç)ô%!dJ}&'…6Âpß áh]È”ŠÒ,,Å�Y’SdþÅPá�°StH¾ r$@¿´Q&óu™ R¯1&æQÈj51E²Šk¦5„—¡XLïƒeð‰Ã œTz„JTKìO)y1øžGI7"J¦ò“ê‰ñÁØÚmeYæ*М6:hË3gÕkЊ¬6J%J‹/ C*M›ñ?�I/š™öhÎêSî"¸OibPá(”Ñ=žòÆI6Okè”+�!ÁÍX©µƒžS{‰v' $å 0r;è¥Îå¨MÊ!C“ýÜŠµ2¤S°åFùœM™ÿP´'…†e3d‰JÅŠ!С>cú<„“jewŠB„•�N&gޝFɳà‡O� r7RX<3sÁ!ew©T˜žEIBèDÑž*¶5ÈŽ|ª,hÆ�úà½è˜†K“$$( %Šk�§Ðu.H›7hOäñ„,ÞäŠ1-¤ "�´ü”�ìnÄdŽbP¢ÜÏ0…7L3]ꊕêN#ub”"†:Í”žÐääç"ir'Ò(ŒÕž}¼cƒ¡™6órbú?ÿÄ(!1AQaq�‘±¡ð ÁÑáñ0ÿÚ?!É“R¥C̵«ö•&Êx¹LnF™CƒÞ H�½,!ƒ¸&èÉÌr©a~CHpnR•¥ô½êrr¨�}Ë»"WUîaïs'’[¢ÍZ!L:§Hÿ g f!‚2 sîUÙÄ u,^k´viË™¶*üÁÈÃpn:AKn¸Ü,TYS`׈ Kvê0à•P¢óð�&ŸX78Y+«#y² à €3DnÍQÄÏh?q™¥‹“WÄl˜l$™x„‹ÆRfÕb!®Ž&(™jûÊs ±¸–Õ.UÖaì¼Í…f¢¾I„YÇüµIk<’�w¦Í˜g ÖzJ¸ö“(mc_ÖX›W3-©wÒfgHÞ"G"¢Û`Λã´$ižŒÃØ]<%ó»ÿQ[¢s ÀÕóD/–ÈUIKh!ž+ò•èt"Ñ{€¼5§™^¥îWcr¹šëRɼJ,+ÆX­>åe²ÛŽRÕ󧸇vY"c•×b 2Ø(Ai×Üt¸/PŒï»,Ú㬼§æZº1qàIFhæ[JÛ‰A½bRéÕ g¢9[êv•#¤²x!S„3 `u€WÙ ]ª+s>ØÙATA¦ìâ‰rÝÊÔ³¦â«Ñ-Z°+ûqJX슞]zBÙÏ“N—‰Ð6ÊD|¦Ðv"&¢?´E03…Ku.øÄÈut•Ë/0¾CšœpK•)ë: ‘šØêC£ÄtÎ�m‡~!M[–±‚;Àñ `ò£‡x›­X ټ”Á:Ä(Ó<1Óó}X?,TÜôZ…fǯ K ;JL/mÀHKå-+/^œfÅ1[,@µi˜µñ™A–¹•�®¿ÔYqˆ¡áD',U�¹ï*p<Ï’rž^ñ… E‡è…y„Â{ÐBäå¦uÒÓ´â,7UÏù¹š:*y6.o%ŠÉÖ æÌQ/ i¯2²kš[Ìè~eο˜•*s7º˜ýÛxÔ¿Bñ Å= ž'Eî,M(©žÁÒåñ]·Ò3­ûÜb_á ÏJì2ë-' ÷€‘MœLµB¾a­ÓµWæ!fP…aKáŒ=—™OÚ"sv/¾�:%€g˜FÑç 1�Œ£˸�ƒ×Ú9„¾ŽfµŒ[®[¹ó’­uEÁìR&6nXmT\–ÜÑ®�¡JÌž•ˆª \TÖ΄Pl{z”"ÐtÜ[a8¦>p¨6Ô u1‚¶ÚÊ_;1‚VŒÌ°Gq¢8©ÌÜT,År‚Àò%æââ eó1ÁØÌ†\N³rîZ¬¶A´¶ÞN’Òºˆê)Žf|îQË–¹n!cVôŠdm\ëVŽÀÛÚ`k‰BüF‚³œÊô"Ý9�Jn\#³U¾aS’8Ë3>Æ14"ƒV�Îf N³¬<À˜Š­T¼¹×PéŸI3kßq9©ÜµwÄWL.`98‡ Ô=‘H"“ÀÈ1Ë‚ÎFY­<$Qz½%&ƒ¹W-M(£pÒ,*·È–/±Âôo1ÜÈë*æTŠž½e…ä�H<øí5RS!†Y‡˜é¹HÝxœ cR¤‘t8™ÐÚ¾ì]Êðc—Yß°å12n±6¸Ü¨%¹AÇêX±²ÍÄö’–ÉQÁ9­LUéOþ*Y\³¹ÅΦ¯£Á/.=¥pë*rzÌfØÊj9€öeÚ3ÝŸ–$EÏb/Þ¢·œ$ =ÞeZQ À¥íÆPÚq2x®û• ¯´UêާÉãÙŒŽÂÔ"'Uð Sˆ»7R†bë¼àÌkå]Pñ1¬®‰ÑʱQêêÂmN/ IÞ05@L-JùgGiq«¼i1.ëÞQ5]j-æ¥_2ß'“Iå¼ £H½ j%O‰{÷YÌEQUÝ)“ãeJY+På™ñÏÌ3·ôJeoÚ%q0 Ž9vßâ=²<—‰{˜†œcºõƒ á?( œ[,i>'�çŠø\ÊÇU‰öŒk—±ß´¥Qg-A|Çœ9—�Jó-`ÌÔc'ˆ²‚Û˜¬”­b.äÿȯ™Ç0ÀÇ$lP!EŒ½%wÿ<Ô™æUòÔt9ë.í8DÞemÍÅÃE‹3IÊoòu�ØÊx9œg3Á}"­¯¬ _#0‡kCŒêRYޱ½“ênÓ0„L»…EÖ2X†(ª"¡õ‡uª©í;&Š�˜è!4ׯ£uê:œJf¼%L vÅ–¯&h¸˜ÅÝ+ÌÜ Áî¬eÜÔyqÈ­Á«¸J7Ì@–ºÊ{|£?)GbBŠ*áäÏIoHë̪ÍÝRÓ%u ¸×2§w]`ärаvb5Ú§mú•+/.ò÷”�8Ú A®ß˜ò°O}‹qèC™P_‹#ªqÒâ•)‚ÐÐjkÑéQ”73cTÕ‘²«Ý�ázÄI….¼B›£}áæ[¸u:¾&ŰÁ:¡âu¶m!�6ŽP0Ø7 xJŒb(!Ø¥ï¢5ñ8êLK+©å�y^וLÝs˜CàÛEâ;xtÉq…ce�A㔃H…Æ(§©d_<Ñz�éL2«DÍñ i)³†jÒkî§'iE¹=÷¢fRCŠ€¨ÐYóÂdsëUY®­Æ¡ fBÌÞ"Ò�Кuòˆ¿2¦ÞósllTæ ]:£PÛ!N�\¾b!Šºm�"Wa•Ýb§,™f¬’µ¢Ý9ö„mWX¼Jiææ¢‚q,e]ó1ñlŒç3Qt¸>�˜Í¿(;ª�"P9[T 2†|niã·iHPí˜Hèq1È�ÌKl_É(i�Â[Ç5!Láï€3ÒPCŒì³V¥ófq•¹¹@)·CQI˜å@•@Å\¼¾[ =œTº€Lf\ºæÑ}{G<ªR�®“,Zyy”w\C<.i™…V¸…M�†g$½š,zÂÊÖ,h{2L «}€*ÅÝn[h0‚škD îPá©H®[ÔKyŒÐàp5ßÔܼ5Œ!ò®Q¿Z°WÝÊH)æ¥Þ8.Yq8b†)–æSø³$ˆ¥_h-Tå­õb ÒxÑ ç5 ±€˜YÖ¥æ‡I�JùŠ×Z:$°=eÁšp[’=¥`GéXÀl–Ô ‘Ï)@yÃ{ Õnæ… –7[ˆÌC¥¼®ªRwŒ1«i©³J&¯rÙÐØ[ˆ<§0ī͚ÁTê zšn³ÒS㈢�Ö°²Á.Ë)OIÉDå™x6j*7Œ¡‚À�ýŽû‰¢ÒSV•Ô™Ú+ñ+*+Ë3D¶…Í`•JVnº\¬q 0�óI¨÷‹šÆbákæaKÌG_˜Øsæ[gtCR›ÔQÊÄzBíŠÕÏ1AhV*6–£]"-,Q¨ÈÚìŽ9Þš‹mõ ™ã³‹.cÁ]ìˆÈ‡ž%‹7«CJ…V§ Fv3Ûš—Šà ó*µUëC>e&@ kLZ}Q#kU›+30-M îU’û†Þ‘ß5Z5©Z)0b¼â ùŠ0 R8fsäQì1PÊ�³;îUÕ˜¿ñ8Ÿ^ó…æ1Š�µÊöÔó 1or¯ñâP¸ð± ¼b° éL›(ü%À"ê¾b9a™­™‚Õ$FzÌÇ0wÊh«^¡á’$ '¸,JˆÃÂ4û¨”- Š�µ¤-¡ÖT޳™oPˆ@Éþå@k,!‚1WÁ |h#gIµ¸.ª=uQ«ˆ>ÜCšÕ[pg ·¯2êÙ˜ÎÔªi"ªù�‚™AÃU +;58‡¾]bdàîj%Ý·Pî[Z¢³é Y^5]çö9 sn hÀ¡lrñ“6b³2&ÔÁ|ˆß!Å*?×7s›Ö:ø©²º¨ƒ»g»ˆW#‹©•Ú¨Æ!ûÐ5–Ô¢6ÔÆ˜®ã-²ÜÇ)X5¨�& °¥\#1(¨Œà¶RÙ«Š\Ch~×8%v¸–ƒ²£Àq…—QÓ)î(n9€Ä”;T G ”ð�Bö÷�éËÌiiž%ÀÇS¦=¡mG•œSU-²0twŽ%nÓ-ß�`�¥k™I~´+EË µ×˜Øó�Â!ù¸d«‰. ©×)Ì0—Ùܪ(ò†�ÊËzYó–»™²WÉVæ²sæU6}ÁeG‰ ô©Â¬#¤®×gÊ ÷(Y)´9c/0#ÄËÎÌTT¦H/`NG;YP‡6جêÝ’…µ¼Ä!�Ó0î1_h‹jo‡!žæ]cÒþX• P@]¦ÙDž¦ d9¸ã¢ +ÚK ºÓØM?‚ùš3Üæf:²Ô*‘»JX ÷)=¥ -·ô \ÊRðò‚Ë™_›±›<Æ-s ñ™qæ\wŠfs’¦UN¦H¯vÆYq! •dÏxä·�‘v‹VÊk4rƒ­W’;8 똆FšÖáy¥Y—?ö6[Å㼸6‹áÔT4N/sHxƒ»ò!µiÖác^w+hk‚êc¡Cp‹ ýÎß™ -Ù/X°r‡õ,k´ ñ¦uQ8•\í�’(ÙÈ-㤌ø‹=h©‚þ`õC5F(ij3h燃.Z^`¢ù¸p\Í.f³wÉt yãÊ3%E…]’áÉÚwî#Z%ä¥uƒÑrÖè"Yæ¦] MÆùw@>Éá9J_œÄªž‰ÃuÖP*9©eÀ×:�RŽ%*ílÁ�®ÙÂ^°±Ï˜»3ü™zŒ …Á»Ei114p”ÆM±#¦´é=+›>žDÞ«™™Qàƒš¿à:ÝêiâcVc'0] 7Ò9àš‡Ù™©nZ£s­ÄCh±ó+„{p>QºSÔ–+¥NP—Ö+ö�ŽtÕÜÀPì‹P �Tn¯[Ž:×(&b¸”‚7æ'9¾½%‹U2&!Þ ßá ÏóˆLOu”GÏÁbžXeKZ–k-µ Þ1˜…³=�Õ¬Ú»AHÛ¼e„Ⱦ€<¤Í·˜ê—ï(=¥š^Ð�)¡yëõzj-£~a©³¼ê�¼íYÃccù G·E}2d³˜E]EWb ÚVf9ÔEÅÌiŸB¯¢: Xìe³ˆçdϨIÃèÃr�bR—î.2Œˆæ=�ÇÞÈn,pqRèñÌbSËrÓ j9ÃTT帘 ¢ã0­€eÝxë1ÍN¯¬JF†Re€· TÅÌ¡©…ZÙ–‹¦ •®%ÇÓ¼"¸¸k<¥ZYÎA�^Äy˜³§ºn2”¿x1ï©ÃnΕ•©Çή¡væ¶M­MCɺ�Xˆ¢)�¬%Nf2­r�A^'iˆ< +xÅ\0è"ìŠPû‘,E_šc¡FN·{™ {Ëí1R×-Ü´�M=fV Ù,î±¹¶a‰^›Hö3dAï ÌAËY–¿‹˜;ÜÜ×¼ÎqEʾÐEž ‹œpë+ÐÁƒ‘Êñ6=jG _Ęs-ê©]8›œF¸œ8Nf”¼jè-)™¦ÆÝÌu²Ç†þˆqÝ—Ëž—B-iè1Ü, "W-LâÙ˜9Æ%C³/}÷ KN¸a“ûj¨KÆT²ÒôšÉã¬ÍÀ"‘„Ü_,;âW¸¾V°K �¶ $ï)‹ Æ!‘9ÌrqlfvÞÄÊ´cº ×vusut€‡Åj �gÀëé—V}¥•n%6Œ¡ÛІvàTÖ4t”{^:¼ÃPEÖ3)¬uq)†³rú„tæ#‘ëÊ]�r ·„¸˜•Ý *k}"LÐü o1F?Á[ ãCfyd–4®¦qFáåÄL¬¢ß¸Ä_�MºD ö*`%-UIF Ø`º®ffá¡|Ë@X¤\ð Ûù[�~‘zDÚ?1`fìšS©Ñ˜¼8©©e-iŒM�eÄ*³®Ò™•dhŒÄ[) Á̆9Üóëp`ŠA¾e©ÊöA­7gÄëݲà E�Ýù‰u–JZ„©Zê&tL >b…{e„mÛ9–Gîm•Ž$!¢¦´ÿ©e©`uš ‹Õ»N·Üi…®)bÏ¢q fˆ’Á8½Ã¦ pà€h7¶÷-ê|ËÂÞ‡Ÿ�Y�yø™¢F@ÈrÔÞ»o‰”Œ°±S4D`¸rÜ òG`›.ëLç]"Ù<¢£1Y™â„¯2ÕO_êmǘuó;ãrÌŠŽ®¦Ä/ÂQPNb=o/Ã3™+˜‡RÍõ€x�p[®Ñ—�yæaE¸¸¿¶Í1»…Aœ$©ÙƒTrtš®†x“=¹ivÌ�º†¢±WGD§¤¬™e;K½ŠUCbðjX˽°ÔU(5IÉÒæc&e¶¸p3337K;@�.«è‹Wf »”ÊdZôÜÛUŽðE‰ZÏ0ε”‘]gàQÛÓ1Øô†Èâg¼ola·ËuÚå9¡nªœ8#x‡HUÛ0Õ)^ð†Ø;aá|Eã_DÄ�ÃûéŠÄAÎe¥‘u#žš°A¨¡ÀÊ*Ë ekEñÒã'ãcb˜°éç¬TÈ+ˆ*øüE^Ž-¸Ha4˜e©EºK·Ž·²ü´¨èYV:L–ã�DU©WbŽñ‰_\¯x¼Зµ¤2vs;ºYfÂ ÔÆ5wj„D.7“Faœ‰ÁÉVæNb1Mg(¥}=ÌÐÕ“+[ůP™Ùvÿ¸ÞGVQˆÅ´Ãr/µ'bá-ŽŒÌ(TÜat*ð—9Ucºb]rtæa·/õÔ§ T§o¬TtˆYœu…�Ι‰üDÈLËsB÷¸t:5 tƒm>‡åF�  ’É·¶gXØ­¢¸Î¦wÝ.5¨WUÌÑ¡q`¨e#¶­å‰_ß™`²ÜÑ9µ<Éܼ'YU à èe¦¤³J³&•2[g!‰‹¡Î7h`ËÛœLlêl¦^½bÑh«•.±– ®2™T¶® ˜@<ÿr„m*qR½—€vŽZ–ÍÊ ¢ï¤¥Üt¥�»¨rªX<¡�ÎâdQ‰™¯rÓ'�0*”ÐáØõŽ£jÖe˜‡N`Ü�¦�Õ�ÖS¬À¸–@:Ê,cÂ�¤½ÓŠƒ¢UKŒ™œ?¥rsÈæ#0ß8‡t¸Ä,�4QëàÕÇ£®±\¬¸‚B‚öÀQæáŒÇ(ÆÁ+³�{Ô4uê0Š/ÖPáj9‡á/i[ŒxrdÙÅâPg'ÌÓ6—w/â®ZÁWZœFcP±pL‘qb¶i«-–¥¦³€3+îâ*ÄX6ØH�ŒA?ЄÊL‹6#ð<ƒpجeí�NŽ‘rM†I–¹x'.•ÚL¥€†>xl•÷é1TµÝ ”.îá%ûZb&ºaŸIK+x_=PŠ¥ÅÖ°‚Šby Ú³Ú_’*½Ó$ii]ܼ‚ÖÊKKn{¨:†ÄêFˆ�—Öbœ¹™Ôæ\x–ÄAž‡ öæUVqŒ £É%ĵñ1ÅUe0ºNœÊ˜a€ÖWF Àñ:12‚‡Bxù2,%ÀÅËZÎèm«®HcNƒ½%`oÞ2ª¨È­]\/5;f ClÉh!Œ> |Ž¡[�µ%Í,0ÛoZ©�é `0a~¥`ãO#ƪ_ Dbóˆ%€Ñ[b‘Å6ÁÄiCOXµÓ†½YûÚZ·¸bŠÏ„*á4äÅ Þ¸–u�à·JÅÌ’“WÄKLe¨E@&hæ)/Ù0R\12kˆÏ‘-­<&á“ ˆ…¢E”{ ÕÒUœÙsŽ´•ýOÉ-¯–cXßÌ…�4ƒjÀ8ù�Ð¥£V‘…mbb"8Yþa>ÃLÎÕ�À*áB–ê Uùo ²Ë!�GÁd®ó YL #m¬Wo°…EM•\°LûÙ’Ö÷Œ6�.R¦!ÂB›x�5òË ×¹EL\‚m:i‚�›,‰‹ri3Òç õЇŠœ'´0€�«4*ùÄî>e›PEt¸æ i£U % ÊØqhÀ2…ÎlTΗ9dÁJD‡—ŠÛ,:Á‹—S¤8yeÄÞñýÀ;e°E ×H c:šUº]æÏ}¢bo9�ÖÔÀMB*¦åÃ~�ù¬¦�gfJ•‡u:`ÔoŽÈÍaîÊ7PˆWT¯Å·«9™øý_§éòÇŒ*¸>¿43/ÕÑíü5ÿ ’”Ö¥4b]E³)¡9¹S9Jµ‡„ÒÊ!2¶¦šŠ»¯ý%=Œq-zQ8·²/N«;!/nõ†€k+9Je†W™Â«$¦ .²ñè” O9°%žÒd¹‡„´jmàÁ!aѹŒÓ¹¥ {JÚšæ=”{á=_˜æÞñ³Ü6¡r*ç8•MWPÄÃ.4øôFÆ@x©gI¡Ä ã6ÀIr—£SÀ”é˜ü½è‡ýH‰vÓ®5Sé(ÿ¤H°MÄÌËG½üˆ—�øg0ü3k" z‡á~%�þ!Uþ ,JÿÆV4Ž 0¯@죳‚n9ïOaSâSx@�PÍJ>Ù˜ ìéÚ"J¨Äåª-u»t•‰°®Èkù˜¯Ã¼&†àà¯wpr;{T,L ˆ�/vÀÁ,=œ¬APB2½ ÏÏð~’ Ä)|ð…I‡TnæQ9ƒ™‹ÄÍ\$5X¨b„/:ËzüA5ùÏÒå¸üà:ü¡™×·w2²Li‚ê�‡²‚[St“¹јµŠKë”oø+<¢Ç¼²Y,ˆ¯˜Ô¿D]~Øl™RÄ/ŸˆS¯Ð·RR ø€n퀵D3,ÑEˆ-—)”w9beÒgÄÚŒô–}ÎÃó-ñù� JA”ÿÍô§a„Ûi6þˆwü%¸E–µm‰íP Àì†áø!Òˆº—ÿÛè¿s?CÕpó .þ`S8ä˨-&Ü¥®³¥å8à„� ÍÕ±¡ GB µÁ)+ЃdJêŒd¨P\=4øþ¡£Ñ†ýñz2ÞZ—u2]n_x¶­ë™’a…Âî)NšaŠ@Ù!¢ì Äl¿iJžQ†ü5:h.ˆW±Ò~eݘ&ùJô~&6¿ŒWÄ;_‰À0k_SÚ[ÒÈ·Bægªg£è[«Ð®ˆ„¡Ð\Ðh6,ŒyKuA¹Kr£NIžm+Õ6ÖËkìNñØw3²³4´•˜©E: 5¾ý"<¿~f÷Ú¶Vxo1Fsï:R®g% l«´&ìí;GÄã0Û2_1ÖÊh€€±ŠñŒ¼KðÁ`øÿ¸zéó J ™ 1C'cýÀ0vÙŽ$­CÛÐ�Rcê-ÛŽ'’�Í$ü88"{„!Iu¢W™¯xl~bOŒ3Ÿ’û‡d«+oÑpD¦Ç‰Þ€æFDh”² /Ea¯æ£öI¦óé0_±ýÇ‹¤zò~%z¯ÐÔD�p%ê:õ?çÓóR±+×Gðh†¥^� ïôH¥�ËuÂ4Þ˜K-sÚr,-|ܬ•ºœÔ;²ÍŽÑ,»ÑÞ8!0�¸=¡Õƒå™E‰²/€7©Ä%ö�§½ÁèzAèM `—A¿?ÁãÇ«vª}3LÞÒ¾>9ßÇ~>ðé|¡ÿ¦~¶]ŠÛ¬)1ò�Ió?õ¡hÃË8&á ¾îŠÛ*c™H¸¾Ò­`æo瘨âj¼i(Ó7æ5Ÿ4çO†jÄdfœµó˜ ¯É‰˜ÁÕDz÷`R6²Òø �¸�ÕfŸ_ÈœOö˜‚%@\~®iýËìÅ0·AkQ¨$%T惨|‡þî"•DYƒbâ=€Ü!õÈ_2£7©híáÝÇiQ9ÿh”ýDVU³®eø‚6ŒPÕwv `ÃÕË ‹9Ž�ž•?-.\ =#ØŠüÄø—Ç0] ðs„f£ÆÍC_Á…zï^XÜà"#Þ}f=ıÄ6E™ÜCu5D"¢×F—† � ÔbaÛ9½ÇT;î[gÉBKÜí™Y˜KFut¯ép™pŸ‰½7š=Ó—©,¾„ BÉ[uÇýšRö€8œDÌÙ2§0.’Š]”zhLïC¬G�†U™Ÿ‚qêëÞW¨¿ ¥G²R6œM·²O¬ì>‡É3Ëßbp磙f¤Œã=3l¥x™l]OMj¬Àƒ V ¦]XÒØ"Uz{µ=&·'¼¨†Оôè!Ìü@†~, žÞÝÉžçR5d°Õ0)á–„Ú ?,ENYùQÒZžŽ~$L­g5 ÄÕ Ö‰U½ÍiW@™TMK@Sd¦e8­Æ>�åKw* nåUÀÊÎgêŽa vox*¨½^ï§HGq÷!K-�A0Â~b,¼Ïèõ©´¨“ÈÄLðeZ£3ú‘Ñ 'h§Õ˜�n·ï/VÑ00¯‰¸s5ÌÐ<ËÔÊæ™eéÓ±€ŸÜv&7 Þ�Ao¤È‘f„ õC^•9&¯àmõæa^!nïÁs —é%̧”ˆhùDÀ¼¡í.,àõ{D6¢dë;¢º±ƒÁh­qóŸlJèñˆÍ¥{ú0Íi/Пg¥BŠ ¥DÌÑ+=¡ùPÊÈëoI\„‚Z7P€Ð Å�l…`ð@¶±?)ƒ{”¹iµkðÜqè°²Ûæm‹„þfW�ûô§R4iógɲYÔ–t|Ëág™hV'Ü6€» ¾�©±Å KÈ¿6æ&¼ö5;fj .‡0¢3L0a×üL¿;`i‰^ÂÛUÄ,�É`¡hÿ¸PÁɨΠ¥&Jèä%ŸãîB_ò�KãKÿ‚/f_fZwNaK(J·ÚU²Ë(ˆ¦µñ¿¬§A-Ï[W¼iÄÍ’ö˜7ûBŸñ8Ú¯´G!,°¼;èµ/kȰƆp:°¹w4ãàs?k0ÿI]þP³—çÐ.¤JMcq1KnÞ”“†"c`ÅÀ¾hG¢Ì£0§ˆS%¹um°ËKªô„ê UJöµ¹J ãÊRÇæB“ÈLãLPQ†#¬¦ãPJÙ2i;Ä.ÒrNä„ì ™x–J@EÙ9g4\öÓ®¯i_MÒq3Ë;7†=–Õáƒkáƒ@Yïó6…^gìgëgëf�ìÄꯈ=üR¢ñyG(š©å{ò}áÝ gÎc¿›z0vž*Àñ+þ(ð²÷$+²òÿˆOü2U6® m mFáOLcÞXv^âL»Âä˜8�E…Ú,pEÌCæ ˜7;ÄVTÜ6DXSÓ²¿4ó|Êæ—_pé _á?ñ%³ê‹²nßp'�½Nˆ–p™€;}ØðLÅÅ|†èËq/ïmç@{@JU(½d“Ih>ˆCPaæ;Qדê<è;’¹Mµ§ã%fq+âõ FôˆÔ4 jS¹Ñ) SÁ~Ñ"ZËrföc8û— ~ª— hÙJÙÅKÕæ.,EZ¾jU/|ãÑ__Ûêˇi½�qm¥]3SqröŒÍór¾ˆpRîÛ›�Úg.ù”C'Hͳvå´ÄiC„¬f#FEV#à¶Óˆèe~Q­Å˜Ž BÁ©KIÙ|Jt%!†Âå%I²Ð\µƒKu‡Ú§YApg0x›·äÏé Æ†¿�¹«ø;ú1Ø€)èÊtŠm'ô9vx�ïª{ÇŠ@.8Þ ,aÚ˜@~þJôý§oJ‡´¥�R?™,˜—ö™YþiKÉ9Ð,±^ nyo´û±�6@ä9„þ™!‰¹w5ηWß¡„ÔOx�ˆ‡¯ é«r>ñY3p.2J7d zÉéu Ñ^íÄÈxW~#ˆ$¹h…l¡*½“ðÐÜ#–>�ÄÜ ‚Œ¥sÆò³:îP¸Ž!ŠòŸh?‹ïÒÚߦô€3zÌ#´G`ê#¤;±´üK ŽbÛkØ—ËÈ¿�íþǘ©%$ðœÁÃÄÉu^™H0ø–>ø2�™RÂÓ~g5QÔ‡©råÚ%a„ŠšTç=  aë•G›î<ú«.’àËP«Ü ôþЇ©”Rð~®‘Øí?2¦˜ =ö&=v‡ðú}Sìÿ_Â×®ßÃDÓãÒ½?_±érçáÿOEŸ‰IuÜü„Ïõ`J%T¦ðË©v×ÑHÚ‹ÊV“™LßïÇîwõNŒÍ<ŸpÞu¼A?G¿¥«j0Ip%bcϬ ÜÔ‚†–¿v�ð_Ìî ¨A….f¹X”.cvñ?éR£�è @«‚ü2è@>êü£ñ�g½X»‰ó1ê�ëƒZ�È:Æàˆk© Rà&ö˜ÚüQ,‡ølCŸ>•*ÃÐôßßüÌJRW„Ç¢‰…_ª#ƒÑÍ�Ö¥æ}Q~®“ ÊÃÖïÊ„%A<Šl`ˆÜ+Ï~§xzk"#Hn‡_ÜÔâbLßë>„º…ÆÑS¤„yî„»¶˜’½âZ,Äu–ôD~+cŽÀ™ô1* Ûâ2K%Ë‹„¤DfÞ% ˜ï,\vÌÂb=Q�E»²UO¤Ÿ’Zi;hk£gÜ)‹¿’y>S¼ü ¾]!Üø`{üCy=‘±Ö-N¢Ñþì¥sÅÔ—LY’w‹Ñ‡×ý‘(Rî>æaÜï?KŽê]¦Lna‹îƒŸõ/…ù�mqÖ\W þbA:ĸ=‹¾°wÄÀzÌß}"u̪Çh§—L ­F¨\”�µ‘ñ+hÀ ðÃq:NNòä+&m–FÔê±éˆí» _/ðþ�áã.N¢AKûzY)Ö-ø +s¸Ju!q„,rnw N¤î7íó ˆ&‰IÞüOÚ¢_SÉñ<Ÿ ó|@Ó»¤.NÀþ¹j¸Y€Èþ#cú'ü\L6öŒÄåÝNûîJ<^R#‡'2¥Háš‘ÖÖlÅ uyÐ0Ø%½Ìí,&�ÛQü<Ë„¶Ñ“üL#€Ù,ø-k¼¯Ôþå~¿÷1Æ%WHÅ.çi¯Â`§/ÕT¤ÝK{šÞÿŒG/ðÍcRó‰T…æ '0”+ J¶TÛ#Ð9`8Ä)‘ISÓnj7óM»÷`6ò#Íó;Ì$t«ùgO;iÿ ŒÔ?ç@†XÙL¥W´4™éÙPÊJ¬}L2w¸”øíT¸ ^³ gÑ3efÿr*5hìÃPnf´Z5Ì1&õzYìýÊjêc/èzJÌSò`ö õ*Ë=h¾q‚ î™\JeGÈBW–oÓú~ßB&'àÀÊôbeÅ3Ž…�™a"ߥ…pŸp•:Dnmb†Ó”¤þ°þq÷ e�ŒW Ð?U,I©øÄV:1Rž¯Ò6ŒÝß2îâª9˜úVÕ¸ÔS.�Õó(ß‘žÑBŸé…9€¨ð2ËÑ¡Hk˜_Î`ކ]§¹ˆ*pÃÅ·Ä«/NÈ6³Èƒ§$/QÙé·¤zíåOWëênYà‚û¤ô_œ?¥Ëš¦�æ‰ý=.1~Ræ&&=†¯Eî ¿,o­zèþ ?­>›z?C»ê %z,Ǿ¡åþÓá Že{Ïχ²ÀFôY¡5ˇÐ?¨™H)¯0x#qº^¢\´‡Vh˜Hô£”²™"ïW8½c]éõÂjhNWµæü0b¥9£2/îöæhôý}ßB:‹á†½q�g˜­ñ/k:C$&C«0· WÛ¦_?xÿØ}Â_Ñ]ã0¼¡,Œ0= ="Ðæ±âU1Ñà "òO™QYݳ‰ôŒÆy&Ìá÷6^!è–YgÛJØËlʦ'xK5 & Å�%pžÅX)Rt#Jèêü'¢9’ÊC/û6ä¨ñLzm>ÇßðüŸàý?‡àK­è~tüÇðщÂ⋾f°!�ðªºó–;Iv% Ýæ8dͪ�ÿÄ:/‰ÚüEØÚÆÄÿLz+\(Y 1º('ûNÂ,Cgöeú\_Û̲ ÖR&=ayí+òú[ÿnÕÅ›î…%2Ý� pÁ¸b4S̯eÍ:K↼A·£ï‰|2Ô iûFR¸;ÄèÃÔä?I,,øOö/L ø‚ÿÂ^ÔŽ–Xá[!¢ª×ˆ¸3°U=_ÔAamb"œÇ´zi 7‰Àë3À¸1=Mµ1ãó”“Óþ¼L@9†¶uLà¶éÏýF^¼úÏ?“ý™²×Çýš‰n¨ñ8çá?A+ÿ^ú©¨Ú8kªêr/ìJÿÆ^ëâ:š` f^ñˆ$#�^Éÿ·?c3ÿH.[óÑ—k~f·]bF¸e�÷QÞP˜Þ IöÇi)ÌÕÄI’¨�H„á×ö�Ñ*}B7gyB€»ËP¢ç,C+(X̯âé2Ã7Ì(†×˜–c‘ŒA‰fÚž cKé a€òw>ªªdRF·¤/úB�/¶C m›Ïé˜Ø óø•×ðžgįü"¬¹Oþ%1ï.Ðs ,ÅÑ葼…üÞ%waÜÏ&d2ÌŽX-�J™.À�4Dtý‚v?ƒ" ø†"Å2Ê8%)ij¢YÑèÔ@ùýñm�Äý„ý„¡|F1_¼|@y>%ð/h$�›WÝ äÉ ”JöÔ n!8¸‰ЛŒôÊnç®�2jΧ;âm?– wÆ!Q�®«�|!pJùÔj˘ƟNÒK býfõ™*ú>ðÏÁþ�& 9ª+Ã,Þš:%Üè×Vdäö ?Xßb.e–£ƒ>ºa+rÅhŒÆûAAJƒoÖ}U4ðe§6Ͳ.ôáÞZ¾ bTºË®ÝŸPúo“î‹â•Éìp‹ˆýÞˆØsý@ ýR¦¡Ë÷è5/¾ üBÜ[€eë)§œ¢ 9éU–²@ñ Ƨ%<Ô y› |Å0#Ún¶:$VXeôŒÀß2Ò¹0(:K-·HjkQ\ûáÏø:÷ ‰œsdp£Úy%ú\Ñ6yþYüí/qy1šB�À@?ÂWÇâ äü@a«²šÌ¾ÄÍÐcËq �­ü¬=n˜)q ó²‚Çd|0«S]‡}–od?Â37—ª…f¤ã²QQ!ù˜3},r"šFZâ{Òb°×ìÔ&c1̤1õGbH>•LTÒXÄ@_ˆG O}LBã&ÄVqˆL<9Pñ*Ú'*jftL=]?{ô§Í¡„¯CK« ÷ÒJ´a"p#ó �ë œêJÇX¯Ô3ò}À�6ÅWByÄ~&^³·ñc­~ñV¬ö'eå9Òjþ‰ÊM¡<‘BÃᄵT3Rß âu+¬µc-‹ë É窡~%ŒÏ‚0§ˆÕl¡1ˆ3�ÃÓ6„ aÏ—ð>�àëø8ù†NŒ'ž?�šy>¿†ÐüÞ¶B¦xš³ï6ß4á�ˆR+f ö¼ÌJ ôü �ï/Bæ�ÌÉyÄ5 Å6‚ á+Óîf>KÑ!µý®-±ÔE%ŠT<Õ»H IDǧâ>ž¡†a©·¦uõÅ‚:œ.—B7_èõ®n­×ð*/Hz€Àšf{éwôfmwؘ�Ù†z}ˆf¿®˜±˜³ Ñ)5mæ^¹É R£Ã÷ŸA„*^½r[ÚOxL,Q Ší(=ÿƒ5F¹�*}‡® Ñößâ!„åüµ¡ÝÏ úO´âÆ›G˜ò¼Ÿ¨Žä91qáXt‰ê ’îBæ&�bßîçcá-8eÛ&s´teÒxù›CÓ/à~3ø-€´ó1ãñ*<4“ÙTX|1!�MŽ«ð¢ß„”ƒo˜_û“úxŸÙu—fW–"e�ÛÐLƒéeÕþÎ׫Ôët'J� eÂúK"g0Ô—§íw„¹ÄëW:ÏÄÀ}=4u}yJõ&Ž¤Ð‹š¬-‘º}M϶g‰Ô±•pƒ¥äA£)r�¹ä­/(Ž®>iÓá–†ƒpÉÞoŠ<°(„QïvTv×õb'˜/úBIusë"Ò&d¢·?÷ ügo1èÑÿˆ÷üJ£`âøJôøLÈNªŒA1ÂÕ0)Mnþ>нL\ª~æU¨Ñ•TÝ:%n0ê¾eÈßÞ\[ÿ¨�¸u…d™„6p•_1KO߈͓Þ&›‚Ľ%ð‚AwS¬§¼ÔïiÀø#K•í˜QÌO”÷‚â�l¯*ŽËdtö”l•R‰m‚�B†!Tq ÜÀ­ÜÞï ôÎÓ21 ­ºJTŸ ôl®s¤´­+I97-×-×-Œ…•™‚[l­@1ÔC®Ú$³MxS9ç!ÿ¹Ÿú/øF™0£ó‘G7¸Ç?¦•9<Œ¼j‰ÙR—Ÿ¼j N¬‰GYy þHx¬d̲UbyæÛb,ü'|OÄJ[‰]ÒŽ­ÆàN‘Ü|#ÿ(—ehë.·à%ßãþ'þGø�ÑþM*®1ÿ�«ïjX.Þ&&ÿ ý!HÿÉ›ùFeò§þ¦õÄï*1ù”� ÞÑñ0¹W„"Â:QJ–\uålÖu ?âEÀ:‚nå¤â9ÃÔ”2RƒÄ·Rʤ ü%F°p•§Ä5…¡ž]œàÒîeôBºN&$IùÈ`.P¿"ûZ"%\ lF=\ÖN2—£¼“H=TüŸêR³²Zd{}Ë—>©`wƒÞ±ë;Jl³pКú_ˆœ£Õ¯D±%ÂËy•Qè…ÃWw#Œ�Ìí¨cQÅEo©-ì³1‹¿GÂvôAŸ³ü·ðáñ(œä£íº„wM±G)�¡ïÝa%€Uó ß(­§âb¤3YÑÁŽ÷ÝT¹_œe]kéŒ2ž‹ô6Kt­Æ ±�?‹ëÐPê£?´âô„Ui¸b‡òEaœ³â‚‚h‰‚Õ²—¦öôÿp¿ÉNøôFÇØ•y‰qí€,╯oÑ- ödÁ¥ «)> f9Âõ1 g®~J³pïÖä²*™B?ÒV—ß }”DÀùW †„;ãºÞQ?ö‚|\ÕjySÑ›o0–Þ8¤l©ƒ¡Ó Z×HÌ3´-]õ”x ô'™�5¹¼¢RÉleêk©û�ªTI÷p=�½ Ø 4J%7šÀ|L#°aæFY��'ux=o5èœšŽ…²¡ J†!¤¼Iø1Qî`T! ü‡§ÙþaèNg/ªïÀAÅA¨[è%ÐÓ¤ô¦ñðJWÞêP`  \Ad!ŽßÍä{Ê8d1ç‚%Xæ\Ò§�]‰¦~xì’”EËÚ\(û! èÏï*K{&]õ68@hwkå‰×<=Ú½e' yšjø"¾¦U2uÙóÐ|¤7AÁè7ê‚p†üsó Q&QÑ1 ‡dAý#ñâj46$ü¿ÔüOBWJ]õ‡hc^%¯´Á.ãýû3½“ȋľ¬Å‡3¬å–íÏ@ÕöoßòÒÑüpDZH­XXÀŸNô:÷Ÿqá–‘ÜYqx‘1%ú}ÇÜ%ÃR`å’’ænŸ‰Z¨+Q6óËa¿ˆ;jÔ³BÜî>"»ŽL¢x;@-jdÒxŽÄ°nÈ€ _M!ÀaÚ*›ø„¨�@«ÏЈYQ?Á/SÁž,ðC#è…9<š³õ%bEb'£2ÜÓ¢&÷Ž™&€}°kɹæOöd£+/d䯙ØAâdÆœ\j(ç™Éï_œ:G¼7ep.HáÁ¡vÿĬý‰xäNŸò© cxïS?lÂxg)ZèÁ~_/ö65ö%3^ãV³[Џügí_ï¡ "Ö;Fˆ¯´ ^'0 Ãù5H:�tAËoñ .»C—õ�îx'Z,–•r '”Ý> â�ÒSýW‚5ÐËÿÒ/‘ w™lÉúÙ_úÖaœ‡Y�"ÓiB6Çx(i¸nS<ÿ2‡Ÿ™Ú€tƾáN¥zâ_ Çð*¾'@NÑЀ¿´§HNey†¢kÒçÈD`ºÉ;ˆƒ4bz÷³I,Ú! W¦3YDÝöM=¥"%Gæpóè`T­§Å&·zœ]gµ¨eºñ|­Ä­8.˜/QeÓâç@R™¨¾Ã×Á?󥂕ngþDNÇ£?�ßð7èT5\F â<¥³É�´@¶\[ÆU˜AnΙA{½ÁÚ¡ö XçJ.cùÐש>épï.\ËL¤{&SDÏq «¯Agk3 þ/DÀÜ\Ó˜@m6K«ËïÐ,5ˆè0ˆM�ůlDÙ+£ÇÒÏ ºŒé‰Ÿ… šñ .èýâz �=Ÿˆ¹ª—§*¦gìi,ó#.WI®d@2ñˆ®nSÛ_G+Žð5ÌÙ†<&sÉš¹ëú¡/i”Ñ_™�4•pf“êYEK¦ …¶!·XˆV`©MJ\x©m Yò–ÅÝGÚ°cyFóŽì5þCÓìõK›>¤ÕéP<ËÌHwÍP h%ø9b^æ`oïCŸÙé§Œ÷¤5ï%½YÝT“íCG©¹·ËF�H–.Ï[«NŠÝš~tñ Zˆâ8Å»kÐ p®ïÜã B‡8ô5þÙ”õCȸª?`�ܶ˻ !S¾¨Lœ÷¤±x†!¸Tàþê,$¹� è0Qᩤ4z~qôKƒ*¡OMsê+e]õ`â &ŸC‚‹Ê3YT¨l¾¾Ÿ’š¡^%¡dŽÚŠàÇd\KYu÷ãôû*žLnc–G¹H Ëû¨®è[L+ꜦDMnc†S•½{z3Xå}4â nåNbEX9�"u¥ Ìùa½C0ꘒ€5,<Åz2¿qhè„¿ƒÐ„û?ŒLC^”Úš|GRëÑ@ß“ÓÑHç}Ï«öz*H©c_´è¥Ñ/x‰¤�†�á«å÷é¥í;(å×ÐË.'?1Æå¨ÉÒ#_ /ÍÔH%Q&3 7�–>Õ D™KWÒuÓýÌc’9,½«<–ô°öz_ˆs׃)æD°t¨¹î(nn?X�ÆhHÕ À ôÌ̆TÉxúô`�–ä¯Ñµ‹4@&ˆê�ô"œ< ½T0r…O@G©¦º#GÀ‘$N’—öû””4ÌœAš¥ôþ—òŒÇ+DaªÃæ]e�\âdÜþÐ�¢¯Âe¯&ŸA%l-a¤Õ"ùØ‚á EòÃhkÆbÑ×øC(¹:DÊÌ3É PØjRº ¾ °R¹š}¾f÷P¹4”˜çY„¥Ü\ H"�QÛÖ¬Ô«:Ž »ÝFjÃ~�GÁÔ o”ˆQ‰ŽIf¼NxÇIÿ�¿¦hŽÒ¿ð†Ã,¬-±’3£Ùbs§{B[r¡Ñù Ü|Á¸MKp„߈ —ñ*¶MÁ–uц˜`Æ �¿õ @¤-Uá^Šý ýŒMô#Œ¹Ô�m‰é1Q1^²�r‚lt`Ì5ÓÚ÷v„Z‚»VÄ(â„ïiÄ&Òßxþ• IròþÌí/è[ƒÑ04NÀ äfæ ΢‡ Is–.bvFópzÃàš‚z,¯ {"%ÓoEÂúË™B}_ÁÏ‚hõ7éT Ìw?ªÄñ/ṯ¼Nž®�>•ïj >e¼YÔ83=M?ÁgÍ5*Nò„õ£¢R#¦Y{ÃiÞâáåÁ2CQÍ@“�¸‚| ˜°:Sq9™a¢-kšÆ7– ¬s7ó³ÀRýæ³ñ±Y(Ô×÷›ÌüiÌZKÛÒ>©àlÒr:‹õìÌÙ×îú{Ù½(RQOHw€qéÊíõ LÄhtƒÐ©Hó¾];zgŲtŠ ®} 0$$Æçáʼnrâ6õ½@`þ¨ò‡ˆšö‚B‡¢+Ñu^ÒÇ�ø®¸3!*Tçu—ïTmù^`â\åK‹eHëèÒnð&V± Á9”àÌé[¨Ó‚°#_¡Î†Æió¾\H†ÈG“Ñäµ’;éë«Ì[ø½OM¦áÏ™¬sï/Lä¡àÊŸ‘;…êþð‹º!ŸyÝì`ÄIª}9þ´©yÍ4_Å2Nó"¡Åê B£eµÅqÖ*ñ™(m×x ›§•pl`R©Ö+ï‚å±É5:,G³‰Uß¹L§~¡É6»F¾“¢áÌ|ç‰f}SºÇ¥wâfv?HªÛk(^­M/ ü_B!a-·‰UëªJ;Rt‡ïWPŸ�=æ!Ú䊩˜þžðÄÄÛ?iTǺhV@Ì]£s]~êT372‚ïÚ?DŽë(1 ¾%z 2õ¸¬¾„Ù,˜•γEš¹ˆ: yC1ËÚYç+¸¬†QOˆ¥¾² ¬\j\�ôAEÝ’ø³Sñ=xYª·5ôÐó @„¥JTàzæ�½JŠRf g?Àò¢þÄ��Dì&~4OÌ!yc÷ z!¦!èöŽvŸ„)N„…á¨ê²âhbÞf`ôú–xÄ©Nï™{çaˆVˆ†ŸÙ¼âUzÌ2᧬¾oC£;”ævžpTÖ-%lÍZô*1¸¿rµÄÔÆørüAÎ%Û(Zé1'¼~ócÃÔ”r|Àµ&ùwžä{x®ª™é2Ê„–Ü“ŒÔ¤‹òˆÒUáùèÕUwz(áùgþ´1�kˆ~Œ6!ÚÃÒŸuËÄ\©ïÁ);£Ë Jå.™¾.+T‹êKê!*º¨ ¤g'qÑ”øœN£ä…ùAÿ‰�þ zð²úÒæÒøWBí jŸæWþ1oÉñ+­ñ9e•ÑohŽhK Ä ²¿™N50È>ÑüèëóE[-Mb&i¹\î¥�ªÉÖÌ5¾»Õ/Ã�S–eÄ®‡ºµÍê²Ï3ÿ(™fÆñÄæ=ò¸¿ 密mºOпÙúêÅЊé1ÿâÿ‰�¦rS݈ÝKùGwÆŒ_?0�-A™îÇ@»%�7d³!ƒca–¹�ë¹€i}¥§mÂ3Ö×ráµEáGIn¸EÈ‚G¤¹{¯Ä39]ËÈPFÒý%îù¥_9n;�à•7\1š^ä!±qË-83" dµV!%Lñ1l¦øÄÜPyD5œµy–>³@mÃA…;ùáWûÁb[¨ë?ܹÂ?(ѧå(õyºápíQ<¿Ä$½!Gá©UÚ¹ODµÂZÏx d4 n‡Ä£c§H§ZÌÏü9‹ž˜[ârÎSˆ†OÌ(‡´d4°0w™3w‰ÿ�(bÚÜ"[&}0SÙ¸�Sþ¡Ð&,q‰† ñÃP» ›¹qÉ·13 öBá…Lb•SÂxJíÒ?/î‰+YwŠ/ÓÑ„\¸0~lË4ÄGÿ#ÿmë8ô©S™Ö\^‡¡¶’¾È°ÉnÛÚ–ûEB¥QD;‘b½$aµ4¾Šn¥ÏrbÄ2¸,\«ùŒè(KŽˆ0š}IøßÅøž¶bÎë‰Ï“é\Üñë`ù ´l&ýqWWr!,q<ÏΗôÞšï¼8žOPRGdfÓU‹¯3²ùt”f†X}?^„H—$ìz3˜ÄtuÍJ$ sÝe‘pñébê5ö€éýzA6zQéú�á7ë“vÊŠ¼Ð[JO¼TŒ;&æUÃC€C+<½aC2ó4{DÏ·¤C6²®áQÔZ[(n¥¦eþ�rnR†€}ÿ¡Oc ìÁFÈÿÙÙÞ¯EñÁ$$^ºK`¤µ'Išô[½K‡´ â-2¸~øšàS;—‰~¿´ë¯†lË súé‚ßlŒ×yq0NW´oÊš£¹†y¢žÆ"…#è£9œûÊ�Î%Š+Úp~v àêIùÖ¥ÎiV˜ÐÆfŠËn(‚‚³äƒ™·3¶ æ+ðXÂk¼Ã×î=IøÓOR~ðûB‚™9ŸWªŠR@7ØHݘT˜û“þ„±(ó1X4œ'§vXjbçZyô7’Pü4½>�× z2ƒ@YÔØ~"#UÒ�a -ÙÂP@&ç%3Oƺ‘Ía̙ˣRë·xÞ™�Ä÷4#¿Ó‚5]ý5þÙ„[M8�A ‡dM™ Mú�KMèRœ ñL53g1FMGoð Ó([îWÌ5ó¸(ˆà“9’s 'Öþ’­S=⌇£ˆ½Ô/År:7´:‘,°|GIkèAC:Ê«ò?äRì•eï™{>S(9¤¿ >wé*T¯A^ïÜö´9J�ðÁä~‘VZâÙ¿>Èy¥ E21S³ñ;×£(´¶u•Pôæ ÷N±Vbù‚æ2!C¬ÒmŽ‘-›Ñ^ŒfªæF§ãÌ^ er´JÄÜMðFPáoÐ4©gcˆz‡¡?hzŸÆ}ÌÌ}4tfnxô#è.n ñ—¼*t™ Ïf/$}ˆpŠ×>‚+ƒ€KkãiPÜåikÐú= RN¦"ÔTXŽÈÉJTŸˆ Áé $ ¹iò¥áÕ¹˜ClLÇJ‰×`L?™G\z|Iø ô%)ûá â•uD5žÎ¡“꘷ˆú:_ÌoÐú•¸T›ÅM Tʪ\ÆÙÒ?T ñ7"}f,|‚´ˆ­ˆCˆ™ŸÜà&šŽ—b‡¼­K˜/õ6vž†�¡cGbi— %Q·‹".çýÍ¢Ø:én…ø„}^<ž•gFƒ¶ mfM6MÞóK®k?3„ÄØ sEÕ�€CQÝ…H½^e}£о¨uß¼ø�÷Ä`YW—œCóŸÄs¸ê^¦0ñWx¨Î¥(s1ö©b*ù!%³¤-0ñ­Á‚óè†c$(aôs¸Ð$:aH¬Mb�l˜±óÿx�HöDSÑÖ*?´Ïo™žÓ=£§̾“æx2ú˜Ñh>bô1‹ÕG\G�jW‰ìŸ¦¦¥|b>9«…ÃÁ¸*éô÷•Þ8+3 «fIØùA¶¢�ÃÞ_D_L_L¥‡‡Ô¹Œ|þ0µ¦?]ŒËáø³ô¦ Ž� Ê{3‘ò¿Ø†"ë‚'3/žŠÙ‹ø2Ý™ù•Õñf'“ù¶“pè̱dW‰Þw†ä:>Wû+þÿû)²Î%ÑÞ~¥7�NÄ"Ù¨“û~cÒкô¦]ö#¾#Ù§„;!oÈ&(<1øQ“èÊGã49UÔP\ßæRÙ)‹'�üÁ*Øîˆ ÌEjª1.åð™ñW„Æ~Ç´°}DÒüM–žÒÿpÊBóRSüˆX,­"Ü_MA¦Ƚ‹ëÅ+§¡Ï)û?öâIkmÍÀYAeÿbE¬\,3ºÌÄ\qèÌÿÑÍ�¹*ªW«ó.¼tÊ»sêf¡ ð…K}P«�ì¸3ÿH)Þ|À£8Å5VK÷Þa$¶7"— ¶g{;z0µ Ñ»g�£ç¤µè˜6Kp©g0P‹ø¥ Ä*á&ijbì<ÄØí€AÕB£ÒW§Òû‡®~ «Ôþ¶ÍøMFXXj;Ì$²QLä½X2þª|0‡Ñ/$Ó\Üév“ìf(kDq7B2ò ø‡¨]ÄZÆpË3.ó·tÁ-ï¢6È^3ÛÑR¸~r_¦ß'Ü5è>™x½I÷>µÃ{'iaêê¤O£ø‡rš§àz’TÛƒâd®"FÑn‚SL} ]!é¬Bc':€š®‹‡Ì­a ÛØ„ì!ßۯ؎ÊcçfQö†=¯ð&V?‰p¼8fAÑ‚a‚69¸jV&éšu? C/§œBmí*ÌzG±H*]ˆ/ÞrÔÉ;ÌÜ9¯§Ó¶çâƒOBñ=I£åþÅÝz D¿›ÃƒÌ �õ!0ØFxV%Ó×�Bf¼¿~œú} ©yô£ÄÿPÇÖĺýú6y>ýá:å1[öúŸ­ÙË`¨«e†Åõ0ÄÌL¸"´Zü!?ŒÝ2ãËûô=§ji� W§„²�Ðz/WcÑÇH¢4`jtGÆaÐwJ[Ô�–Ø×IGüNãðκøg}ø—ÆU˜&—á‡så*qòB¼6ê”é×Í;$S×I}˜ö°lM×®zN5Ì=¥ùy.fÿDÁPö� 3½ §0/OÄ(!ÿƒÐx²±+g‰âÏÒCÿ$*ž+ÏÌ•ÿ²Wþøq\>“Æký—@¥@ϦXÊuºs?Lÿaÿ—þÍHø‰€b³ÌÑ.?ùrõþSöOö/ v ¿æLŸé ßôÌ0 Þ¡ÿ‚h�+ˆ%ï�þÅhzÝu;Ãþ±þÅ^Ì@=š4Ü®2þºÁþÿêî�Ó˜•�ßýKÝþ¢È´ÅÀ‹±¦¢†ò@”Ûï)ÙlÎð[ä™)ËÜÿgþÁþËS–leƒô²;HtdÊË®f ƒ’Vú²Vb½¢8«£¹d6{Kì­ÎŸÆ”ŸRVì+t�»þgéÿ˜f÷È‹d¯6Ù+r~ž"çWrÍ%ù…¿ñ?uþO×�5²¹éÁÚ~Ûü…Arý�ýoõ-.L?X‡cæt¾H?öÏýYw¦Î²†>iqsãøƒÊKMWxÌÿØ� ìÏ̳ÄzÁ/èôʧúƒJ«(@‚²œ�’+j68©ûTXgU=¡ÊÖÈ\¯KRÁÞ`¬µó,N9–e|Ñ[/3‹šª¨©SEm  ï(n“J¾’ƒ‰£pXŽ»Í ùWð5#Õ ^¿À+½ü Å?ƒ£ÌUÊiŽåÚXÌ�XÁü7€å—è_´þáè1~Y䄪ùiŠÃºê}úêžöžgðú?R¢z‡úJ¯SoôÉ!¯ Ujš¤ÜÐyˆºk0ôÈ7Uû™+§L¸ò,Ú­ÑôÂ\Ü6Ù%ðF[x·ÈÎY…îw¯xµ±€—du×A¥Ìqq¯õ"‚©5 ‹Á¡ø=BV^l´Ï†² ²‡åÍÃó�£ø&$/¡äõ¨ì³ ¸™„×Ô›ðÒfÏ/FÐôcµÜg�ø}wC†!ÌÔ}2œ<ú†^Ÿw ³_/0ÖÛfá?~= ÍÀ&kÉþ×ÖÄ�ü�0™ÛÄs;O)Ç¡íɼüOá·›øGÛèz~cõ,Ó¬2Žé{_~»¼rtÈÇÓóO©rý?WÇ­AòdÒsËOM}zv9eEh‹–«©÷,î‰g@Ãp•ãôåñQ]°ƒ*LðsTÈöVP{úÔ,“vFîV‚o!EbðÁÐÓÿÿ^ò­%tÒÏ2Ø•­†™DÄ©Püo¢T©R¿¿FTÇ3O'ß®æH±ƒùDô&Ǽe®b=g aÃ1÷~ŸGÕ;æãÚ9<·§Ùë‰8ôáæ:‰\åM÷‚½¼C“¨z“WðvùÿZ¢ ÊÈêW~¿ÁÔàêΤm™s|«¬e¼:x¾)~¿køGÛëSò?¨A±º�àOÛæô¹ó|÷mÂ4ôwæ>�áí}= ý¿¿B¿ó,^_îe‰ö¿py5dÄë+Ÿº)�bÚçÑ‹ÃýÁZiË;Ð׳1ð帎a²fý,hœ$ÃÛû„·^~fbÌtÊÇã˜ô÷a3�3á+‹˜Žƒx,°¨[§O0PŽôýþ2åú+oé~¼Âû‘„`b ù�®Ç¼W mÕô_ ›%¶òúõ=yô_쇡ø�ECÉ.^ Îà÷€êJu›±uÔ�‡Ì:/˜&S¬î´‚n”ë;„í#Í#A„Ôïî'"Yy%“¨ÜÔ²X«!Ø{‰Ûw|âù†¸jvÓ¼D÷òN5êJu :’¼�Ó;™Ú|Ïýɧ=Ý V‚ûÆ-c11�‰§Àaÿ?óÿKlÜ#ª˜K"µÂÚìÌÀ”9Ÿû²½ü³ÿ1,¸E¼ö™?©ëVmް³46 å�[¯*–§*àyVV`W”‡ü¤>³w“8¢�fJ/É ¨Òá•ùå%>™VöT{¡–’á'þX@ªÜ “0Ø T¦/¼¹æ�d÷”°7fWNN65 €(¸{¡ÿ ùYAm=nx»ï?õfÙóć™Ì‰‹�™ë¬ëüò¸c¸3G¾ŽÂÕó”G»±Ó­ìÏ óf:F¯J.ü>�ÛzæRÄÛîv³q` Lã‹¶`³Hê2­˜t€B—rí Ž‰åò�Ã5žeÒ^gK‚^È(Ù+ªFº#-Vy�×¥ú—�CÒã~Œ»ßéG¾: Ëð,íRß½h.ë‡É)ó2ˆ>ijZsÔ?ÌÀuðËdH¹Zô;ÿñ' Žóÿ"ñ ÈRüL×O‰Ú|NÃâ$(50ɨ€›"¹Ôˆ*±.*\¶:€Hj/bl¾’ôèT­¼�F¡%D§IRí’ø =|ÿ…?ò¦ í'þd½þ©ÿ…5‡þÿ•Š6Y´�G«O‰ÿ�?ñ 5®³P ¾Ðÿ�ù‘ Ä̃´kçЬ·êȶ;L^˜ÄQÄÖ0e–—oD¯8]ýbàîž#Äÿȉm/z˜ Âw` ©‚jd%ŽO¹N:­ê�8èEX¾Æó™Ù|KK"&OÄ-‡X¹[.+6E^¼B¼Õi�M¶é�ŒãI[j\ÁcîvŸ²ø‡Iñªèûe%Cì;€G¤.®�µ› Ù0"¾à� CpÏ“sÆË±˜õ¬èãÖ¥J�¼¨,jâ‹N#P,#üÍ™,ÌIÚ·ÝšR} R� 1,è#š°»ŠÔ&ÐôB ½<ÄNq¬T \XUóï9€¬™z Ô™fHË,ä‡à{@‡â=>ÓîqÍf}¡T>†ã³ü7óz�þŸs5b„éé/`§ÑÚ jÎ:‹ d¬�¾ÌÙô˜Òý1óÿRåÁÌ¿Z‹¾gìv}k .�I§ª¶w�[Ã}ÿ€~îž—ÇÏÏéþæ<Ó˜Ž,T•? ÕÌýOT£Æq9«Ìê_úfhá”bÞœÆ0ýæ® ÁÓ2šåh;AyÌYnó?{pàwLèùœ“…:LI›Xö—�ÈÁVoÐú¾ßàÆ}Šš`]�¹¾bJ1�æ* ´Ïù„«S¸f†c“’àôú‡¦¯/ÜdAWoå!XÛ‡N£ÙQŒÿQãárÀ$T\Œ S5ðMÆù‡©z(¿F4†‚¦‡£7E£Så(ðq6›·Ž³ fuuté2"v�„ÙëËǧÚ}ú;ŒþÆ&x›O¹‡óƒù ³é¿”KÄôsVãéc°´�QÔ�¦Ô5/øÿ›ýz’±ƒö»>•.ŽfÆ„eǬïcq÷"_£‹œ�îfë™’�J&ú~R½ †t-ƒ{“»ŠÊbTëÒ~�ª W©Ä «}ÓbEŽ«ý³S¬¬'56íÔ£ú7 c†UÍ‹#a”%Öj"Ãíó¡ ;½‘ ñ‚“Ä6| †)‚CÆ£Cô̳v„!¿�Û:ô®žŠ™£Î!±1Œÿö!“´?³¡*Wh%%ÌmÒ5©\„úPâý Ë¡«}ÄWIÃÓ‚8Vl“(>_êlgTº1ï�Ü­½²ú ;¦;n�+{f@/8™¹—,âÜ55vR`bUêË>og§d®ñ%V¢b+!è¸ôçãø,.ÄÐ f½Wäûõ"ý]?‡à‡ÝQ�‘:À+¬àêN ²¡òß¡¡Óí‡äG­ËøråÅûºz\Ë)ŠBÂ_¥êOÖLËŸ©÷E.Sú¶„,8“µ[,Þ2ŒQ !s¸ÿo”³sžgˆ–º®%5ÇÞ]) ¹JÍÉu0N÷æfaBžð{c¬¢?�…äJaª5þÓ"Œ<óð?SðÑÑz´ÂJ»³QÛˆ¸™^`¥š‚,?>·HuŸ®6AöâÔí²u®³*~×b8!*~‡fVˆï „=C/ÜGßäjÍ�vQ¸"¹5 ¶³NÊà·ó½EÙµ¨jÕ@ôe:¥ @•q å t`}‰”rCªnkÐ…tŠÏTz^]# [èf3{‰žÓí˜ÿfT§I8˜€ß9Ì0…®ÇO¬ÿÐèùp%'ü4ø@q " XñÞ&÷òJé+×䉞y”ÿÒw¾H?4.Þ¯¬w‹ïª7ç9"�Ë*ä!ü ŽXææ. '¶ zÊ·¿š7É€õù%:üÒ�~Hs_1¶ìû§þ¬ÿÕ�V a¯ûp ÏË?öpA éÊV*ß_݇eÒÛ–.) ¿õ8¥Ë!°¦n’QÌóò•Æôsæ²XÇ€ÊÌùPäUâßg?åOýd=¶ñnŽEÌa•µ‚‰� ²´2 •›1¦ñ-ºÄ üó”ù²†ùAÞm[õ…-bÕá´ÌúŠ—wÁ9îN�xƒ#¢’AÄšÿ6[�®¬KŠ~OD¦Æ÷Št[ù�¼ùEfLäׄ¾mYˆÙ]xjRQW™ƒ4rþ™Kp¶Öcß·ˆYÔ‹±¥ëßpQ˜�Î�“E®­•æÌòx¹�‚Šô’(:ú ndÍ=ŸõÇJîí1?¾3ýP/E íQ½DG4îD ”rw›õ[ò�«¹‹ûfõ¡X–¬ nc¹”:”€Ë?5+ÖÌÍ3ÁÉM·©S˸R�!‚¦kÕ@¸Ò±r–gk©Í¨qöš=|z~âmeÓÔŸ¢ëü?s±SñÃíÿ9uœ�àÎÒg¼Ri�î}x„_ˆ}1÷?‡ÖõOÁ¯K—Áœ%ËšŽ¿¨¾/Eú žÕ÷+vpÃ$±ôåáýúâ?cû!·t¸@òÐüÊ'‘_Nˆu¶zD¨¬ãý‚ôþŒMeÔÜ …yy–ÑùŠó¯²\£”´¦è=ÂhMæt58‹oˆóí÷@÷\8§y@qi¡ µ¼ê+òSï&>¦Yƒ�÷¾æåCu?k¼¬@•?RD43@ÍK뺨GCÓ£ôŒú;Ê~‰LCÀF6al‹~ßQÀ M 0cìú,íL•-ÊÀK=7Ì3Ú£Æ39ôãÕvšñ9yôüy«ÑüŸ‰8—ÈD㬻<;A—x„×Ï÷_ÒíèzÕ#~�Gð¿¤è}#2çòGÐJÕ3UWL§”æã­^È}»Ã<çâ Êt”Œùf!G¥ká÷(fPÎÃËú�àôÔ#ݘp‡‹ôf'ghm«#TñêùÈËÄ(Ëø)@±ÓJÁK¼�–pv€èé%m]9uŠ%[~fšEÒ=.Öõf¯;žš�ý8ó|±¤ÃsÆUøE-ܘöœ3Ìøñÿªn¡Û42×pŸ¶jv›üÇmãëÐXðåóè·þÓ{õÖýæè†}?Qž±ÙØÌ…’³²oþÎ"™×cZŒ$É ôÞ*V †jTUA7‰LT/¯¤|ÅŠå˜(6@†3íÆÒ�SìÂeÄÂõÑ4x:³�hôHZAœ)™VS­C3d5ëÌÌåéøÞǧÚôS@wˆ^ÏîXÐü³#¶·*aW„'ü¡Æ}ç‚ížÎkÿ6W{¨L!çÚÑ®“>•„vÀVãô_ì­Ÿ½Ï úë7–ÉÄÁÕâ~‚~²5¯‡Iúkâ„‘Y °èš9|Ê•(‰ÞWy†‘5cÞ#yy ·h®�oûºþûۧ͡ï¼_?çLAeF“ö‘Òüe'Ä,WÑÆAí>­ÅÍ^aÎãUW ëø• ë¹rÁïê,� b„W×?Ôͽ™…šö‰ÖbksewŠªÃÜ•Þ/S=e£ºaæ+Õ€ë(&;0–(/æ'E·Þ *Þ¿ø™£ j6~õ�Úòñ–ÏÞ¥Ó§ÝþCþçü›KkŽ›{MLbsÎúÿÈ ٜ©±yˆ”©Kÿ1·öOûWù2ÿ{üŽÅ –¿ÔÁ�—þCô_Ô7}^?œJÝýSôä³÷}GŽâý“öêugˆÜje¯ù–6¨ê‡{ÔÉ5‡ÔÑÝüJ§ñ(€pöF�ßø�íñÒS.>Wù¾�wô~%`ýÞ&ÈåXnWzÅ>- äx`ÉØ‡²£uqmíKèþgêfSÚ¸xÎz0³* a`N’€•LïáU ôeÉ låÖjŒÃ0ÅÎ=W>Ž^›üB@¨éjèn5:óWŸÐ…MÌž®e0ôôŠooG>Ÿ“þ˜}ð´òõâ}‡ðü8kÒ霛–Òjm϶'AÛ|Ãu{Í—Álôãøqün_¡²?ÁçØþŒ!".fXN ·W¬Ñ–„znÌ͸Á$ÄST}ŠhAʾƒûŒÉ¼�é‡6éÄOcðÞ"hH,÷‹SÀ`)¦XÔHÌ3Z–¡0§æf´Löf™ÜÆq(÷¦nž&·yovÇÂ{’¯Öõa¹â_X(�Ñ#ƒW.s?!4=èƒâúƒ0¢ ÒAÃgXoôé•+К®XâìÊï‘Wy¥¹}%z(…”‘*tL¡‰O§séˆÎ‘*V}a6 3©TÔ4Ü‘`ôÔKë2Y0Œ·�»áÂ{"œZ¹Ì(*~õé¤üY†âüaõý^Ä=qöáëÃÇðÑüq÷ü?Œs/|$"�"/ÎŽ'Y”‹~~/tOxð|4«êDbÁÜJîÔy†#¾ºJ€Å¥�Âæùžäþ–óÊA:‰8ÐºŠœ;’0p ¬h‚ñå•+Q°MIPo1RϤ=%XeÿªŠéÒñÛ]±¹ ;ˤcÂqcÌ(ÛŽò¡l=rçãJ?¶›²ÈJbÄ4˜ÿâ>©­àúÜdYÞ‹í6Âz— 9Ðu!õK—5ýƒwÚ̺ÃõÝOJÌZ'äæˆ ÅVuJ—ý¼Dï|uôªÐÎ04>Ì_^ffVÚZ>QS{† Ê?Ô¡Ù Pzrêzšú/h¼Ì3¥Ë=B*ÌyNViC¤ªqëI¢ã¯ò^Rª€ô.³?Óó?¯F uÑdvCÓ‰ûˆKôü#ø^'ð}ŸÃ“ïø~ Ðþ¤¨#BÌL8²3WÁ)ÓÐì”Èm¨Ëœ„;+N¤)“Ì8ˆÖ¤—¥¢pÀšÕÁõxr�ù�]o¬`På‰d3Ý;BÄT!Xsþ½b8ç‰ÅÓû ¨­c~�Êý@/4‚ßâYe“ýC;Q]HÕòË6Ô¨ò¿PÓ3E¬¶w'iƒ4žIÀ¹Í¢"T#?&ç3�Ñûš=!~�Ž6hüúäHR^ÆwAGì̌깡úY=á52éÞ#‰Iç SôûJ›ÓÐ$ŽÆîH€f�Uk7˜‰F Œ;&Ê #„[n¥\Mkцd…Ä8—TÓèÏu/`�Ï—Óp³‰·yÄ¡šñEO§ë�ôýŽÞšT­Ã‘hêà™!œï4½Ùÿ¦ô‡5ï>ÈÓÿ�î’ÿè�KeD~ïüŸ¦ÿ'é¿ÈžÊ˜-—ößäÿМ€ç¬Ì¥¸¦f§|æwòÇe)æ='Ê_íRÿkú–¢( ¸ÿd¾ŸÌe {ÌÝ蟭��ƒpâqšöó8¯”ªü1~|˜~Á#Þ¿‰¨ÙŸ¨z" wüðý‡û³íU9/l+{°� ¨ý'úŸ¶@¯-xGRkùRñ1íÙõ¬ïÒ‹ú´•³&ûD_WÐÇGÅ.ƒªZ%ä'X�K¿²JÔbg¯€¡é·ºT¬JôC^‰, ,èûD’ZÙ<Ì6@"=ãF(êÎö¦dE´x–j§_s‡ñ´†»eÊ:Á´ÓlûËV‰-¥BÔä™§Ê[Š�ÕG^L Þ%ãOL,ø~ Tú„æveLjûC`^ê`Óv@3£%bo\Áî·.ðÿHUËõüOQeÄ»€¸%$ÜàéêOöG¢Î^`##~§¸_>«/VD�ø£ýÌÉärÁOËïцZ€°×¦˜éDÅépq B~êÂòzo>Ÿcø;{zðÏÂ=IjÇW𼉖“´EAþ�­Î?�Ïð&Ï0´:ú9ß® ;ÔM=ïæ)%�¢¸ö·63E°sWÌYyर/¤)îõúŸPŠ y|Á¹žØ…Œz@4Nj‹ Ãö‡ï4`L3ŒKrW\E£Ÿï*mÞ«5HÐ'þÑ6•F Ÿ°OÐ!ÿ*5L¶˜ÍoøÂ  óPÀ÷ñ/4Qúüw‚£é‚ªÌË{ըëÍ?¯Òÿ½mí+N ÅËß*ÿ¶s?*#�¶äQ=>X]U9Ö>x󆼥Xñ ¡Ò bã™—ÙžÌög¥ËƒèS�ľÒáœ%[?‹´èI ™x•N[Â#gűiÅÆ€rfš‹³Wõ¸eÐæñ(eùÃs¿bWŽ Ü !ÿggJ™Ò"©±é(;#(§Ì#� ªJõ‡P‡\Š1ZcÜU4̯Rh£i¤L¦pyœ±Òj_ýb‚¡¦ WU\N››¬‰Š�‚Ö^L\11èçY/¿0Cd*dƒoÞRáP]ø�çó‰pw5°Ê•ƒD;K­‡–^íô@'jK‚�éL}ƒÌÈ"6tª ö2Âïéy³ÅOJŠgð½F(_÷ŸàáÐKpF»ú:”.“aÞ~¥�ÍÇO&=9Äï‹]ÏWÜôt8Ïó÷8#µµzÂQ)˜ãÖL€nw_Ãî—ë‡Çø~bõ'àÿ _1sëËÑÚ‹ŒÙLôc¿[œ2ý.\.¹—.9�mu`b ¢Ô[DWoZ|&#wz™Œ¸¹`è*¦³¨ER«RÛûfc¨ü=Â:á¬í©ñ‘–”\°r•Æñ.)¡Ì*¡L¹�°ú—ëŒA*V'?E(h”èJt>%zG¢%fm}¡Â.söðebýæï9nÿ/Ùú 1ÁìÌH3”*ûÎ{.}ãÒ\ÌôI*“°îL^Œ�6aÛWX‘Rií™~r¤º]%iòŒY|¨³cY@ —M¡gö%:>èÛß3q-`=.y0ì[ÌpS’¾b’¦= ¿R)öÈCýå¯û¥¬8÷yŠ[¯ÞSÿiMtù(O¨h²nóϱ.ªr�úËœzq*²ÏÅ}vó—òô `clÉ'qô4¼¾ƒŸø…ƒë¹çø£×í>ý.\üô5ü4ž�àðù}úºÄJ�=¥¨åéšu_̸)â9L»úòô¹dá¨!ƒM"iã$ß`v%´×Xn9kè Z K´æW|9�mú, Vþ Éuïé1´O¹û€\¨©>ü%«8‡¦^/BTäþ>¬ÛVïþ%Ù BVoøq?þ ÖG™�u=ˆö ûb€&�'ߪ³Éôó!¸2漿¿¥ú,~a/Ñõ;ŸÃñÙ£ÔÜüáŠ/—ßð=ÍúýßÔ¿§1ëÃü]&¹F¶È4z¾¨$öØ>¥2_†å^è7n-ÇEËÀ9ÍÊk̶/¦¢å¦®ul�ç[†nQÍ@�“�ê+Ø‹*d�Ró.Zåß�åŘïÊ—51«€�Ekˆ—HqÒu+C–ñ¶pqŸªnΤÂúÂdÌÃÇïzjZÑëG^="É J^`¬é CpÝÌ;£é¸©‰ ¼!;û1fH*TÓï÷ ÄqØù„|Àa}Ué�Ž0ôvGgªÓvõX³Œáô”+Ý æ¡¯@òéÝ‘\˜í*¸ÓÔÆ,/Èa?[·§Üzý�BP�Þ#Whƒkí<Ÿ ÍG!Äí|“ö)æùE1¢òéÿÊgÛò™¶ü ¥:8™9:KÐ?;ˆsO'àÈà M�÷Šº)ˆV¿–éÏýXÝ‚¸±ÖíOýéÛ|Ã6û�§Ìí>e:’†ÆB¬ïA)±ˆ‹¬¨§R(ƒg™‰ à ø#ͯe1¥Rþ‹Ýbc¿%ÖëÄÔTâ»~—è>‹àýà ”ä¤"‹Hxˆ©ÒYP#Ã\£óϨ¬1F?Ȭ†§,ÜìÐÇu9GÔæsâá—;Ò\-Çw³¡Ô¡ÌÑ Š‰KÝ0z&,h,c[p¯0ÂSv©¨(Ü ŽnüÁØñ,Ki u…Ißê…•Ig2ñP)i™*6Ù?î–c¸ÓS©4ßp쀸Q­M7¤2Ö e±Öáé?ô†î(p�¾”ÍKf’ºfÞaÞ€q2aR…ç~¶ aÌ¼ÏÆ�¯N²ýn‡Ä}²XÞË©‰Duuzdˆi4ÝKÆcœ�ÿù×ðŰ"‡à2•¢ü|C¸ÅK +ÑÇ{ûÿÍþ¿€´è'7Ϫø¿†^FÀÔ,Ñ(èNÂ0ážÒÍüíü>ŠÌ1.;Ãþ4ÿÁ�Fïs> ež%�Âó6\e¨3ÕEƇ£ÆsWh“'ò@¹y›)‡JÌÆR‰€cHêÉÐfM`d ´éÌNÂW,n¬ž-™hÈ Z̰AiX·óqÎ8¼Ã»Ê”G6"Akæ®øLðoŒ.yEM¦óv:«¤Ì¨01“=f;ßÚeVìåW‡Y@:ÄhRãÄ`U(ròç•e»:R’“„ë|#˜œæ(¢Ï .;¡”²ymÄ^Ëæ,a+«¶ñ{AsƒHûų›,�cЊ Šë+˜½Ÿêo‡&mû¨«? QW pâ9á~ U ^Kþ¤´�ŸøNÞñ ?£,V±+ê Ö®etLj·–At›2ÕO ÅNo?öUÿµþÃ}ßbÿfJŠºû…ì¯ûÿìWýì}r%F’ÃZji_�ƒþVhÍ<1\V a…�û�ìeþÌòø±��xÍÊy?)Ù�ºsã4GþßüŸûÿò§zÏü•R‘£¨Þ�²¤x’ «   {1�t`±Í?®�½º¡£»Žu�`…,fÚøŒb:›.õ ܇úÞ‰S}ƒÍ–#yz™gïvšKÜ g™Ô0gä=9ôý®ßÃí ÊÜn_¦H÷þ‰¸ì„¸AHãÃ[þϨ@·™ýb 2â»™Ÿ°©�â/Ó’}Çܳ­ðw„ôzKâaæMPõD¥Ú\´¢]ÂmAžéNh—qTFÞÔ¾±ªÄÛ&–v|CÀKö“¢£›¨”2rq²eâÌÅ›´mªªŸS3ðë¤\uþª’]w¸ô¢ø‹æßQ9ðÅôà`#~Ð.e‰¦¯2¿ MbÁ»À+ôc–‘ø#±¢çYaÇÌ[=àëºÜÉØî4VÏd² ÄåÔ4L‹êÄþ¾ÒņùĽ¥lÏÕu!’å2¥f+îTñÊh‹÷þé9ÄYhèïô;¥+Àë3‹æ&˜¼¾á—´j¥«3ñ_êéHRë$¹‘œút%½pOiÄ¿R"§g'Ž"æ^&^bªOBÑÏ.\±½�0ެN=?/úŒÄ.Í@-Y¹„'俨Ýc×oÓ^—.;÷�sꨑ¯_ÄŸ‡ên+ϯðû>· ÐGsB ÓfZàÄý+7Qò:}Ë�âvÓlˆØ©Á5L_F<,3‰uÍÀqm K›–ÿ§¢‹ßéf;r§=ÖáC;wêüÃqéxÄ¥0ìfðTiÆêu¿¢#¶c·Nc-“ ©pœi^¬fŠFâ B¶ûC—‹kÄÄ®¡3€ äŽ�úâ]­ÕT#\;|ÇÕíjñ2³ Ÿð!j šX†ˆjÙ|øUÇêú£{>&?¹Ðpf÷"üu—¦X3 ƒxA¨¢Î™Ž®Ñü/¤ñ/0WÚ`ðK‹ˆ\ͺ˜‘~o¹tùŒµ®bVW#è."í.?‚áøú®+iÄå„@ky»�y`clªÄÁf¢.™H /ú–Áþ(v$ðÅ‚\áuAÃÓòϨ±òÊÛ.`܇Ì:/™©*ÓÿJïN·Íˆ|¡ÿzv“²ù—Òƒš�Ø·^ez�{« æ%©lkÛ©gYs… Sðý,–Õå÷._£¿&\¹sÝSûƒZ�1äæt¿Y 3é»É÷ Ž6„”„_Á/2åK+7ž%XRÛ%JXËÓÜ•\ƒ˜Ú¹Ïùô'xAi3yüž®›ús\ºBT 𙤳lrfø‚w«þ%•ĸ5¾±t�HÆUí3wœ!˜5À8™\ík‚E�×6ˬTZ̲Ò�âo‡J+•²®¼Es†7ÑÎ38œý)á¹­w]`㼺Å`þê`¤Ë{ŠƒÞeû„p̨½%žL@%â^"àóÌ»ÁúG%qz1>?¦S0`äÕÁ�›~ç$Á~b@À4‡•Õo¦Ð…áÄYKûRØE ·í+ ËeGƒ0C1ÔÇ¢Ìt!AYœÃ´rì�q=/N§=£áœÏÉMQbvzÇö®'SÏyKÀÜ*îЀ²‡3ÿ:t¾h‚Œq¯‚vÿ:t}ÃðõÔ±¼Þ'¸ö‡@Ý –lëª&<üPøãJnºOü‰}_Ãáá‰Ï�Û?R•iùÿ©”Ëߪ~÷?Z�ÿž±9Àºü£µ°Îx˜âØ*‹<0 ÍyG¤Å&¼ýo¥µW½ˆ¦ßÍBpº¸§Eñü‰•öµþN¨ Žh™Q Yk1Ì@Yc,ÄÐVwU~È7ä„Zù»BưÅÿPÅû¾gGôyŸ°ÿc,~S¢i³Ý+åB;¡Ò!T4ëʸS}50rU°êÄû[½ÓkìŒò½SSÛÙ�!þÓÃ;ÂU¿«$¬dWºÀܰnÚh–¹­p¯ò5O,ǰ¬,@õù?äkîP:+¬¸ ¾ÏD`ÁŸø˜Gz[—/ŒfRðñ”ñ—Œ4¹xB3¢ÇTZ½ßý%–þoõÓø#Æ b—Žý¢f}?¥ÃåkÒøPèù¢?"i“9íë,Z~‰€¯Ÿ1Áƒº_*]‚2èÃfÙ<³±@«›¡Ë­í-ÒvÿGh>�»üŠ hꆒÇi’…p†pÏ„éÎa„¤ø‡ŸÄ¥müKy~ 7�EÄǯÄÍ´€‚ñÒ`ËŸLg0¶c¼ÈÜJ̲¾Ò𤧼]!ÜdÇ¡´9Žq x‰_™?¸J¼mó(Def¤k–ó0ô˜½ßÒ =æCøc^—+é†_¦­èþS¯ÖúOÉ>¿‡/DRÞ#M³¯åúƒsg§£üþÐn_¢áñ(ÔÍ=YŠ:}Ìçіц¯Ï ÛP°©Q†Lû£vߦ™€²Ë~ÞŽ/˜à¦Ú™•E>Ñí­G(ËfÛÄâò§âP§ñ(t‡ gh oK‹*µ{¨úÓú³ÆæaÎ12—�ÌŸ²e.¯1d×M*=½FÎÎF!ƒ­K¸PÓÐÔk¯JeJ:1ÄÛU4耬ñ8ñ, ýH·ûsP~Çö�ÌqPuÆ5+ð¾’ÌEä€Zæ?ÁýÆ\Áidn;TºÙ »F4UŸ¿K0¼µ?î—ëè¸>=²³£7¿�øO¶cÑ$sée‰jµÌ{JáêÜ¡u¸.c£Å./Ì*Ÿ6˜ñéBmsæ bñNߦPÅ%¸ÔRÛÞq7¢Ä¬í럃UOÚ6…«×�º�ͺŸ'.d;Ç õgËèwš—{__Æ})úœÃ—§¢ý`ËôøÏMOy¦_ûE‰í—/#³í‰7ÌÇ”YuN?Ãá"¬½É¹…;GaÚ2ÒÃn`.îs7M@£Ãñ/ÅÆ.w({Lah³l¢5’$]zï ¹ñ\˵6˜¼ªZäT ¸oB_uÉ.’Â7‹ñÃâp Z”wÄÆ]0¾’à×%ø�KÞQbfY|\uØûÓ”»Êœ@°Iñþ2èË…˜Ù¹wîbj\C7Äø�¤¹Æí<ÜðÔ¹s~²s2àú6¿Lz\¸°Ç�ð}Tß ‘oª|}Ø÷*®‘¬’Z“MBKë�·,u›#ˆ—>ªãÉ¢ÍEñÎÐR@t²×Y sN© …º˜ô\¸¾'ÜÜüTl9ßÓÝCÁèҦŋÒ-Ž8�YæôÄ.\¸LÑzЉo7G¥ú\•,%7è}÷"ƹG´º›lû‰FÅt‰èó;¿)“Lu”ŒK‹q^ÚŸr\¸¹'ÉþòûOÊ_&8ã‡á�¯3¹è¸ÎàÓ2™á+ ±¬ì­æ- ò–Ù€{¹�ŒahÔÇF¥8fY•Üx|s/L¶²àÑhÇä‚iž] X7qËQ¨ªïP¨ \fôfX‚–Y¹Â1.®zJvŽéŸC¡Ì©áE¢iöÇÅSC™ð¡‚&g¨.ZM ˬÄva¬U˜¼ËµˆAph‹fxkÐ�sd»‡ºÖ1~!á=Ò°×y|:s¦[cxX^¢{Ë©9Ž©Š1v¾*=Fã¡@³ˆRŠjx&>`5jëAð�ŸñåÖò˜jŽÕzŸÌ|ÈLGM×Ä{7/C˜…>Ç-Ãc¸Xò½Fã+1pï”Ä-1ßyu¯z ³:ë.¼RЬbqàqq_Õ¸`»#6-Ê:{b4\bZ©€5‚šÓÛòœPóf.a�9n`ƒPíè5ïÂPw—µøEíç´kn.Ð0Á)“”¶U+œ9#I‚cB_¼@ò¹”ÆRc€OjoŽd´©m¡Sy— �#LLƒ×™FwZ=Óq5ý‘ßñÈ$³£5ï-N 5,�PÊ™÷†Ä£Øµ*Àµ«¤CF`°«œð‚ `kƒÙQb8pø”ªêðê–œºI’6®å6Í%)-ÖZ(‹ó›/Sq?Á)³{D9˜ÕŠÜpNa ³q° Çá"¦�À°Ó¹ gïø §š¨oC(µÞX¼¬8öe·^ÔaµL’U­±aç•Râ ¨2ަ€Æì„4õN¦ŒŒå:àš”� Íe ‚ÙÃ&f;‹ß™CLd…¸úOƒ)k'¦²yób'hBnì°ÁÔ˜NxksC¥0c �ÄK€Ìh sR�Ÿ˜•nž"ε7ApåN³^ŽîZ¨�)sd˜JÞ'T‡²½ LDê:&@{0:Ϭ9Ýcž[YA'W’1dfÈB“QÛÓrìÝêùˆ—®ñÐ.ŒÀÈVÝ ±ÉYèjÑgˆ—í§xµÕÌî�ÜÕî8PÃ�ç‰^Ò9Žš7æK’¸Ž êæ ,>¥õ…ÌM‡’‰“@Ý¥ØUæ{Ù¡™Ÿ*ÿ)fo¶X l˜PÆÈ8+ä‹X orDþbùSCp!eò¤êèô™`sC;”÷-—dÜ×s~ô¤™œ‘ñ¨œ"–JL“ŒH‚ MšŒªˆÁ½î=eßKÐ0!Eg7/jì:36KÂVa’âž`…ÓeF _•¿ÈKœ•rÔœ-0oÍ/Öé–Y9ÏY¤¶«1Õ”ªeƒåBâ ã|BÙ�Ô ›w;•L|oó,#´ÙsΆ*k‘¤½,_'^òöQTù€v‹³6B�rX×·yÛˆYzº™Ç 2ª�²Vؾ!nÔö†7¸&HG¡\ÚãøB¾ârf ‡8‹pr ŒÂñLÔlÊ)S‹Ü¬fð7(€NSó2ÁÔ¤ÄÚê„®˜ƒjwÿPʃÝÌsÓŠu!ëÌÊW´±šë;‰Xê))žVñ°œ¸qŠûÀ4l›-C« E|�µn¯‚FÈák:ÔÊ5ÒVľuÕ‚ÎV#6ÿ%ðê�ÑLLa͵˜ºb­_ŒÊ7A}"öÝ4œ[œâ½Ö&Ì^zYX �•aê�–Ì‹ˆŽ:•n?w^ }àDá6G“ríƒÓdÀ_,UoyÄáÔUT0-§v`«ê¾+¦ÊÙªû}IJ5Ì¡ƒ}¾IDC€—ª/©2Î2Ç¡p”ȤMM”ûÄðñ+¶É�‡HC„à�m£²\�|Dž¤#.Þo=ù'Xju‹†­”õb2Ú©m‚º@±‹‡R»j~¹˜··)Šæë™Ÿun]Þ=¹�µzÿ‰ŽÏ$S®Ð9\åÙ�éˆL¿W5ƒÑ�¹HïVCã d,Ú÷–”ûAJ]–ªfN”¤–…8Šš�¢)h KÝ J˜}ðo C�†#ô‰‚‡d£˜ßlÍ ´¢U s”ùÄ´ o‰A«dùŽ™nV,iÚ#´ÛË!P9&‚ï+”:Eaë.|ÓhÃI×5.>lÅëLÑi”«rŽWÁq²mŸ´Ì‘±*Ñ„ÒEç(Œíjâ5ó)¨ŠnîYAßHŽž{Á …p[ŨÓ2Aqg5þà¯Ä ý^ã!àúÎ뮺ÄfaÑ(Þ¼AÇ �@j8SÌ~Õ OÁ„XJ-j H[0V6¿2†¡‹ñÔnºß2ÆÕ€ q…5éƒJëˆÂúŽì.\±JÊcœ¿ rLKÝNû‘ˆ˜JÓlBÚ¤¸…â7±îÄ´æQWñ0sXÊʇ=\(¶¿3Fø�CæAЃqbª¡ás –Ö<@M>k˜°DNdÉ[ ø€é:®d:»J‡°¸,–Q/Ž"§RìØy‹B¼JŪç+(ï ¶|™=*ö‡´S0!Kåð•QVL_9%å_äJÃ¥[ ü%�µ5a›fd.°NÝÔÄl:ÈÀ˜Í­�sÚ|¶ã£ýf‰”Ä¢©n9:æ%'+MMÈ£�Ày�} à  @˜°ËI¾“¦¥±Žl¹Àã­‡X†§ó¶.Wå÷ýë170#Q(a]a¤è_̵u™fWZÄä)ePóÓ¬U¡LS3`®ê4Î#fB˜½¨¨·1ÏŸ¤9RŒ,Eòž)bä!ί‰“L5’R€o$4)ñ87¾QÌÕ š£3Ú¹à€szX¼qÌ ƒ<³=‡¼@¹ÏH®ß™Ÿ!׈Ä|!Ç1ïêeEêó%r�×â9ôŽ8—k0¼g\JÚÒës9bº»›w�…©ší-ð#XPt†F€%C«Êº«æ!œ·9¬w<¶Ô3=¶nwÌz�íé”� [xé1ü˜ÉÌÕ+z¹Â I‚±–ÕVó0Ëÿ„¾èUò¹mi²¹š’ÜFOiÙ^ˆÍ]^‰µäܼz‚[Š�ͱlmS¼MUÐ2AÚØî�æ%xtï-lx޶ ‹Ó¬pŒˆiïR7©ÂaÑ(Ö�˜%¥{Ë^ýÙ.ý%ëÔ­ŒÖ‰_Æj³%píjPÞ‘²9ˆ]ë Tjbt]\Í´Õw¹ruš¨0wòkxy…TÒpÁÉ/8¾‘5›Äʯgil=,%ô¿£­HFCîÄ çÈîÎ�SM›´ŠlÏ<}‹1¾°î‰”W“Öì—²\ú$-g¤ÑŽJ\*Vâ°•� ŽFF½÷/ö¬Á£§gh˜!fÑS“©Lu2˜‰Æs§æ:”ßäj†¡�™šA�„1ËB\R¦_Á/BˆôÔtmÃP7ô‰º…ö ÜÁëü"±_QéÈÖ(…Áxï-ïa‚Tž€Ô_@Ç Â%%ðÊyîHIz)—ùÙNL%Uâat<1Vªœ"é8Õ #b[Ìe03Û¼¥ƒi^|EÛEC[nœ 7Mê;8b—4‡¬K0”Ž¥m‡B§_r«­Jo¤¶¶g4Êüͤfp;ÈŸ֎ÏHØê™MRuPxYZ¾&EΪÉè’Ë~s§1¹Þ påœéârGº,â߈Qbª}ÈÖ¶n±L‚Šë«˜º!½0ô+›Ì±Èq*”–˜8+2Ã{ˆ 5Öp1ãr¨.:�‰¸ /EºMàv˯ìŽ;cÆágˆõ¡®sX——å2Ë<«Ä%KƒA v‚§7w¼AÏXÐÙÜÑͰÝO—I™y¸ž¬!‹R6íj áß,¬Ž´Ê$± h²÷fÜ£V¤*h®��(–÷f!Ɋij æ™Ïïˆ<ÜﯴâV¢ÝzB§¤y‹yºÃÅ„Ó> ¸Áæe¶¿©¨‰sS«Žc"3Ýk¬Å4¦æÜBe…îÜ. Ú�W¡‰nµð†<â«QrlÔU3ÊÅJ§Ò+ z1QÌÜ&Lyc(ÀO|¯é¹R,ÜJTIŽ ©v†¿$ 0†¼Â½ëL ¶,“1.�Q8r$ú;”Ê©{.@"aQÑ3.·Í1ª@6¤»ãB)èö›y„U¬ÝK»0·Ç%zšƒÍñ»Ù²—„RþµŸS]j*­*é )oH¢×�¨vÉ]e[E±Q9· µÊ~ ¨‹òÓ1ÞººÌ uÌ ï5-�†ïäë-H^£ é5¨-ŸÅMIÙ˜Jl.âî"|DµT:ƒniuеf[$<á²Ø<œ½™eIÆãë½ù•à€˜T5Ý-æ¦Øšj-m„H–Ã�#_¢ÖÆeVI_åKVnX cè­(æQ¨Š¹�É[Ë/êëˆ39"«²ðJžË^™ŠAjo ÜÄÌ0;L $ÑJœ—RŽem„Tt˜Ào�²Ð¯f`ϵÄR<”Fö°#b ­D¤{‘…F7(±D¹v Ú,Z. WJÕôšp”„‹“Ñnº”XˆyeUà]n2œœ¹�³†Bá­gW¤)Й£‚½>%Ëî3C^ŒA©-a�Öδ[¸í4æûÃI©m%gU(ˆÂÇF FÚ=%$3’üM‚ˆàɬ_0�Ii�Ka�B*Lº“1 áfi”ehq úw�¿|Æõˆô3dz=g ¶0lÒˆ‡[w— !n!ÐhXa¨¦r£a» -x¨‰s°Ë� ?ìË›cÄ8 Ú¶k¼0±\t…rÅg?¸^c³.0œðáá)çÃfâF¹�F“Æ™óíJà…{ ¢›“ÎæÓnúÆ?o”��Äà é¢qù—ùHÜT„¥µ9ˆpÅ#~cchåØ@Ýï8ÜýXº06{G›o´ä€b©a‹&ÃZ™\Eµ®Ó:‚Ù̶âÜyaãÄ./߬̒§ ¡S›à”ðºÊú‡“ä.PÏ,œ!÷•U°tâ-+§´W DÛÝJ8jR6v0± Ê\ ¶`â�ÙÙ”„t–:}ŒÊºN³C‘uìü�9€xQPËèÅhàæ¢=é09™’^zº””ų/F²•O~±š¥ÖVL·+Ïdm‡k–ýEO¨A+¸ë±ÌÅÍî15�gÇI†t*¢‡‰Ýt † ·0íî' :¼Í‘ êdJfJì&´ßõ1x¸Ø¤¬é¥*Ïh"•®Æ9.F»D:×5Ã0.`ÃW‰i�íé.´ßDÖ5½J ìÒñ2”BÄzovò�KqÞY½%å[eጱ¢µÑZ.T�”¡†_v¨Ç7‹¨YYè錔�âàVnÓ5QœÚ%Ø07Ö¾}Ûˆ]"ò—l:µÊ g¤ÂõÇcit•¨1Áƒ0ØÞÌl˜ì+Ã0f{q°�DýÑqw‰/Àæ"–ÙQ㙟73ËìD¬(R3/ΑZô¯»ÌÙnûFŒFNQÍ®IJ YÚQW1“éÎ`µseÄlÿâZfì²O@йbê "ýSƒc¨7Ò&ÈgÌÑÚ Úȯ,´\d{Òí/ںʼn/¨0©úÜ]ËVîÞ"— äꡉhñ3ú¥äÑS0gYHÞ–[‘8îu•w)K˰ÆH+zj¼Ç"ëÕÚ>0½—*R®g-˜`ËzݘàÁfqw¬Y¼NÜï •T9GLË¥_òPP1œÊŒA¨ë-!Qh8ƒ\Cà¦ë�XŽ3vB‚�9Æ”Ã9Fû°g�ט¶yVÞ Ð`!áAˆ-Œ3Ó´(Ï� &qÚtËTz~˜©pP: ;¡ÂB9WšÍAe­È_Ì­HqâÆ.ñt¶¢ÖgÜ@Í$¡Ci‚0"@7“+Ø<ÏýH;oL`©V¬ïQ†�ëÒT+aí>'’ÄÜW:¥Ø Ø×yÞˆ\‰œ^ J©Ã-Í:K”KUë(²žìr&æã²H‚w˜´ùKOxâ ²½°ATvÁ…8€\¯+gß¼.—a ]¡è!]‡ÉW,ψÈjjÔ¼c1—“™Aç ¢.JXXS�»€®ÒÖà•Nµ ìÜèáíN~c½0–B7~;Ì×ÐÅJ˜3¹ó(à Ãæ¬Þ¶[Ãr‘þ£8íØKŠ8â.0å—Þ1â¡ONÕMªr{EZË9²]K.œLy®MÇ@¬ûË!k6õˆÕFóèÒÃ10ÛcDªn,ÇÂF{B¬ñQÕG‰ð”ù‚â¨ëŒ7ÀßxP(œ*&›/˜è *t:E^T õ•†#(u:$Á´7T¶(¢wG)¨¤.ÉÜÔ\Fð�ø–›|"•Ó‰ÀKm÷óoÁ )B‰ÂºTÊ›ø—b ÉÜu½B†ê™SÍ0Ñçpªôå˜w´Aƒ~åkF-é,˜Åcng;¡¶ÂÿS)§ , Ä6x1­%`ón}\¹(Û¯ïM�+G¼t‰b‹uÈ64?—`º¤[2yƒ‘ÀY`òÛ)ûåï#ö6ì’­¾cy|gÃ8}Cvó]+¥y�†´›€ÆétÓÖp3FÅpá+’—dôîEï§e^R…_¹"Ú©Nœ8?™ëÕœMµÅËJû-Ac:P0ºz(þ)V¸·:<1�P÷HEu"™çðÊ(Qck¢š[µC}ëOk>¼:UøÁÛöÛ5¡Ñe ÷yVé“9­×+€g”bþE,œ�_IòŸî` (¾¡Ê2Ù`ÏLƒžë´œöÔÜ›V¨ðcš©7Î⃲[¢*ðûjqØ•Êá‚ @Z̉~E�ÚnJ6¹Y­¶8çèíBÅEÍ45h“ÎÇì_/0õ7'!ËœK?2ì¤ñ.t/ /› ñ KWRòzÞÕ!8s_A–•fÍìÒCñ4÷x`lKTm²÷&OïìÉÏlÖæÝ?.dŒ’¨ã�èsö4!¬ E¯1S#tõR8ý^y{’ò&VciLC¾çÙ-Vv�“§o¾q íÒ¤;ÖöÍÂGyÜ\»®ƒF†ç1é4öW·ñ€ù·ÕWhæÓ•1ÎR¨²¾ˆ!ô”øa 9d›%òÝ jßr5°\­J¹.Ö•ôžš!¹Ç ýyûo­k‡5ÿŸ û¹ECÁ¿|ý%´,èÚ—ªôì2.ÖB“m«C,�ï:¢òç%9o¶­žÓ] ÷ê¼ÊÕÏîñþ½°x3í41s§(ðVr‹ÔÜ{gÞrÍpDÉ_“Xš(äêp÷ÙøPmà ž¼gç .FùžeÅ) øî^a}"®Ct�ÃÔ¾²É«Å°Œ4Â4Jg–HK@Ebûx˜J•¸ŸôëŽ}ƒ÷)*£„ÁÏ’< *íWK3E”*ås4ƒ4¯î�É:sQ3¬Nó÷dðŒÙ(*¡®Ïý¯˜”rZ÷3�lªÁpš“×{П“Üú¼ãWMàÓ£¦wû"øýöÉF}ü#zIlb _ÿø;l5–yFNÚ –ü$oVk±�¢£\úõ–�}Ï©}Ä¿C*¢Ÿ´M`×3õ�¾ÖD3›ó/n“p­T[5°'7³[‰üŒ<’�§ë2/xÃ5Ã3þl�÷Ù›??|ц2{`U„£ÀÕÖFÇšÀ·&˜aRJÆÑTßò*ÐNê"—d¡áøÛ!áZ) Mžж„ü¢EÉß[¢ÍNá¿æ'å© }ñù¢Éʶ�C>hAä‡v·v"JŒeüjþPYÄ|mÙÛö;mE&U‰»ouNèÚ34éóÕÛ¬Ô4¼ ƒÉ¬iHêÁ€jwwz¹ÅŒº¾^H\ó¢L }³ºm#LêÔÉ—ké•0Ø[Ô}‹„ÒwÅPÐ_ȼ0H°ŸæÉí佯q‡•‡¦- Y7ňÇXrû²ØÉ±ŸŠLuBå; �0FþÐu_{Cì:Ú—`s™ºÃ¡7ŽÝùÂ@TÚD2$(#¨Á0¯æ/Ìv:ü r³¾E ‰º³ìâæm¸cÁ Q!wɆÇĆŒÔfºøá]ÚΪU. ‹ít›Y¥É=Øœ•€ÆÙú©øZýh}k§||ô™=öˆsw*²)½\I¸V Q!3®Ê-ßÓoºµê=Éáu±£ùF�%ömNü=Îz¥û$s]kQ0“Ú*«V–#E6ω%ùÄßžG�Ü•@y²V¹Sã5âõ‡Â­ŸbÔöv'„½Jÿ ÉGÐç¯HZµkèp¬ÍQxàÍ‚È6Áë\vÍÈB.¡DŽ„Ì )‰;ÑþèO7±©üoXyx.“ÔÜu~-Óh˜Zo['ŽÞ«Ö!d­À¸d’fÎû¤sOm²VÔº‘I·Y +QnN êXý„I6¡~Q5×`¬š¹:DŠ%ûhAÂ5Ož·Æ ð.È!ò('T¿2R¡}hrÂt‹:£Ê� £ÞHÛèË Ô“½T6®¯úƒPwV³¦‚c™Ès =©ΠҒ¶Â$X¾æ6 !½}£÷`iõÚðSìGšX�IMS:*0\$«§ä!Fý”Í7ïD›þºs¶'`“á"·}Y‚ÒË­åKQ½^&è¨'jû;KÐx|¦±ÈÎ2Š�7ÍhkÄq«Ï�)5¿† ŒÍ¥÷›„!G¯v/ÂÉYÃKÑÑ�É»íPÙh"1fýþŒ"ºZpt&ú=Yó37o(ˆæ•ª¢lãüº6”µ),=èXÙJ÷“wRRA†ŸÄ‹èßÓ[;ñKñ�½ÐÛ²]¦ªâm”EpÛM8ºKÀ¼תbv8ð¿Èöú*)1 ´‹J㻸ØÉ AXÙÛíw6X—i$mêmNMlñtvþÐGêaЄNŠ]uyOû¼ÔLÜÝ%mLWΩiDŸèà­lOýèø½ÜôL÷3½\*E@ZHzËJ&åÞ q¬/™)7¢Ì!ìYçòñÄê^†»9àM¡™+ôÔ’µúÍ” /Š~ˆ˜ƒ!C*R㌠ûççç²è¼ÅGà[t¦ |ê%¢«þDw„o—¿—‹ 5÷�×Mûò¸C{x«!sù¨wå}ís‡{™ƒ4ا¼OÖaÈR¸µ/H ÇGÜi“.c*#v"졹FjúöÚwãûBß�ÖÖ»ÌyKYК‘Uó˜%#˜?…*ß:ÍH¼eá82`*úºs£]ºð#€]üU’"þö³åšBÏ�K)ÝÉÌK‘cÛ´?ýFôè-ýÁ�ý�äLf×l}Ú¡Ù �­°µ�& {õù«ƒ1e’O¬ZÛö1�æLá7!ëG¾A„…Ï‹é wa\k¬LÍyM�7ÅT°ˆüj‚#¡É+8Ðxþ�,Ûäw”2ÊNÙeoî¹bÞ@;�UÌú†tÔs@§4mš¨À¾ÖoGSžh'62è9r7ƨtÖo³WúVHò.[ö` p]Šë`¥8—�* >h�ôŸ9ë9ü©yD€‹°!âüÓÿ~g{N „úén«9ßÐDÊZØ[>«mv@‘Åò$èÄh|%žÛ2=µîÿÒ’®ˆ“úî÷INr}Ín 'žD»t9d�"§=þÛÍX×ÛÊIL„ÃoJNq¢90.-VonÈ —÷TQM« {dJdõ’è¡(éJþýƒ–x×éªï¥ü…å×¶ ×6Ä©05¡R%Ú oí¿ßÿðiû³Äd<oÎM†v&½Æç fAƒ˜¿&ZÚØ‡yÉÑ!¾Mäâ÷NLÑ¥…µ¶åÀû*p½I˜Ž­bÎM¤s˰â&Ñp®Æ• æ,¬" ³Ø­‚B]ÛyÊ�gYbýQhÆ+Úü‚Q'Ám„÷{6Ëïº\{¾ÕLÐeÐ÷°£�ÿ±¨+ö8+çÃy¾H]«íù°Á{ÿ íph|&Zr�ì¶ ËÊMAö“H×OІœ%ÚYºmì{ð�ž@¹®‚rb‰ì“fê¦Q¯þ硚ÿßîÞT+~DÞót!üÏüLR4@|�ó­v*‡v„>«tiü]dϧí¥î9\ëò©ñ6ßø#Á×Åò~mŒè©#7R5Öî‘ËÌ[=J›a?¤­ñ:žXîæEjz¾ ),�¯Fîm âl�ÆEE7S-…ÐóOÓmPŒ8wœÅ YÒ%°ÕÙÉÐ1hBM!õYC†ZÊãÐ’ó¯Vd Øƒ¢.;&^çOo‡’nAî?zµ€×DÀ“Éæc‰õ¿�â³YQ#m¶�'ÏŒ!··Qݵ÷R$Å“ì¦ÊDï2á^¿óÖu® Þ¿S×AEy°™{01·° ’&lŸ$‹ƒ³ô{ØÂŽl>%'·ò}�‘I�êÔ`ÀÎûÐMW ”XÔÚCz‹ÖoeŽjZ×Ö`ÊŽÌ%-±¤Ð¢ï*Μ`Üf¿Ã¥BŽŽ¬ ‡n Ô”JЍn„³äÂëo(2`êòtý§‚ÖÿCCnJ ™†¶˜› ’C´Gæ¾Ì²ó߉Hýä ?­—LlÂ�}°hÐÉÂØ¯ËRë!øS]¸í� t^F»©æÛv&‘&ÞžÐ0Ú>SU¶Õû©EºÉ#ó�دpˆFFy/êiÊŒVõE€"ÊjIó <=•wÍr·Je�6€9€ ÿù2üÁ¢‡¯þã·dyˆ N¨eî÷9¼¼Ò÷t•1Öo ÍU ßõS4"Sø­†¡ÏY³úPúé,¼$Ór#§ýÕy);Œ¸ŠÉšµúRÊÏ<2¦²¾8´Zšýñ듞–“6•T…pAèåé_OÏuÐu0öWñ4:Qÿ´õ-8±:õ¹á˜�mÂyáý•¿›M·(e«*Fs�qûH¼,JÛkÐW�÷äìwà·æ6Ñ ÑšU¹¤mw�m™¬Ò<»=˜ú¹’œUv&eEÄ÷·¢\@Èô[˜Ì8=Kb‰!MTZHo² ¤vgåÖEn$´.¹ÒdÅË÷!³·„¿)“»ÞqÀö� | z‘¢mœŒƒµv§ì†>›i¹85ü¦G;ó6ƒé~ÿk¶pYa®ëÁêÄ¡ImÕì|öFV¤ž_Y¶d];§ùåXC‰µKÛD/•É4ƒ(Jõ‡m 0Øk/ù{÷²ÇÈ$Îdû Úc æ› ÿ«Ú�”Ù0VØ_fµþ@qM² '·TÚUg¬ƒ È †ï„©]$KöúÞA>]¤ÝY» Z.L4¾[‡ V€Øx–èÖÓ‚šß쳿&NÆÆÃZxpË59'Ùl0¬ÎyrJ4…ª­%èj*²ÃÅ×cMŒ¡õQÎøTö[Á¾‰$˜Òk «lÐ…ç|囵¯(Á2êJñÒÍßÜÜ�Ê•Rwû¡™¡pgTt@}:ÓR3Œ§zo!8Éi=C «‹ÛëŒeVW) Dœ^lÇöÝ3šD©o…í[“Kß”#r‡KÊ:[6ÌlYm+ÞÈvÐ9ö–Ѿ³pÝ �¬ ®…¿?|r;üÎqãÀnŒJR³(‡zÙ&ë÷:2š>�óš-TGO+Í„'{_¸p¥†,ØÆŠà}›}§[&_(ÌÑ šóœ�KX™³Ö«gÇ6OX5vÙH¾•èž@S”COé¼TÞ¢—z˜ð·™”hdïõ|ŽÊ•ª åù6T·,vq¼v…é7õ³‰Õ×£áÐÖÐS ˆ¬?¯Õ†_„ÄL%͊ćlE£Õk“az®ÃÞ�ÝB>nUêV#ÔqvJºiÛë”ðz}-FKäÄüfÕã~ö¨½%+Ú`´¼¦2_KÖÚ–¬£Áwc¯þ-2ݪ“‰N‰¨Uéò’ŠÊÐ"ô4jFÖ{…’úBëàãt‹Aãdcrƒ«üE%’¥Ùé(�ßNðë.ú³V¹.þ­~Ñ%äNw ^”¾²¹ÌÍöÆY–nrvíµÑÅh˜ f XäZä MìÆ–ßž ’<ë¯Nv*Óô¹ZýjÃü…'£ù\;–´±¨“=ºtôRR©e³�î&`ü"×z£––èΊD CÛ¿t/cˆ=�‚2™¬Œ0%D¨N0w¸T«²Й˜‹éˆ„qln8jÕ?¶°º6ýê—"«Î‰¹ËkÔœV“sÕÞüt W\85f¶ä€�71˜TŽà" CŽ põ¾®)c¾µÅêFù-pÊvM ëY’Ï8ˆª÷¢ö�u̦Uƒš¬ïVyÁrå�PV-¹nú{PFîó¤-è¶±S`)ÊyD�œÆó¥ñ²Ž‘ŒQYÛbH/¦øÓ�fsö6Œ½c3í>À•VÌ’·›cßb; €•[lKý|‡;ÍÕPËðk eºÙ,ú£zö,dUvƒ•½¦ÀæTÖÊÞPŒ{[´°AG¯¬!ÚÀ7A¿¾·Àº{7vìCɪ_Ëä²Y¢¶ÑJ'ŒÇ¼$¬¸îÜk Mu„Cœ~)ˆ¦y©H=–ŒÒj¬í“P>ˆ2þú/üÙ d‚ô�‘d¢¼Hò¶?�Ôsh3’ÍÈg± ep�ûûf‹N´2l£?טü,Q˸r‰”-ú? ¢—žÙ^„’dñgueÿ«’IÿÄ#!1 AQaq0�‘±@ÿÚ?·á—–ðuÁÃòxÎdutç�~ ¦Õ¯À8É‘HøÆCŒ¯eؘ^!ô°{Y¶YtÉðE¥“ž­™óÏ› 6NGåœd–IlYl<&ÿ×9Û~'ÌŽÉ“C&Y’Ÿ‡œçÅaç,²Ïø<ï}±ðxÌã8ω×qëzI½dŸœì[bÃÇo!»”5²°e>ËÛ-‘F åàSÉÆ~]ñ™ ‰œêwŒD·OÔáo(ûN_Ï|2ÇlÓ�òÊÏùìã?B–[iuuÁ—p"ØÀ˺ ¶õÉ�ü6`ã> γ°7vþÙ?-Ž2Î~¡à{á‚NêÂK,8jâ3§xãeœe“ç ì ç·è‚.ä™ÂG/Áÿ”K9ìmû±=ð× –—×�™ Â>­¬ûÆÛÜ«3mBmrîÆ×Œ%M³“È"Yò8ã­˜üÎdpß/ñ/’ò=ÝZZñ/DjË’ì{ð>koð ûeå–YÎdq� ð89„7€D²ÃÇE¶Í›eÚ ã#¦<¸dË�ïR‚KoÅ~^ÙÆY0àNeÏÃ’Ûú€O$ èI6Ô)Ä&Q á9íöä°Öz²²îèÛcbw-çr’,Õœ[Í„÷oËVÏx õ.[uwd>6ŒaÖQã–©>䇋*�¤ßÚÂO„e¡ÜÏBÛ©i´ÎNüöÛ,³�±»†;-ü·öÿ>³¾¡ãm0LÎpã>%¶Û(îov¶Û0à_ÈM¬<"ÒÒ2“zÉËðH 8Í ll·»ní¶Ò#†,@¾ZmÉŸB„©o«20ò×»X׬i»ˆ'Ù d—Ë£ËO»¢ÊíêC¦öciêé E»¶õ:°°6s-�.ÂMÛž‹ùÂËm±ƒH×Üv_vO¸BzÈ^ Îä1‘–=ÏmCÕÛÛtÈ,ƒŒ°€°áÉmãmc¾3l‘¾q{‘gýsç¸Cµñ.ÄYí¼61Ý£xÛmã«©ãeŒää][�yè’Ý8ñ:–׌ç>Kt�y ò+| 4Æü’zúÚ¥t¿´·Üiíý¯ÕkÒÚž[ý¿¤�÷k°j¼‹xÚ½m”M[µØ]'Op.Ž‘û—vÂoîÌÿr‰m·m·�Î ±6 ´f%Pž�9–òþKu² ^vÄåÑmÝœeàîøÈ˜-rHU÷‡VDI‘ƒ× >ã|·%¼'(–¼oóÃ᳟S—S—\ìê_ìfÞ­ŸŽò‘Õï`9“ÜÛ0ä‹,ML Cnçl·-¾‹W¹ÝºvÍ‘êVÔ»ÀÚÃõ’“É­‡d.0ÏÁ^’ÀÉõt5¶ÔÂÕÛ˜û[Ýà;ÝàF0ßQk�‡»,ñÄ Ru/CË?‹Ù>Ç<-±­ãm»mè-³«m·�—eùoüvÞw–]¶]ç¸oŒˆçulIY·N£ ôÏòÜé²0¿7<¼À–ÍŠX³Ád¯„ îEvëìG� »MÌG[näd™$_—ˆ[·ï8m¯’Ÿm—cƒdÝ^JyfA²wÕ²© ªKíÝÂÀlj ÷~³žá\1ë ÷f�|¾îÞ0ý³ûYÏdý¤äa- >CÄÀ}Äú³¹ èºöÍ›#Ô3QÙ1=ϱ�Ž2~ øe¼? á8êêSä?â›&Z[Ažßå«- óÉ›.–YðÛÕ£u°O^­êÞ¸l°¼ú]~H>¤-ƒué0u´ýHöà ÈnËS�a>Yw5÷–³mÛdþK»m…õ€½¾ˆ«ï à,³,à÷z» È3¨K„��°&éç’»ÈwÔX€´uxÔ¼ßç·cnÞݤëÑžç ]>á#Y™fØ9çv;Ü[Ü„’~â?±=�‚¼€ €ÙÁÁú’Írg:Çg">Ïæÿbò;ãdÛ\m¼öõ×#o{©Ôi{‰ãm·eKV¡•ä·c€¶Þ2Éu�Û)m�þÌ�û òÜgÂ/¸B–©Ï²ã'Ež‹î²«N‹ô¾¤£«ÙI�׸Oe}%½Ãl‹ú²Î ’Ye‹eÛr¾Æ%·<ã»~­õthøFšNÓ¡#Ëܧ­·ŒÌy4#^ÅÜërwý7AnÀ=¾‡öpˆ»˜’ˆX2‹e6éòFÙ—S7—²w7a'äñÜòí쟜draöÃä�cccfÊú¿‹,—SêK¼ƒÔíü�dÎ;�-ýãgŒ›aŽX·`êXàŸwf #ù'pg“ßYw御Ïa^§E¨/rñôÁ�·f‘1{³æ]6y#>[ݘ/®L[°Ž¦cêÆù.Ý=˜�tOYe™v·8lCj�dÃèŽâé½Î‡ ú£y5ÒCêÚEÐ^S$.iä¦ÏK»Lvp–YÞY’>Ö߸ýÈÍ WR¾¬«ý³òéÕ—V‹Ô8w$v’&.³„Þ«$à6ÈþÉ}[Î}ñݼd[’/¼ŸË6DS�»ÈÔ}nÍ„6NR_lÏDpƒnX%W€gl'eú^’–Uœ‘�¸äKMãêºwÁ»!ûöÙ½H¶D}R”ÇÈÏi­ ü”@ò2î �Ô•ÍŸp¡ël¾ïío÷i[딲ûá mæCÞNxp,„±Ô?±ž¸fÞ­»pée�OV|3޹:·àó±dr�I²–Û"I:¶m—âp7h `ë`]ºÙd9táŽÂ}B=œ› ÷ŸÜ¾Œ§í�¿Iú¯âwÀÄw±û!ûŒøÊaˆþÈ¿êL‹e‡ööëö }ÈÌ6Kìý-´º¼W_¦ÿâ]ëéÈÛ©~Ú¤z›ÿ»#rÛÅŸ�ëAÌ #Èé�ca÷öuý§ô¿µ©¼ v—sÆØ ½q÷}Ád’ä;‡~ ÔCil.¤»±ƒ,³>:|óã¶ÛÃLêÏó†Í�m’C©Õ‰l[bÅý¬¾ãËdd%’Ô™>HöZ¶nÛ ºc¯8ÿ¬÷ìuå¶ðS¸g—é.Ö85ÊYÓ`à&àḨÜ?·ƒ¸«Ý‹b4†|˜³×„²XÛiœ/PÀޤËêK-o¶'Ûº�vA~SÏ¿,óýG ß»Üþ·ŒŸ-‰ä[_eÙ6`~Ø,É€³�«?–,þX¸¿/á)Y× @²ÁÀ°yîþ�ûÙö.¹ŸÞî˜Ú·k+-alØèfcdo?f¥³±ñÆωðÍéµOvDY±s�ã#ùÅ‹, ú/Ê\¹¤¥Žt[ a.H=¾âMËÅ·ƒ>-õ—Ôb·œ6eý³Í²<�{ÿ€ö^þ_€Äà‡WC ´Á¼x/hnþ^Ãm¶Ë¹~ã—Ã�VifÚ»«½{€:& ƒ}º/lã(÷ø 6VXØØÇŒ¸±<¹`gÇ?è�S¨äÔc‡Ë7ÛÈï�›jÌ�aÇk¬�'Îj­œ�ŸªSÖÖûËûžÔ:N}]t¬.±²f@>ïí'ë7þá_ûŸÃoô�ú„ç±Áv?l~ØÏl~ßÒþ�ײkØ&p™ë‹Äë�ÞÛÝ»Ï>Ïdqïy.åݶË�›ÔûlÛzãx|-Ÿq“}„÷`θN¬²2:²ÂÕ&q² 6×Õ¨V­YÓ›«ÔÌáµÓå³óØI³Û?¼ AÎa9È<»öQä« †~,‡À4É‚|±Íy•:Jíõu7&¿h«!‘ ÌÙ\.Ê€bïž]^×@uþ^“oö\-þßÒð[ô)Ç x~Sïe�YÁàfud±îË¡¶q�dùËÉýXâíÀ“5¨íì;öêÇí�Ø7Û·ô³õ!‡v°oÜôÔ½âůÉy _�ÿ&[g‘ ü—݉Ûµ^®‹/8Ë,X³bÇ&£€¡ <�Ü%×Ì}MЖú‚?\|ïû¡àö~ˆ[8‚I>¢ epºúÊ.Ï`¬“ÄáÉ—�ªý6d6p·ÝƒNx.£¥Ñ8NÂÙáãÁðõj^Y¼ú˜l i™VêÉõh·¨‡¼à² 9î¾IïÃî}³Ÿ_£€ŒÕ˜�¬ú£l~ìþù£>ßÒ?Hâ ǸϦï‘åì†ýZüµù+ùiù!ùdGZ³Œ±1$>ì>­»»+Óð>„ž£€ÒÈǼ}Ù0XeÒöå°ð�{ÃÑd»yfv¯¤lƒ Ê—n�—òÖ}eâÕÚýš~¸……‡½„ "óB}#EkãÕ–Yd:,²ËÔüÝšòy'\eÆØØä³œZ6œdN’Yzpɰ‡§ÞI÷þ +C¶ÛîÓl=üÙ;±»á׃\ xež ¶Ûm¶Ò2¬²I2þ›ý»6Ît»6DÀ�l8 ŽOIo¶¾ÙÃŒ]Û1Õô6ÉS¸~’žÞÖ\½wÆÓɞɽX¬u¬>‹kܲ̀ýßM» o£äA0Yd“�„–C¹,åðã,‡rnɼçW® ÐK'&Äþ ÛsÉrÃ*˜ã.ï´ž€Þ¾#îú³“2ÒéÀ—o«?Æß»ýØ�Â8ÜÇRÛÿ½§» †·Ù&ßËËèd£=¶AÕö0pï¶ }G ¹ƒ`ÉŧD°ý1ø�{“õ¨D;Âέ%Ú]å›az‡Ý½Gˆö“}Φu˹uÁ?„ÈO¦ð\ ¶#?,-¾ìeNAçSØ{–U©r°µjÔÛo!Ô¹-¼-w‡„û”̲ÆZ}À˜E±¼N ûàûBôšôÊ-@í�«P¶MµjÔ«V£˜BmÛ…L@VYΖ–,Ø´·�¸m·V 9±#à6Åê¸ûËØg Þ7ê¸Î÷g]O¸ˆï�õd¶o ›T¶z6FÙøPÞ“ï ð´à>¥Ò0¿¼G>ðÝÝßp�ÐDt‘y�ŸPàÂÈÈýÀ'¢Eyៜ$œ>¸àlú¶S…Ó‡Õëƒäyñ¶'K³Ý‚ˆã&StZµ m~Úµ…‘mµáyÁÛeÕ¶ÝØÆØþðÌ,H±gxA.œ*mƒÃ³þ-HýGr%¬-¶ÛðŒü&êؘ‹Åâx- õÁÕ„¶ÁX)f[Œj(t¾ãŒúxx½CÀ½òM»6|äYÎ� ¾¦tÇÔ½»_øÍ—qÓ'{-ê9 ´éo –H3¿$=²8u$Ÿ€‚x[3Î+§õ{àèâ9/V¼}³i¬ž‡c9=Ÿ‚oÃÁð÷” �qÜ.ÀÙÎÛlI¼˜6`X]]XFXXXX³fAðøáø�f̨õjÁ :Y{ã|´¶eäŸrïE¼aÔ2öÁêõ{cÙd“B}ÛÝÙ–6Êw2ÂÈa-ÝŒ?A„€z¶tSÚ]ôñ¸c{e¼~-îÁç,×wÜYg]�2OÀ;ã#&Xêxy{œmrz-Žß”ã ‰¶¬ ™y.‰àöO‡¯‚ôryDäÅÑm¶Ûm¶,r x2¼4ÚÊò&º´òÅÜR‰ÒôÌ Û»ÎÞ8Tì™�|2È}‘ 8x²ž¸ ìl«}lÇ`&ítɽ6ŽyßYgu„æZJ[l³^NlGQàƒÒ?!¬‘ƒ)9?ÏŽF‘½�ØJFC=�º´±)Û1­[Ù Óê:�“Žœé$„u忲"ðÁƒ¢N=GƒïÁðçÅáøÉg`�ˆ�®"t™ó– K«m-äO«ežøà‹K÷¶Gw›ÇÁLÙ†}¸Ë#„%¤Œ‹1h8�JBò˾F¤¶ ;`º8Æ]ž›Ï�lî ôàðÂÈ8ÄcSg.çÃzçÉ,² IJûvé²á1‡Dóæ|ž¼à§·Ôµã˜%ë-ÆQ8×ÛЗ-³nòì'…€ËÑœÍÉLò;]—øŸãà༷nV¡£õfM¶ÂÝÙËim¼‡l³ŒäÿV~ýÎë„à‘ÕÙ�¤ù”t�Õç.¡‰-€ønH$E–ß\bãc¹5‘ž %‘ßpË%-ƒmòíöé†=p¤ÂßÞ,È6Å`ÂÈXHŒxØÝ´™-#¥ãhGd’[†Ì·Þ€Â6O ²ÑÔè²=lù'>ÄûËáÌäO`n·™ë�ûg®Û½»t^ä~�àÞ¤¼úå3â|çÝâûsN¬º”Ž åã à8N ðÆÆT°zÀ|€t‚Áµ_VÝÒÛÀ7&´A±ë`êÆÔ ¼qÈ'Rý±yãe×mìËè¶{áz�êH½Ç à[wgv¿VEC –=rDŽOl,åßȳ©ç#»8^0GN2CHóà]¤4†<¾ÜymüpKï·&yÃ:�`X�/Vϱ&rûø2�yúä{áé9³3€9uiu?åÜAð]JÛ[PípÇs-­\oLãI¬]Œ–[>÷mÑ«n °±ƒêY¬Ãâ‹À[{`iÇ^Èe�—'¼§»·¤"[Œ™1ÎA“!¬:‰eÕ¯Wfá�†\ë˜×‰+6 C“¦{Ã-±¶nñ‘»’XÈÚÒ;‘î!õ)rÛ:Ãw�ð«Öè'Máʬ.œ²÷k÷/´8o×>þÃëທ‘­ÝŒ­²ë'è·nݾCgÝý-ËÀðÛ¯Ë?X¼ÜîÌÔXKÔ,lY5F™X± d3女bzlú—©ó'«v0Å·e³têÖ_— „ÄöCö>�¿-~J’[M�“wÁnìa× ì³'ÜK »!Þæ±¶<<ä2¶²¡IуŒ�mÌ-g”[«.ŽWs«$yüCz,@{ll}{&XÓl\ý_ÒÏÜuð�#cÈoâbC“¸]np®Â»±²Ë,°¼Mܳå�ˆtx°H½²K©÷´�}½ˆ;¬-ÀØeÕǶ>ül?¾85°±>]£,g$'ÞC�ÜÛ{‚ñÝ›fc/®=Ù¯Bë Ã nâxÉòż:A»ABÂÉéÞ¥x½Åøæ_VYÖ Óv½O p)ILøpúEå¾îÜ}-£Ø“…#�'NË÷Jú³«ŸÃþ¼»Øa¶[ç*6Ë,.®¹Ëbó³Ü‹ 'rl;t7Üá¹Å�ÈÃë€Pó Hý@³#8q“¸wuîÙaŽ÷u„t»{`õvG°'¸’ìw:ŠGkØ6 ³'cÉ÷ƒ «  ž ㇩O—F'Ü�Þl˜ïƒvâgfcâ‹�ŸP±ûX¸{Í’Dã¥ÜLu��‘‘t-­'»É'›o_Ïø>Ðëe¢qÝ“ áÙnÓlw,níå]äá"Ùv}³n+™Ç/©žH1Ô» wd×H`Ù êÛS5#©×Ù›¢[÷9•n­Ž éÍps»³�¯\a× Ùˆ0Ä¥çê/ðθ‹ÔÏ® žÄÎD»x™˜ølãóŒö“�ZØßv[ÛYß+»L¶ÛYø7�ŸÃ–=|>÷¤çH'ó)b�Ý‹«m¶ßÛœí§#©™dqžÁ†Œ1Îxó¨f~ €°·€ÚÂðÍlÎ}}Åæ}²öÛÙ`ã¶„kHù}°çRi’ºY0†Þ:²;”‘"]`Ö Ž,b°A&ÄP÷ÝºØ N ¸lmÔ‚÷'<»ü»ü‚I§Ÿ'',X³{ OËOÈOËEÛÛüZ~O®<^¡ú‚ÏãxW-à07`g­³¿oõÕú/õ«ýGDÛ?¶?l~Àb[ˆøÀMwð„ú±Ê}Ê¿9ýoéköO¯VîîèÛ¿ �¯ÒþG%˧,m·DÛ¶_»{Ô‰ïrl{ác eêú¶tÆIWÞ}XŽ ƒ¼„6l^ø³ ^ä NL€‚u%ƒØ7€¶ö—8ì¼Gï�|BdÅ[· pŸ>%Þ^KÏ'Þäë×ÁçÖ,Œm§¾G˼}¾­äÞËVþBxX{H=�yj&ïc©àõÛlv.ó�œ—HãÌÌÛ0u�$+“½N�Ël’0�³›8>Ž#î’Ôi7¨åCÛò¾Ç Nø%åÚr³-]³"`$œ&ëÜ ¨ýÅ›á=÷à,‚ßQÓ&Éõd„ $³‘ýp|ãïJ–|^N#ƒÈ.ãÎü=ø™îxðÁöøz¶["âð¡ã€õ+ä§�í$=­—ÜælµÀdÙmåà= °ÃÜ´9µW¨ƒX„c‹Å«Û/ÇÂVVÛv1䯦/¥“õ-6XÝgRÞ è‘]î\$pñŸòɲÎ6Þºœwà{ãeã.“îñü„g÷/�8<ŽC¶O`“嗆̞<>üVk’ðZ 3£ŒÖÜO° ¢I¾! 5Ÿ&f8 {ØòYr;KG{uõð)Ñ'í±grÔì!ì+»¸;oYÁÙdôàˆwbmêú^ô˃€ò{ƒYd¬lÏ\.CZµñö(˜ñ¼}OdIg»/8ç8HÒ�=�E±‡gÖ<6ÁÑ�Z—o€¡œ�Ï-†[måú ¨á#*ßä©«_�²×å«Sm«_–¤Ør¹¾6ÀÙÕµÂaÇÞà -ã³7fycÔþ£¨†@ý‘û�€l¹2îû;{ÈôGÓ¨W¼µ·‘lA^¡Þ ÉÙg°±¶·€Mb ùuù}[�’òµµoÙdªé&l³¯·’ë¼de¹z¶ÛV²×‰«¦w±eïÞ?x ›3,Hm£X.¬HY=]ÄvÄ}%ÔûÎsƒ"ÆÍBPÒÈ�Î~¸|oÃ-”97;“:ŸÒþ’Ýíý¯íke­¯Û^v¶ÚÂì­±V@3�œãîãíx}C“ê]™„;˵j@ÉvÓ2Î2Ôr<Þ¦[mã¶l†·ƒÔGù"ØÙga8¦�ÄCïÇM7b\„g3‹ »>Ù�CP–‚Émû±Y¯Ì„yÇ«îàä²îÂ!‡¶Sù’‘û.Ù»psã Õ%mÒ ² ,Žž ´_¤8öïé°Ÿ¸´ÚÆðIï0²,ÿ‡pÉâ_¨lÎ7ƒ1»áù{8BÆFäxG¥ˆK’ß–OKß)ìpóè‚ÎìÉE�KÁO£,6n#v5nÒÙŸB^¡êÛÜñÕØeÉòÄ×�¬d³«¥œ}6k/ËD÷íº3]°l€Ê‡3�¶c}Ëñ çÈäbÔO»×üHp8 gØ›eÆü½œcà¾SïÀw}¾=['[i©àˆîûG{Ž ÿ®uêñ2=cÈ;>  SÜ{žAÆ8¿dŸÛø¶{/SÝXm¼Kxõ8™Ÿ|à—V¡o¢1³,`Éá�mú¬v6u± ?/¾ &üÍøo´Y31àÐùç¼c,6{y8É!dÁ'^=Ã�ürÛw�|huÇ©{åì3/‰Øvd±F_RHÆÂ…ö]Œ‹Ü¹i1àsÜ#~[t�:G“zÞ 9Ù–ùz»átg¢'´Ë¤ W·‹z¶Ûlô¼M´F–,ãníÎÉ·'vÍ’öO<0™ÎÝ’¥ÂÌ·nÕ«á‘Ô´Þ !,|‹‹xáìumßÎʼn,µeÙ m¶Ûm¶Ï¶ÆN§Ö=Ùç ØüàK–Ãe†@–? úK|äÞ ˆ–iùoây.¼·ñ�F>HÞ¾9&6‡m� Ø †+»¶se‰$‘pK`®Pǽ�!¥§HO‘§,`–]…Ù4õk/L‘%–ÐÓ†Y0™™d:±7‰6O^7ê ³Yõa–“ú,Îí›%�«.­!Î~òz¼ðÒÂwòU»©œ:³‚Í·í‡ÇÀ^-�ßP�m¶ß• �ƒØGí”�[&ý%Ø—[g'ÉT:lþ§à=.æHáÞ1X—r 3€„Û·¶gM§;oÁ%u™ÕŠ6ëzËõEñ]G{`Gâ-�‡‰cÁœˆ‰>âx �¶#ýØý³ûûcöþ–~ ß`ßl?l?`~Á¾Øý°ý±û#öö_ðt¶u6IÝâh6ù�ð×�exé‚QŽ™ßÙ-Ç(×O¨…µ·ƒn¬Ø¨m[¥ÑžÍåÅ–R?°¤d¼Ù…ƒl®Èü´}AÒ…llllcú³{ÃÀû±·€±™ëîÖW6^øc¥–Ye�É–C|ºT£Ý«r¾¬>åzo²‹R)‰Âvkk oÀ:†{�Õç–Ão)÷oçŸSïÃ×=3Ó‡õóõ.¥Œ>2¸!êÞ¯d²Íl²ÆîÙ«sÖzsúrÝÖϹ6ï(ÝœtàuÆIÇ×Âm­ž’Zp¸KìˆFí� 0»bd%­,>ä”ü¥›Hqá4°Äg »,Ëë,îÅѳÇ'Ydá³!:³…›ü”v030»2Ãx,Ï�s¶ïü¿(wg§“Ù÷þHœ&ü²qqn“S¾CHYeŸð}äk�ŽéƒI'¨…6ÎN6Yu}86ØîË£cס“âÇü…>¸zXeÂÓ‡ÜãsV¶±¹waßÄ#�ãñ-8Qé:mé¶ðÞ=IeÜâT`Ž œÏ›‡KDhÖ\vÓáä2ÛÁ<¿Ñ�5Þ}|o__ôác->y1 §m’áÿ>è‹-]Vß\‹îñ$rÈ]m%¶Þ÷Žîë� L—rxºÏI1°² !‘äñZù õ?…ö òXí�aÈ ·’Æ-[º1†¡ÞB,²Ë²Ìþ¾¶ÄQêKìiœZKÅwí¶6lz„’q–Ý÷¸õÉ�ÿ‚A ¥~–‹\­Û‡¶‹v­KjݹyjÝç硲dGlp‡¹ýpürK,amo\ DÆ.…»9»õ à#€½ñ¡“Ù�§¢| 8ÂyvÙ-]ÝÃ=Ç:œ û)!ûö¾‰ÿ'ü�òÿÅ¿Èÿ8ƒ�Ô{wwklîÈíÖH0[k:Æ]±`�ÝŠÃS¹'ò 1¼X®[cn¤oœubÞ¾Ôüõƒ÷À�¢‹éËýË}m[Ü»‡¹aî^6wÿç89ÿGm¨ˆAÜ“Èícæ{ÚëÙv‘3-"'\wàœz²zž‹f5 K$íäìlt�NîÆòõØÆ²>¦{'›ÎÈvŒ±unjˆLYe‹Ý‹©:³�äÕ«REum°¶Û†ÝbìSPêeQd’YÁp÷®“˜Dôàyy&¸ù1ìûðõÿ áËÆZoÉýKÔ;�ËׯYwÎÛ1é—XF/êçÔ37®5EÙhŠlâü8¨m³z‚Çw¹àsì�Ý`Ã`¤ô¼qw<&Ii¶ ²ê×¢ †²ÁÛt»Ë9Ù@La¶Û±ðCöퟻ¡ö�:]‰ºa’îÐ9“ï3çÏaä9|à6,/v%àöõðõÿá"ÂRÆ->`P�{ñÙÛm¶Ø±iuu%–:†Éfœ1>ñ&Ãílq íêÛíä"émK“O"=]Œ–uewò×°xŠA—nÏêq�£\=!êÞpÚš]¥½A‡-z·û†ÄÛlLÄ›KxÈ9¤?ådÂÊ¿¶gMêy“ï__ñôã×/œòFÉcúµkòÔ±±±’ÆÆÆG.�³bÆSwàò0¼Q(Éá™#ÃxÂGv@¾Ý–£¤ðûžA‚^àˆÇÍ�å±bV‰i(˜,³�eŒ8ÊX-—LL,X‘ã]Ø‚êêúØ ³'ÜgÜå£<‰Õ’<¸ž÷n:M:mšã)É�wg—Œ°{´ˆ—jìw`6L €ÖÑdjT9Õ’{#%ÔAq“þ¡:q”yÀ½pE¸GÄ7“]¬<%–ÛÃ.øŸ‰Ï¿ø<«FÝ-v=Y¿™R�1Ú8d›dAÕœ3?e�ÝÝŸ õzºÃÒu!#×%×î_Ô ¡‡œ2 :º‚LêÎ¥¶Þv÷¶íØ— mêÛØ·ì±Œ(ƒT3�‹ì½±ÙdÊKl{Èñ �ÈI�gvåˆr:„‚<£¢Ý„^¯]@¦ìöÃHi;«Éí�Yn¤Ï±>ð2uñr%»–ë�sÇ×à·Ÿ§Áðù7ƒÆYhprDî=ðxßøeë“Ya¬ê !ÄòFì§qÜð}G´ßI£(!ä‚vvfËë.Œà#Õæñf%±ºØ¡ê@ÇÒA81<]¸¤°lº<÷wm±;›ud±¶Ra´‰òÅÇs`°àÌ'^ÀJ°K#ÑÙoQŽÙ³¹k,dzìP`vw ¾D»Ç®=O\i’q‘ïàø|�àñ‹O¸²Û”ßæð¿Íþoót´¿Ç8vÙò3áH`:‰ã€á²f¬dn“ÂŽ\›ð ´�êÈýÃô@z`„�9ô¢�Î[¾O¾è¾þ;žø#œµ&7©$ï™ððNŽK>­Ïí—ÜXÚ±l²È,²c^¦g!ÑÌfìÙßd—ŸÉ!~àgýº%àÔ-´1ëÑŒ‚èìõÿPŸ$=°õ°ðµ’ŸcÞ z£Ç¿‡ƒàø|>¾ÒŒz-–0ËKÜ/™š»-·Ž¬Yçn‹»[V¡p8~œ+‡ê l›onÄÙ ;f[ÑtLNvÛr3-›É캶ÛcK aÒAïƒê8ø=q¶ØK,²Îøe“¹é‘ÀVí¿¸ -•¹.þ­ÈÚÚÚÎ-X2'QxK0˜cæØ�1ÈG¶tpñŸòK~áîx8=ãmq?σááðúø,A.ºñë�qíã�”pÍž›mXÚµ.WÅ�Nu /¹�Ä{($ykÆë[Ö]þ§¶2vr?Q†Øˆ°ðG¸t²z·& ¢A:^¼zqâm,GI,Zm¶ðÃK¥�ÒZC` '©ø�¼átZùÄN¯}G“eˆk�V(g¸GdÇÉàö}àó�ïŒÉ2xéððYËðqïo‡®:ðz|êÎUŸÛùoé«xüà‰¬Ôd– ‹b|àÏÝ3‚t6¥Û¯�ËÔÿI_v\ 2÷k ¶Yu:vK½¼;bÚ~îñ^ñ\nvÕ¨,ÿ€6,!õgìBÞÈÈòq¼;‚!—¨!#{._S�…þÞ„~„ƒœ-²�gÈó‚x,áàöx<à5µ÷t„ñ)ü§O$>¯áoâÓòF_Âþø”ËŸ–Ÿ�â_Å¿‹;¶iùoâFÛ‘$<�Ïõ+öh¤|�ŸâÅö‰_¨ßQBûŒñ¼·°Iá!!ézÅÐÿ¾òԶذF¼8Ž-ÔAÙã¢^}mnîá˾s€‰Þ6Bߤp«#e“ÃÔ»÷Ë�oª xn¬2ÑÓ„ýØ{uéÌìYét/¯‰ÔÙ<,/»¶^åî°ž~¿òü�ü¸pLjqÄ ‹mÿó$–Î<0ÏxŸÄ/¸ §&]‰MÞ€Ø Øú°Â�ö9䇼m÷ÆYd uðóˆœg²\´ƒyÛƒØeànaÀAÙu6°Í‹x~;i<ƒö¦ޥ_cÇ‚}†Áð�ƒáð~Çþ\ ; ½Ûm¶¢iik=°û’â?pÖlX¶ÂGê>ÂÇÙ ãÀú‡{/ó¼3nÓ²ÆËì'¾Ù,vwÑh¹„¢IÓðÖÔ"Õ»v­H»íØq‡gƒœÛ»[^@p^^ƒÀåܶØe´žÞ¼._”�À0 ³‹féÔÔkfn^c‘ÏŠ>óëƒÎgÙäðx88||€ñ³“áë‘È‹¿†›/«#rÛzá»:`˦P�|Š1l_`¶†è³I¾ÊŽ­_má¶Ã/×¾:K¸O»m‚¡#rƒ`Àû€ÿÖÇ®2lÀŽ®¸êÓœ Ý<—\÷WÔð±²ó„d² ž­,²è„ØðF¼p†È쿜¤†a"~~9õÇ׊ôY� ô’åÏÜ:YrdtYú³õdÓÕý,™'Ö³gê &L€d×¶~ ýXßlýYú‚û…i¶¿IË8AŸw×^ég YÇPo—ŠêÁk,¾e?n¿gý’þ—g·ô“ôßêÇì&ßîÇì罃ñ‚½²N¶!¿/¹Ž¼¶ÞPdL ÉBÑxÙËÄ,Ù±CcW—››agöî×ÜT2--¼vòж ”á·V6Ò{ÑgV_Õ�7«,±¶^ÉÇí}±ä·fÒÚåš|v|å÷€¾]=Z|–óÐO/À|ßÃ×Àö}øz¶"kÚó�àû Ûˆó¨cðŸÍvÄCÆû�çÄÎÓÇÖ<ãÏ-àqö˜‡»`}½ÇîçÅù&ØÈ��ÖVm‰jZ¤g±ŒÈa®¬œuuÃx ÙîÉáe™aõ#*`ÍÐ៶|m¶Ù $€ƒF’=ƒ¹>˜_r.�D?#ç|’z—À´Ï"@gÁz-ù�>ÃßÀ“¿‡®IÙÞ²r†rðÎ’XGœ€¼Zê½qÛ2XË¥³ÀãíÇG€ö>Ãïàò›}KÙW«»k*GØÆÕi`ØŒ}“Ìñ§— ³×—qqéžk댖ÛmŸmá@Ë´™ÏMÒiUxS½m†ñp¿çl£Â\û·‚dC¸ƒ:pðøÿ€ñø_}øzøÞí �§ÈùowQÉ)—N:ø�eï«lñý‹œ~ë«êÜó†_\}–öî!‘÷u3vq¼®Olá—Yózðºùe‘að´fÛ ½ü8 Ÿ—Õ¿ˆÎÊé?¥�Û°áÝŸÛ·û¿µþï÷`û€l~ßêÿQý_îÿWú°}¿Õþïõ©ïnÝÙ¾¥«p®À´L[}'#«lKbÍ™ ›`±»2û¯—Ò4þ\H øÙJö2È/®<½…Ýü­ä@´–!:ác�¶ÞùÛ~Eu#—–YkbuoYß®QeÝÝ¿úc» 2c÷öåò}ÿ‘|Jc~ç�03[Áç–ÛÁÀ~ß\¼w´ù{F=Z}µ¼›xðø×ü¿õðõð^ˆbÉ݉ääûð|²Ë$êútê<Þ³ßm‘á¶¶·«1Œ$Ù“¨]µ”}ñ)�ŸKùðÏŽsœåÕ•k/êcûN{oí:Z¶Á°Øáœ2Ë,ŸêFÅ—";:Bí­­¢J5ì”éµl­ZÚ…—»[VÚÎo */?-ë#®åÛzå‡ëÙO–ËX½äãdø>ßÃ×À÷à{z~¾uœ Ô¦ƒ>¢uo·‚Ûm“¬„w죽ž’eê@Y²ÖÇd{lCf¹,žÝ�cî^øÁ«GX¯ŠYeŸ6d“¨O|{å°N¼o¹eúZü>¬ãoRï%»ÈÙßÏÔ'È/SåÇÈáøO€|=üo¿‡¯‡®FK¤ðÂ=œ'\åâ-»Üвx–ƒÈ„0à aÓ³6IÒJñ¦CÈpÛG—àüw�|C�¤æËoù;áq†8 Ô©]º¶Ù^aÎr6Þ3»ï‚|�ƒïÇÔóÙŸy!Â|‹A×r&|8íð �[Àð›·j6íÚ…Á»roò²ú—{·+ùCü•¾ZµùjFÆÆÆN¬la �ÈÒû ‹×= =Ba:„Âé}j¾È'_eíï†ÈôYk…�qí<7vôãÌ•wyBû¶m–Ûy0´•%ÛioäËaßx}ÂÄ!êܶØí¶c¾­Ÿ«fN7—’ñÎÄûÆpym–DòpüE1M�9|æÀ¾I=XõÒêdµ›~Çà¹ÛÕ¶Û ²»kkk'm_ÒþÒl«_¶ãed,W´]C‡9³;’=.®† Êwµ¥²l¾ø–1>®Ìf$ñ˜A�[!­£%Zûˆɰ¶ó9‚È0·7/#+ðfœâÿ3_¼;ݺùaÒIü�ô±ùgòÏä�¢Ïåü,~_Ê ì‡ñmõú°›c�'!6ijKb–ˆHKKKKn®­'2ê낊mÕ¥·SKK«A”´ŒŒ™¶Ûb'Î9|áYÇö[ÔÃx‘Iüãñð<~½g>þ¯OÃ×ͳáz‘òÝÞXÁaHöl›;טŸ°^N7bM r2ŸlîÏ>®‹ƒ —[ÉvíN˜5ȸE–8ÙàŸhc‘¤Ë,}³ŠõYãÎä.œz•Þ¸W¨à «eçéð!‡†z¶o® x}ç$ë,³âEŸñ²wðóßVø[^ù|8r Þø=C/ÙçÕ�Ì{>ü=Áà²ÄrŸ Ø/¹Ñ]1Ù·‚1\}rðà¶ìàï©ý—oOÃÕÙr„vº$ä°;�v–ð}ueíž{@Ïó“{¿—ù}lû·‚ýYÖÀV¼{ž¸ÙeÑlp^íåõ<í¶òEé(2LîN´Ÿv ¾Hn¼&}ž¡ >¸ùnCåüˆ{}õzårÜãÜûqê}‰IýMöÜ=eÜ=6°­d´ÚÉ{m­§î×í¿Øò˜Ñ÷jîöHÚ¿´"[VíËÂÝ»ròÓx‘9µ?ÇãÅþ,~]¾¥þ_æÏä~Q�‘“ËÎd—Ò udú¿”ÈD%ü/ã·¢ßÅü#ð´tHv#𾌿„@êþþ&t¥Ï:5Ô‡Û?Ü~%ö™zp#Ûd»Û?q_Ö æßÒþ�O²^7ô°}ݽ_îOퟦ=ö«?·û±û:ï÷»ýÞ-~ßêW×ݵjݬ´X¬(ÆÌlÉ® ¼›½JÞ1“ð9|³­½CXM#i�Gwhé˜ñø Þ¤¹à�g’÷ðú|ƒç$=7“eïà^³’ìñ¼/^}Ÿmø ³oFsÕä½³êÄ�vls‡VdrÏ»ðr{2î;ê@»-€uzgƒö áòõ=Oœ¦ó‡‚èÝ[ ørì>È�ßWˆòíÎÛÕ¶Ûv÷bÙe›m·«m†L»†<uÀÛ<3„ÃNú!ðîJÃÔ�&·£ïá÷ááîë{äöõxO�õøxÁáå½s±íë‘çœ.ž7‡Úó“6÷xÆl:IÁ¬Ø‘̶ü2ÏcØrèÙ�d݃íšÝ&ëݘGv«Ôc©%Šö[eÜÛÊô[nOwÚúá²Ëg�«y=Ÿx߃³9½K¾6;»! ÆyƳ»Ï�^² «ì^¥�ªdœÏp÷Œ²=Æ c;=ϼ2cm²û<{ã8úÙfù*CÅë©ãÃÂà/Rõmõ À“ç�úáüŒ÷›?a½Î=÷o³d`Bð°”ï!xKXÈš=À% x-ûâ+S¹Æ-Æ{îÄí!ÔORí|³™w�¾+Ô2»:xË'E�Ø[>çÔø[ÏÚ|Þv��q¹i�s±>ü7«y=àâõÇzà[n³Â}Úx%_x|zƒp�õÛÿ9.©ÓIV²k¼·3ì­­«²U¨ƒòÞæ=1s¯/ÆIÜ ´z³ë# ^5ä¬6ö±ù!ú´ü��’ü_ÂÓè„ÄÈ7È ¶b‹‘“�*ÆöÀ:!]-(†ß⌰›}bH];7-æÚu–èbHçwgw~I+õí÷Ž6Ä;ðZ7ß`ËAL=À.áüÂ~¶ÆÁ–›x&eâ̲I¤ýïrÃ=[�œ˜–�×Å[Ê_sרV'€Ž ÇO€ “m¶ä+¶%ý…µ+§’Ÿ`ãÉcs»¾î½M²[fÎ|g^ZàÎ @l[°‚òIÆf6éf¶X>Ɇqã�˜Ž¹Ë!Ï�ƬvKú¼¶Ý€žOjþRŽæî;d�úàë»Ø3„™ám»øŽË«üà/a±ÙÜ»ËDý‹§ �/êÃêVG±œ|á6Å‹3oå¿E¶Ûy,)®†Yñ¶ÁnÈõÏ“ û–k.òÈ.ÑŽÙŽ¥"õfp’ú»™&Zbôäƒö Šm±#ÂCI]”»XÁÔ^¤¬²õ—’ÉùoorœÙdIÆÏvMí–YÀËÀã ‡Ÿ*[®±ü‘™’°Œ ‹xÜÞ­3×3m² £à}½GQhٻǜ%œ½NÎâ:yo˜ðHûH ·¸ß/`›lû¶wg¬în‰,²r|‰Ó»á{G[�ðG,½K-·¸I'q¤ùÖ³D˜“«CÛ©äa¶Xáz¶SÝ—EúgSß°�–Î3�½àžæÞ=Y÷!3Õ›d–ü ‡=›ÔŸ–™Heƒ ꉼí“ã—¨x±C ùgC/9XG“‚Õál)Ñg‰$î]O O–ÚËNr °^Eê:ˆvIX‹¯BÁ ·¨;âÅâ}Ï‚ÉáYmå½O‘æñöÞ>¿á©lyáŽý²ûŸ/Ë,œX%ãKõ ñܳ8ð·�{aŽ–§Sì�åã*Öe·|ê Ù1°6Üdó,ÿÄ&!1A Qa0q@�‘¡PñÁÿÚ?é6^p{’-˜ã,²Ï轎–2Kì"Ѳxmã"8Üœ?wˤu1aÆ·†ý‡{'9#âÅfÁã_“¿g®�,>[Ã6Ømý_Õ›Ù9/ç /xÎ3œüvÓ€² 8zž áå¶'¼íæ9?.¹:Iõ%°Ûoçê\²:êxx ·xÓ‚]½˜žVý—�ýó’Z·"[té±iµöÄDá‹#Ùãl˜#o_Žgáï:[i °]Ž Øm–É¥¢òþ ÓX,/YŒ@îË1êÆÔ`’v7äÇlÚŸ‡cñØíœ°laNGp²[[»·XÙcûž9±l9'Øuo/l‚ó�ãnÍ›þÙÇñ!òòßÁmŒaÕ‹lX;’K,‰u¶s€ÛXm-Èâ[´gŽ-·x\¶8{°�ÒwuâÏËCØîaÿGoYwêÜuaàGÎûºvÚv,²ö-Ų¾YÁAbè—-W'÷ŠÎÙ�n²[§ JáŽ9CÊT6u“:âÕêIë"{eùdÛ¶<€Dúï�ùÃÎþ.p½Ù;fg�†8^sn¥©³õm¬17ÞK‡8çV0§Ù�‘f{ùe‘»n[Áw�½-x‡màíå�¶ÛBmÚjÓÑaìâeÒ|—»`RžÉ‚í¥±‰oÛ»¸0X]Oé!yÆðU+z6î¼i÷†Ì}‘� 681óžp–òÍ–Y°aœe–Ycø½Áw#cvÙ’ /푈,"ÛËmá-ë‚hZZtÌ�,Ò|_®"Ò¦Bda“ÚLä©å·ËËòMöÆÉŸ!=­>“Ø œýG|ŸÖþ¬–mÇ-lØ3ËP|dü‡R~íËøµ YÆp›Êþ[2 !™Ìõg„Ìfñ…Ód÷tx=ÙÀ n­‡Õ’ÛRzŒHzcÁld·ì¬»wÑe ×ÙýgõfÙ\tθe–Ye–YcwyÆq’YŸƒÎm‰sŒfw=7ƒÃø3F ÞpÕ©Œ_¿ZÞ{‹,�CµjÔ~Ü;ž­#-!%ÓÛèHXËø‡a™p, &&_ÌÁ!]x¡lYšrÆe³ø-�È{'À·Ù•o][˜È€zà¬�•ô“ÒÅ�³³«¡jÝ©à€î~ðw 2þ›¢uVŒd6�¨°ºYcx$c¢Ë.¬.¾Îæ¼g9ÎYg ÏÅ ²Ã䬶ð{,cÃÛK¼=ð3Ëîlÿld›¿e¡ï€Õ‹ïbnÉÆÂÂZ÷bPB[øLû[þìN†{H˜ßÄlj¾„ëØèî‡O §¬ÉØÒk?ÙcoêØï»£–áÝ““,ݱ&?Hý¯}ZœðïÄ„.{+á o„ÜnÛHñL‘ˆ·©£ÜnlC»W©Ûf¤‰—FD›nÙº{.̺ûÀÙaÇ«³]C,qíÿVd#öÍòÎØ[[VË9`Û' †;¶6InKñ-ˆvó½�-2ë‡km·ðÒöØ’ó _W’fú½lôÞáèðf³¬ŽÕÚ9ÌaÕ¶—¶$ÁÓl=µká+;-Þ¯ùoÛ×WN¢éƒì–Y'ä©òûÀËØ.�Ûn٠ǰõ0}3‹g©KÜ»µä€²Ë:îNáÆLòl½†Z,{còDöÇ»x$l u6j]dsÑùÿ |á)>¥0Ë!2PŒÞ¤�Âk¨~[Þ:±&6Y²0äþËolËþÈ´Hl²Î=…¤Ù¡=Éc}™gÜN½³À…ß“nÞ!Õ›Xžà:'~JØÄ�l8 ãÛytAÝÖg¶Ê %ú9òé‚I~ï¶¶íÿfÂF�V�a·® f–å�->Ú~øpËH¿«v³ üOE�rY=?6d»‚‡Ð S©|nŽZ‡nH;»¼ŽºÈÝÓ“úCã LîËä°“¹l=³¾£ -G^ÊöŽudì–8 JØN§SnM{b]¯ïtò²B{nÐô½ØÁvŒÁ.Gözߢî·j¿›[s¸ïØÛ‡p|˱‹ -µ!_–þËMáÜO–Á-‹P­Òëõ/á'"Ú#N§&0÷#›•Þ®­É¾Û ð)ìîu ûfØGîõ–üá>Û’Ýó{e–u –¤³=“4½Þ²EÚŘS£övAíüAö^6gÎ�Îñ™Ic;ƒ¢Ó©^Áî‚éÒKïä˜ɸ݀w{Õ‚ëí–Iú¿fÆ6Ø:ð·ïaÙdw|·¬´è…Ä4`A.ˆ>!0€r=Þ ¯`]vøÝnuˆúdA{.ÒIºlPòSÉ:….�à_„/X½ 6ßýWÙ":š»«ú–í’»•ýpkš�}Kõë -—s)m¯r�NÛ–¡–ºûà‰;“.¶—gFBòß„¿qû¶³.C-Ü1"ÀýŸ–dFrè[(ÖÜ�̓¨%ÌYîL•‘ã'©m³{Ž¢ÍMò|%Ϻ'ö^“‡êSìéîé8MPzÉz€îÈvKâýdž'f¦>Qô‡§¬Q_´½fZñcDz[eâlÔÎŽÞâÞ$ï¶&OÅjú’²?KäH–îÉõ œHÍ;…é‹ÒÝú˜à0|·ÆXvð¶¶Wíým¾ðÛ«Na,å÷ð? ñ¸^5™a!ïoÙ/¶Áv[0ß$K ´±ˆ ‰Õ¶ìœ{e¿¾uiå‹~Û·QßR8Ë,Aö÷=Ù¥Ýû,ά‚Ì–6u݆?hÍÛÛbŒãØ·³äg)£ sŸf—w�¿,�H øHùoßYe™d 9…] Ù5²Iô#~€Nt�û,wk è#"ö¿d}m‹£jé.!>Ù'P›s‹mîx§�†ß$âBoQm¼>ÿ‹·‚ïÑ6ó©R0p¶�vá[ÒØöI³®Œ¼¿ùgÿ€\Ù‘Ç8Á&°d°`�pI¥‹e–YÂY%–XÇ&›äXñ–@‹xÒÉÎ �‡�IîÏîÙgá“ná´´œÔšöß6:Ë/·õá0È,‡q}Nkj×õkú»ä][¯=]}-Þ>À¹°ž°x0wP¯[[úÝÑ oœw!~Y6(Pœ;didÒïgbŠÅŒ‘™u8ÖþÖc÷ßÚþòðDºYíd?™ÿìøÿ·é`¼š<šýÞ/íIv1¶cª òi4hŸg¾*÷€Ì¼ä0[Œïhm”½ÌÑ�ídÖÙBú0º£àz’}›‘º­–:oބ؆] �qaœ±k×2ñž§³ó&[ÔEY6“¦J e­oâN(OS¦ûPD] ¶ B2ŒÉƒjÅk±èJ5gu<_Ò׈6öcÈk—XOFY9wNG©¸Ê‰c³©oàW»åfC�ÚIŨÝÞOñ89.òÛÐ_ú¦ý¾ãl~¸´»DÆl¹Õ´Õ±`À>ÁcnŸ`þïé Ô¶ ½éwIc3-,“=ulÄ?ü¸Ä Rú_¤0d^Û¸Ó‚ÌäõƒVÁ²®°‘$]`Þ¬ÄÆCê{>Ÿ!) êÁ¤Æé—P>–Û„rß,xÚC…Ñý‡g­ÖYb·íñF âßðò?û+m§³gÖXvÛDç©k“È;€3gàÞ<ó½q0ÄfM“ó¥Ø[¬È][åÝœ=I¨°]Ûl6ŠÝÛ¯þÇœ‘ÜO¼Ÿâ~¹ˆÂÐàEöÃ¥€}œygò~V$l;˜�êQˆrk‰nïe8q„ý¡_ü„}%êºÛIv³øãbK 3]2¾²™Þ#ï÷Ž¥ékq²¯ÙKÝ«åên€—a=›¹foÓÄ>2?„õw/-ÜÀ{þ&±±06²£gÒôº�ÉnÅòûÂEúpÿ†ÆÆLm‡¯x½“îÃcmÙé¬g«»»ÿíu±2àÂôêI÷ðÑ7]6K`·cm6þï�9àúÏ®†=i' ÏlnH3ծ¼›=�ìbÙÜûøà~TØÊOë-lÚ2·ð]–í­¥ÉH<~ˠİ‚è¶J{.òÖÍ‘|»féõn£÷�ƒOoùÃÜLEîxò@L@1™_�ºÿÈÌÞ‰ 7Tq¯ íݘª)¬$IÁ¤gRÿ2¼AŒ{}^Y<»WíÐ>Ï{´ô‘Öl¯Õ”ú·)ùb3,Ðyh$Þ�N°B�þXü�©(÷ußXÚAŠêt¹í:»Â#CbœnìlaÒÌ3ÛƒÙ’ÿ%ÝKH»>Ë ØoööOàZº›1v0~à�C>Ç#þ$ àŒ{Lù(ô@þBü†{=¼ŒC>J÷$L�òÒù+òÀÈO…ü¢Í{•æÈì�«_¸OØù Ú׳÷bGo[hœ€I¨wxwÎ>±}az2v]_ÒýÌýÓxxS¾’s»È RÁ:gHDd»Œ¾£�eˆhŽˆ´�±d—HÌÐBCï:àð½c¢R‘2t˜’ ?íJÁ›&¿jÖ  `8èA7îwmdìxÉà¿v’=Ä r“>Ä^ðvBy§“Eoiîôž® ¸…�:kz—¿È褞ÏîYlNa’¶$î}ç«3ð,²Ë,³’ƒn&e; ì$+ûºËÞ->ßÇ�d_e 8‰�›Qö‡.Û-pþ32:»õÜ)ô¦{v /A°FO’ò,WÉvñݹÎÂñÔ,J]TZFÞ+¦ ¬ÑÁ/û$h?gìkë7{_çîa{+Æuð„ØyǯíÑ=g]µ“¥«:ŽK#'E¡e1…¹òðÈÊØyIHg?µØÎáýQZöoÈC—ñnQÒ,½g“`Ù÷œÂ÷¯Àöy¯ä³¢[ÒïsÌq¬ýÙða &PH^ô8É)jìpO²wgþ1ßp¡Pßb" Ñu2ÌÎx­—pщ�˹ÛËO�½«ÑgÚ%í#³ö쳕ݫH}¢æ[²0û?ì·L¡¾­>XA7Þ^ãƒÁ´ˆ6ÂǾÿ°»'´Æ!ד%·Œi‘ºa?c‚8öÀãµxIu���¨G¢( r–JHÏ íœõµÁ‹¾�:¶' Ôh¾D»lÌÙ¶ÄjÁ튞CLÝ“ç¹4dq�Ät>@#:€ ã8߯ ö|â½ä¦äüÝ{†õ¬‹;½Gûyw‘àzˆ`p&ÞNþXø}Ÿë8ÂMw!ÜB#ì,=«Iý“úÝA¶ÇE•H0Eä{§w’ï«/×ÙÕÜ»r°/séx±â–gà7Ë3Ïø¼ =áÄ:Ÿ&QöYA:ŽËÆqž0.îî£åœþɦXŒáÈ#1iŸm avœLÅk*J‘½e]aúÇ8>ËòaÏÛJue?»¡œ6�f?ìÀÈÇí8]³ÒçØ~Þ6V–Ùðö‹C¤²HÔ�g{—ë-{oÂÓJÿ‘10águ°Ù#.‚Á4›Ôr¡w/C½Ÿ°Q�¼§Û&£ æÀÏâ¿‚þK‹Áñ<~œ‹üŸÓÄbÝ»¬›¤~-‡·”²Ÿßl>Ã>Á|å{”´%!-¼û1aÂ\?“ˆêuø ¾”¡?¼|!Ó»§{ è’Œ z=/D]PßÅdíE�ÙY;»c_ÿL `NçöBv‰”¡¶ïö1€‚c¶Ù»ºÏø ýoÒCØmýe‘ˆÅHlSä‹p“òuÙ4¿H]>KøG¶ÅøH;ãÂÀmÓ¸›dÛ'_¥=#Ùˆœm¼æû,ĺMžÛ0ZÌ{²|”µû/�ÅëŽìcŒü»ã8$ÞÜu‚õa?Œ2éD-Œ�«1þm~¡.ÐÈ–m¤�Üß¶~VÏ|sz‚{`ïR˜2G‘ßzÚƒõ8köa÷x´Þ!¾6x®­Ÿ¶H­æÙ;�æÅÃ…Å÷ê T‘ëO†Ý ›cÆÐ»gÆßaȼ=þøõ[­:.‚p�²RôÚ]�t#U�]‚ý“8K"­�²ÖÔ¤v‰a<#Òõ`Eîɼ[áo¨‰)»aÈ2¹¼ˆò­½FØ�"gÙàd9Y]\°èJ ã;²DÔccõ{z�÷ûwÌË ZH±5ܦݫ[\»µµ”L]ñ°�rlVÿa¾Ø—,=Ø·%{+ìÆÞLD¾…ÓÏèD uÓô¶i¿öÉÔÿä‘õòH_–÷»_–Ž 2jg w“eý4t™ ú~¸C©Ù6ŠOÜ»,�§‘ƒòL�{˜÷Æœ.õõ�\�û ½B„n‹)hãIž1‚-ü'iw/ h½^¶ÅÛÇàaÔ¢U¸¾C%ß'òòñdý§^Ã~Û±o…(öŠì�·Ù‘Þ§fÒäg«(¾Þ£“ü>þIõœ[tËÜ��’°}âÎ*«O…ó(�LH¬Ù.óÑ>Bµ ¦¯.ÑŸe¾•¥<ö§\7¯ü°û;î�`=‹“O[M‡É?¿øJ&N%ÚÂÄ_¡`™i�‚HØÛ¤ íÓ¹6xÂ1Ñmìo‰Émùq‘àqúÐãåíÔ¿mÿB_`²·~‹¢Òc)gƒc�˜øÃÙú†ÚXOþ÷zMМaóhõk†-ü$|�ÀP8D�Øg¶î˜7¡Àªeß'K[c* Ô7Þùýü¾#»ÿŸ$È{ºº%ùýžÃì`ü¼�ý g§á�8Ðmç–XŒ¥.É ã…œŒ^Á,›¯ü°pØ~–ÆÕµ}†‘ˆû?Sû$qíÄÝ¢Az`ë4g¼>d:±öYaÕ× q¿ÚU>Cä´÷9¶¨ßP"°8LZ™ë+’lÂ0Éù<aŸf들þú¢±™Öp’¢¡:Röo¤W‘jÞÝ‘û„F­x‚\&Ø_f,`ê}äð!¶Y@™=eµû—‘Â7íáS8B~gc²ˆm†Þ5ýCøí¶ÃßÂ:z�aáøP?ܾýŒù¤%iÉéö7¿žû}¬pÝpŽAýðƒdËùÆ8G4âêiѹԾ`ž…³;ÍM‘ÊÀ¾ 逕ø]ú‹ÉþOêp¶6^Ëi l…kÿÈls–GÙ=e¾&ìÌî ;ÈOWØYfº¿µ³Û]�Ýw¢ÏÕ¶Ï-‡v²MKýÊØp/BlV"uX„½K ã¿Kå‘ÂK¸Þ�`_c÷ßµÀ+°ß/¼ž6²ZþO<ü7†ýÿŸŽÃïàþ*V’xjÓ¡?³¥¾�ûJÞ‹ì"zðØ»œ7» 6ÈöÈqè>0ég«¨qÔ·Ž6¸Lî.âRÝÙ*ØÆÝž¡²?uî[ÕâŸ<†Í }€kžtÙl‰ÆQä]Pô¨3× —Ókíˆ)mè÷~�ˆ¾—Yõ¾‰ÄÒ2¼&Ýë#=ZÑzÇV"øB‹ñ-õ}èuÀ¼smÂè"=¶‚y'Ùö–`^�¶Ì› \ /]¡>AÜÛµòo¼½ó©ëób7ÏÀá¼ÙÆr^9Áø}üÈE©ãW¯/í¶d*狼¾°æl XüžsµýÛ ÚÎí Ë#Ùv ý’Ót§‚Ï#¡-VÒ&w"‚W­—BXH¥r!ÚÕí—�yÁgO‘ Çíf7rRèp'UÔD;Z™b £›ÀçgßR/°æÆöÑ™ z5 q,@Æ“àåü3«9&7…^–ÇD’qs öËÏ]-f$²E„Ûcö�ƒ�0—³«½:lÃäSïðc�ç/ᑟ‘ø§á÷üB°´~Wõ"8pe6l[%0ž¶°‘�]qf¶j³{ÁXm¨cw·ùtÙ»y,„?èáÀ6p“ý&w,þ¯œ}ÖÂPåõ jݶpäFŒ’htÌ£aRcd�É=­Û¿»m—~a¡q[)žýZûz‚còA{$tF¸KÞ˨~¯¤†{ö{2KåüÍþ¥>@¾–^GþÙ’q–¼3!é%Ñëxa“«uòSòÙé:&; ºÎ @¶æu'…¦Ÿ$lp`’ÀZþ psð3»,å™È¶Ø¶ÒÒÒÓ—ñÆ�ßîfþP`_Þ$Ébì�bmÑ œÕƒ®Ù�W#$dÈÖ·Êþ²ß·¿g¾é1ÃìãV‰eÕ‘ì;;‹µçá¤rã=�d; ý”ÌÝd:a#Y­Ýµp!Þ’L'÷Ø/LŠtÈ·` Ï­‡ôm_!ÕȲ@)×Ðòý Ê#ó!ÍÌp.¯,¾ÖHp9~ì~§/—oK?«þm&äÿ~’`,›bnŒd>Pü{ñ9“nêˆÅˆÅ„öOíýä}‡ö�$™ ˜�žÂmöÂ|‡ŒCÆ�®yÉ/ü`YÆG¿‡ßòÖE„e:—Ëg©ÇlÚ¯ ¬»oI[âïÿRäï Í„±vJl¯–n¾v÷hÝCÂ` w%º¤±ù}¡�Ý`I­¨ˆþÜ� ³4R÷uÛ%�yö¶wpò6ëÞ’)„v±ÛSbÓ¹ü�m[guòfð¼!— - ªþîÙ3 ”û,m—bˆ7êÈe¹ �îõ,Ø3‰LÉ“6Â_¾Æ;à—²ð´‡uÀç¤zB­�ܵüÁÎþG칈ÿs†Pa–å Ú ·tvÏ~ÙgWqTË»g– ìð0íÃØÓÚY\3Î3\±Ž;1ÀºÀ±–ƒmIÙ }òØ�Š©à؉ab Ø[í߯êÐÚ$u’ΛrØqÛ¶zO}]oÆ^òÌ6:Ø÷d|DüŽ lµÖÄ#ÚRN[s ¹|€Ù�:�>6¼cwjÈø@lNN êÒO�Ñ0³bÙÛmö´%ØÞeFÔöC¦]éãþiã?‚÷žp‹ø óƒ˜ ã™3rÃdh]ãÙëvVÛM¤�Áî !l‰dÏgkde€q»4êD±ò1öfñGÛô¹‚ÒÏPÁ¶^Ðαq—§DÈú,cl‰êÆÌ—ÿ͹ DÇ­¶Éß:uç>\xË]Áu#ø�ùtÖ&^?,�·®§¯Ý8–Z#?e�ÂÖ>Z"c ÿùI°ÆÐ¤S–¡ÂzÉ<µ÷ŽÍÚ§\ØeÙ;ɲˆA†^-#‡¶Ú¹&Xˉ½ü^]ãcñ'ã³øoØ ‰‡u“Á ?S«c#’?$6Ìtà˧|œ6H|…nùÆ~¸ÈέâÊÌ*áOØ�—’Îí·òHF¶�&H=6`H‘…ŠáÜV ¢1!0!ÒRé}ÿìÝ#”g»5ÑA 6aÂ!q‚ÄPˆz>‹PõpÝ`!™�ß·\¯í-ë ö ÖÃìç›?¾e¿´ѳö²…0Ý’öû7P=.¥Þ ³§ÍrÖ_Dêò5£.¬þ»?¢ù—R°wW²s—rØ.ãìþòƒ'ð/<ä“%œ§%…’ë¼ BÙзu7ª,fþ÷mà &EsåŠgÊû-{�²Ô9Lû%ã~èNÁ¦ARc¿„íÓÜ ìì�ì¶Û»»]ÛÃ#�’V?ð»ÈGÌ‚¤ƒwv‰-n2\fÝ™�Ž §ÖDÙë´Ý¸:ä ¯8;÷³–ˆöÉ1É£ËOà"õ%œnVSIq"j‹Ä]ä'–Þ­;Ëï]à€aÜÎNÏPã¿Y/DYËtrÁ"º¯UZM~¬¯PÆè˜‹s¯ù}¼r“×-BÖ@­äCÒìJc>ÜM”Âõwd±±±Lv–^&ÜæÎ #ý£†íc?HVÜ&l5Èëœå²ÛþÇá›záòyy97ïâú8\Ž6 HÓo1ÿØ"?ra#¦q´~£V†x­ã·©v]m‘8ˆhµaÒð^òedÌ}“êÀEì%pÙ¤gÍÜÓ'§«e7D}‰ZH†‹Ë¤Àç«G„%Ø ƒ-7…A†`BGÞ0?ýeŸ!!¤~«£Ë±z‰©ÑCü™8ì—ÈÐ:ûP< ˻喟/6_Âþó€ë’:uzZÅaÜ‹bÖÇÛ·«ß%úØ O›¸%–‹Ç#øIKÝ”š÷Æ6ž¡þØ¥‡¥d1ÕnîwáÁô{iCØoV�0ü¶ÕºùÄáÛì”Ó~¦^êlþÉ7zeø½à—ˆÛ»¶–Ÿ·{í¬«àI|”T:i&¾‹¤ô˜L¯îU¬¬æ¾–›3E66íÚd“ïmš�¸'�·œ8&dûáŽìžÀã9õÂëüüþœYòHçå›&Å¥úÑ!Œo{d<‰6Ûˆwl+��’{±4^ï2aËã _‡a#Òýñ �gq,’òÃ%‡_þSæð›Âñàí½ñùbÛŒ A­€qÏ)®“L›,F"O„ˆ¤{y˜bí,Cö@ÄA ›³|¶+_ÒHEŸévÿœ&˜ß®æG¹Mñ Ñg�h" 2<@c¦Ë,àUÈv¼38.ñdoYù3½©-K3gÚ Ž4H~8‘ê&8xy?/\¢_v_°E�Ãhà•B˜F™#¢Tùé:¼f1ÑÛ>h ZYíÚÆ z�‰êq»Ï¦3«‚:˜‡Œ$%ÃYœ¥6ë"Ûgñ(1J™ v�?¤|Kl²ž'Ô ò—&`6?,Vž:ÏÛ×€9öÌåàü�Nü ¿®3mÓcßÃìý'¥¶†!vð%K`¡»°r0¸®Û…œ:Ý"ÁûÔ�õjßä|#‰ ¬ ¬Þ?WLÀtà±'êñAÈjØ/]†> ô´Lµ#%¦Ùô—�“òøH÷â6v£ù23ðæò-÷~¦bûéi†ó®ÁìŽöp…׌ ›m›fJB$ͱ)flžØ%› �u9ž"ZÎ…,q-‹cñúÃÞM±q>ˆqÙzòï?ˆÌÌÇ''¼3ï'úJàXï~fÐþÛ‚h<`ðxmš^ûˆ^ÙãÜØšaQ‘ öM©d2d–L»¢èÙO±�&]ºŸžÌÊé–†ÉAþÎ{´LñI2¸�–‘I°ÙЕ-Ü{K‹Ÿ/ÔGè—"?2ÒI^ƒký^zÉ6#ì äÎÔvÅ�e>ïï ö2¾DBLárZZ­BûrŒjë¨ßÌŸXÛ2GpQ|‘o&5v<ûØaà<ˆ¸þHdo_ä=~âq°ðϼ�þ[È3fˆ{¶Þ|™˜l‹`“P%ö»—cc··²î–ÿwýÂýØáÇ[ûZ&Ýw/DŸÒí„ñ~¢0qWÔ=�ú_¤€}[/࿊c¼BшgÄva�MÖ-}s;oÀ��ÒÎ��b=¶ .Ä8y¬Ê„¦ýÊÜvxöÓËùI‘8-PàÈ}¾”:iÏYuÝeç["BèÃ�»eXiŽ�·ô�ßhÖÑö >—ÖºnL/Ù_Ûú_µ“h¶×tZ­«ÙaËÈ›e–0ê’Ùuuuù/…ÊL,9gÞO÷$‘×xÞfÙÙ$t]L º¯¾Z$U¸¨Ïã3³{˸Þ-Ö´väœ*Õ‹€7vJJ–?øØ2×´jN«ê:],Æ0�ú~áŒpGî8>MËeþd8€B]@e]–¡TïÄÏl&9Þ[Õòõþ#øä‹>ÿãx'àÍÒE�»l™a¶¤úº0ÛÃÊÛ�3–lñ °nN„¤EȤ„;À­Ú»p�ö5¸c×þÇ8V·Ô{a‘©ÛKKö³c3©9ÿ�kI9†ÿÙ#ú•�† =^Q¤Ó-ò!uúBլə׀*ÂlX‚<‡6Äúx?¯ì,².´ú5S躇Èyv½3É7¯ü$ÿŸø‘a"Æ-ºüwí¯3lvÝ–Ñl*g˾»W‡.§�C6orhHå·�vÁ—|0�á)Œ}S‚qKkYÕûÐȮջŸÜ´–ñ¥üãö—Xm´?p‹ÁeM~¬Ú['‚ÿ\L�Òý¸Nž Ôï Õ<`-»K•6gI~[>ï��äÈ«`í: Ý’Ñw=-™&2ä„òäÃt¼³’0`þÖ’Ú—KÇ`˜?¸ÿPò~o ûþ»ÆÛvÏØ�K«]ûw9 ;d›&[<»�/�áÀ+åóÔïäþ‹øX}X>0þ–^Å»G=L§´Š²$Ü‚ùk»õ(ÇõÀ�0™Ó^^½[F,†`_Â|ìĦeüD°…y'¡MÑýV»>Ì òL¾À¹’$ËXëå·Ë-½H¿Œ$1îbïnÄ둜ryÌ[8_Æþ3úg&'ô@’@úµ²Èê`Îí[àÙ¢#F×ç7µ"à‡m{ü‡¯<£ °òÞ—º§ºc*b¯—v·òtÿW¯òtm·ýÄJ$!¡ ébï–YÓž b�¤ô$Ùx²A,~¬ Æm£íŸÙìx-©Ij›úY}ãÌáo!�ÖÛý�Õ‘úÎÝhe;ÉùöV¾‹OÛo²=—÷¿¤ã챬|.øH4òþð°3ñgößÖ,�ÙuÞòF hë{lé` W%ŽPöþüèýà÷‘;Ç ê|^3)MµcÔ~ËúJýË—eç·ôˆ'M '½ØÆú7j’{`;$þÞ´¹FØÆ+îÙ_ÜÝ¥©Ü}ûû�¬©ìK7·¸êÚ/¶ÇWÒ§òÁãs–ÝlüÉŸø’ǡ`Þ63Q§k>™#ÕŒF#V÷'L8¡O…²ÔôÛ¥Õ�× 3&eÆZ„ìão“ów ÐÑ„ã¥ûOòë,“­�%ìMï'çXKè÷v¾Ó+#©qÿ#ÔžÏ:7òï3®[¯üàí?­„¤êÅÕôØ\>[ÑæiÕxÝä!îÔÿÛ¾;.•ô˜�È|…–Õõb/w…+åÉRGz˜îH~‚¬·Êm[Ô¾_'ñ\_ù²êZïâþ>¿ò¬m ½µÕ�ç †Íä˜;üoÊËÉý·n\ñ­»·¶Ù>ØeÖ]ptKÀz“.ùìøeôݼÃÊ'’‰Íø[¿Ty£Kgwa)é-ò],íOþÌÖ*ì…zK¬žEÜ©…Þ²,wÇwÞ¸qF ~íÕ,àPÃâD«]ý²¾PÍ&[ð[çr^” ¥žKÒBWÿ‘ÄFhÃÅFëyö4‘bÏ÷¿E@õvÔþ5–õ ÷l~y<ŸûE¢¦ÂOb Ùˆ›{fïÍ·ÀÀBÔ©Œ²Ë¸°âeÒ8íØÎ8³÷Áõ–öJu=uG<¥ŒÖåx~Ö÷ìÿü�Ö| mPZñt‡:±-w ™ð¼Ÿ®§vÀ$'å’“)õnÃþG´;r¡—óP"›gñ«LÇ:ô7#AgÅ›"Bèš'l×¼ 1„X�‡×EÓl ¡#Åìʉ½!û]™Ã…êO,Ò&M–?Ã?=Ž}q–øTÈËÔ¼�Æìä Pa6D-¿gÂUä‡È¿ð“†‘ÖBáiú¼ �y“ÿþJ|.§¢Yñÿä/Ñÿä/Ñÿä aÿòGÇÿ“ŸþX$w¶/«Bëiž’Ï�Ñ,üß�ÿ&pŸÉCÿ½Ö u„Ÿ‚Û¬'!?Vd<ò=ëâ6×R –C²^xJøµøN3�âôð†Â"ÿ/,kצ'Wų§Îþ%þ‰©OÂSá~à™s¼£VC… õ=]/åkè[ýqê}òY8xFžIÐòë;³ý’� IåÓáÉd+@�Èðò'ÿ‹×‡ðN‚ê5ò&wyÿø`àØ‰¿Ãråªîg¬¼ZUÙI¶/?8”0Ì¡F¡ûG t6†q¿®À�dÚKWé‡_fRRÇÉv—öß ˆ¾…û!“Ñ;€žÂiÜN¦}äðM‚} CÿÖC»°N£¶ õ žÏ”LE¿ð…иVb�àb¼¶1È]±4cü¬ Ä’GÉ7Ñ:nÙܶ>Ð/pýˆô[ÉòY³}°CwÁ’Ͷ‘`Ȩ¼™ÿ�€�8¿ˆž²i“Éü²Vu�±�Æ­Àû'`êÄ€€�Þþq÷ïɶ í|Y ±‡óz–VIêÛÝí·è�,»~Ó£é%u=ÕÕÍ‘ÿ.ÀI8ɵÿî+ìß éÄÏîÈ÷t“æÔÞ–ä_ÿÝ)–ñ îVÕ¿d¿û”pÈô‹G˰;¶jË`˜ 9²¶mÛ<.ü¯.ÎåÀãïúƒ:›{½ð'¶ –#YhiìîO3�¼üYŸòõ¼ÙyGD¾VHî¾vÏM =# ,ýŠ{töúŸƒ`˜ýÉ®?/Z7lêÈ´,;“{’èº; ãNB7[bËþ%.Èúaá©Ø;cpžû“�“~¤>Jø¿BG9:cäd.Ÿñ Ï}–Â=öìS'Y?õvÿ„Ç!šì`>_¥Àïö÷íÚ»åí”ykÅ».ï}RE�#`ñŒù &Ãm[N ¿o%›ÆÑáá˜Fε²ëdÙ/Kãüþm›,²Ë,ü3œ²Ë,²Ë ,,²ñÂ*Ÿ’_I~Ãó%ü¾Ç„že‡„²/öžê>ƒ„<3¹vj�ºÞ|ð 9h1»@^M™.[þYø®ë ú˜l;ì֭׌Îì$&”êìþÑûîéoégí †ßч÷·÷·tÙ¾Ê'¾ì,Øý•ç›dd²w~–øl�í�}µ&Ìöêû‘½ .†;³…�{JYé‘Ú-ˆ`˧øVßȳü/þeÆÛ û'†­þ­Yþ¹þ;l)v\㺣È\”ı¸ÃX-¾Ûý‰ä ë?+³n™ÔjÒD$Èÿ‹©çmºÔ2ìcœ°vñ’IÀtÈõþ§òößÇlXåâõ4N­[{Ó–Aß*±l~ÂôZšçÉ�=˜³ùµBþãg¸R/äûc{›9Ø èÿ!êa :q�ÏÖRÌ9òuä‡ùoTùnÄàîJÆ+õ*žÝÆØÜdmgûWlž'¯5¨ȱ·}†Ä]©v¬á wÛ´Î �ì‰tG'��¶í,G`ê×øoù?ƒ? ²Ë,ã¿÷Ûm·ƒ3^#~Øxò6.‡M¯Ýý¡¾±œoºñÒkw ¯d�éÞ oBIø‘ý—ý–"i%úXßz¤��î«qŽ÷ròziÂc˜ °Àp—êñ î/TËþ,!òE™ùÌkä Æ¿-8uD�ƒÂ¦c6ÆË–¾Ì~®ø¦ee«Ñk´­!ôËRà{ä$-±º"pL¾]ÏxÁ‚ú,YPä6]l•0Ù—OðÏðÎÿÀ=uø|ä/½~¬},þ ~¯Ý7SÎ[séÀ¦ŒÈ¼wò.ÄéÔZ2ÿÄLðœÜ�õÕ±ø#FÏÑ* "AŸ¶Ý—V‘™4ÿ&6Õ³¥©g‡œtCdøù#Òõ=†˜ß%Í×Rà^ÿwõ–Ýì¤pŒÅ¬øŸe�“Œ-Þþ¤tÈò;Ùai7GÞ̾z~Ël÷1â§…l;ÿâaŸû_À™ø|üño(ä´áFMvFZ´ÇêÙ|KÀIUùxá��]¼åÖÂ[‚ /“ê;ö‹ôø½‚ý¸”w>0G"ÊÊñ³û`02{%ß%¾Ly%žÆîÙ2!Ëï: &o&�¥xØùšáÿ[º<6ßÃ.ÊBŽÄŸ“F!Öêçà~ÿàŸ0“Ië�Ÿà~CD~GL¿·Æ‚v!Þï0ɼf’‡2=ÈθjÕû,Ù–KÂA"ÒÈîÕï“ß¶^¸|“gÿõþù?‹ç㿆Ûm¶Ú[ÎÛom³ùéÈv%õe–p‹Ô#cå™0ÿˆ¾·ÙIò~ZwÁâ6óÀm��ˆRñÔÆ§Î‹¶ZL˜zã8ËþpÞ1Ã忊ιÎ}“òÔ¨þ–¾’ð>’iÿ�àzÿÁ¿„õï;øzüi}¾+û_±¿k‰6 müÒêÂõÂíœu{auÀ šYua ¢G‰!³ú³úŸâs:›‰³|'Ý]XXXFX]]XHXHBXËK–’Ø]X~ì,?vYmÑöë}‚ë,³ûaû€,²Ë,²Ë,,²ÈGý¶ËÎOP‡°ïùgþfOÏòJ{mŽùHó—ÙþG›ßø‚a—{à mƒ–àÂf½Û3û ¡©×‡À° ü|áºççø¿�ø%¥‹ ÿc—‡�Äåü7ü Öþzå|ŸÏ÷‘C üŽgå¼çù†`Êìñ’ÈnÚàͳÇvwœdÃIW/ç“ù*'\¼e“øŸƒí–rÿ»òùù¼ÙþïVãÎÛÎÛlºÂãm·�üwüÄ—¿Äi ? Î ü~ÿâ-å�¹.ó«ÃÔ¢lqŸ–Ig'ø²Ëø”GáœeŸ‹Àÿÿ™²½ø®yé‡gYe‡9¶YÎYe‘ÎYe…–q–YÆYggöË,°²Ë,³ûe–Agý²Ë,²Èž1²Õ«»îÆÆÆÇõccjlll`m~­~­Z•cú±ýYcc9ôÉeœ˜ØØÙvá�Œ�¾Gû¸q¼d¯(œeÞO‘ù®AõÿÑ¿“ÿ•ã9?É®wçåßÿ“&ÎN1ŽÀ? ²Ç‚ÎùÎ3Œ…�Yøçå¸Ûúå&>½•ÈÑŒ2|–Ÿ‹Çíþ¿ùß÷ÏÉü,üÙÛ€à“Œ“òÞ^OË? ³ý2ÏÃ,ç,²Ë8l²Ë&Y/Q±ýã=“¿Á;²;®„NÝ·N­·ðÝp“?Àañþ ’FßÉü=† Ù˳È×°³!Ë1ÝœxágqßmæñÎþX2!–¾JÞâËYÔ{lc÷ž ‹d–‡R®·ˆÕŒÛ¢JénÕ²´‰ÆÃešdË “ow v:•åÔ~e×W¼'Q했놷Á•²xl²ÉHB]‹Þ &C’˜\í¶¼s§¶“õÚõeŒq–YÃÃÛ%ã'¯mÞ¨îÐä–4›än_×9È!ÖÍ‘’pÛãË'¯ ú%H Œ²—p3n¸ýð LO¨yØmãlÛ>�GÈx ßHÙݸê9ÒvzöM±!z´´y{/˜ [û¶ÙB=o{†uÁ˜ìàï­¬ÛYw¿'v�xc –‡©îPŒu3bAÂKYm´íü|†^·õÀos¬�r°³kÈ×uÔ{ÇKÛöÍ[Û%s«Rö:ž~DŒ™ä7¹n:µã.u0�F¥�?¥ýZ~6b_á�8Ý…Ù‹Ün„�/KGS‰LÞ1ÜÛÄz×�ýpßüa®²Ë Žä7I{dƒaF¤ (O! Ù!Y“Ó V!êó€NÇVl°Û7s…ªôI eúŸ»GÙ?/êé†pìºrcí‡dãØV]D+¬m¤™;Ïóg#Nû÷;Ô¸ø]¤—Y0ÜÒר®ÉéØ×°Ý¡�pm—RðòUºÃ~Ü< 8~/ÕÖ ³l³¸ šåÒËv�Þ÷}³—θ϶m¶÷#ò7ïvݽJyz–n6á“Á¼dɮݚqÝÄ0§L:¼í‰ â#çàò]Œm³ 6õz°‡#â)¶ý[§­™œ`Á[É\„Ì›2Vm¹é!� /<–fìd—–—k,ág‘ñgpLÉÆX能ºŽàÎ;Y/<á¡^ ïrj´ÙÄêË8XXÙÂ5bfÝ�dê>Ý-àíòõ2AÝ·Y³oê[_$=d6džJØ÷,¿/=AvuÆË7H6#«©EÎã=žû’K,„Î {à‡eµòõÆo¶=ä†@2Xáå÷$ÆÙxÈèÙÀžî³Õ»ÇŒdï#‹`\a­·Pú[m¶ð3í�¼0n�!ý´¼”ù#ä—Û~X`ü1žìáL^õ0ê} [r&9! òÉc¼ ¤¶�Wž2=^3¦w.ç ³öWË£� �®�Âg#cËG:�r3wù …‘-ûlâSl÷6LÆYáϨÜâËfÉÜöÂØu'œ~KÇV.˜ 9Ô8ÙÔCMà=õ-êÎädàÑÇ€³lŽž9Æ@wi&Oz™o=´Žä2 ²\ŒZù-‹w¶þå�,ˆ4ÆÀ÷tè“#¨mü7ã`!»Ó«´Él=OD÷!›ÇVrêî`‡wíž�J?HôœB}àe²[6wf[c+ûoê=ðöÝ-3$¶‰‡Iÿ†:³Ý—G`}º·»IÇ 6¥±Ü‹ù…=Fù8,À#�/姨ø‰çâ_Il£¸î[XèË x½Ê.̇êtì0êXAÔái!±�û?ÉXodz%!pŒñ·<=Zdç¹Ö_�Ó A'ô½�y9½Ýe…‹Ñ-§ONÛôY# ú³½l _n¾°ýKevÛ6zµƒoãŸn’k°IÕ’ƒa×rmœlðtê•…òK Ënì›·÷�äe—“,ãÛr÷ì2:ã` g·as#‡‡`­öRíð'/ìˆ[owäÌ��] e°ß#ŒØgr÷À¾Ëä²K®Ë€]à>Þ®�cKÛËlØ;ÈÆÌN½[!ýÉd¼q±³elO-K ïÈØ³ì»™O¶ò›}‰öœoà¹+BA �oP=-êwÆÙbO­å™ §‘ç|<Ÿä3ÂÖöéo>ݼáeŽ»ðÄ©s‚Ã.ôJIŸ³;" «Â”t»5åÊpÇ#�ì󶽑žáËt�c÷³fsæÀ„åhºl°”käöOnG’'|$“×á îfÛ±Õ¶pΞٴ�vIm:6WËQäf ÂjÍ’Ãõ?¬¹=I�É_© ß|"}´‡x·K²†Ý¸:²È2!ÔÆ„‚Rt» ãÙµ�úÛ³1Ç—E�Ô5ÜA¶÷Õ‹0C!¦@ôÃëËr›ìÂòl›3DwbC¶$u1YÃh<†Ù„£b{ÎN'‚À/6!ö á·%Û,ôE»eÒÞ¯!`e܇±ßQÓÝÕ“%œtáZÇ{¶¼/wËÔ‹§šðÐûK’ Á¯’%öo<�öñ—½—gcÜI äEø°tÁ<µû“ö€énp]Àï–[¥ãme7_xM–K:†ÂL™c è–uc›-êP¿nÓ/òis»ï=`ÛmÛË¡pnãö‘.ïdžryÝ…ô’[Ô)ý¯am}Œ-ÖðçÙIg�`“,»m[rìÂg ¼;òËÛ`�ž�Cd[Îi{²Ûµ ƒ3chà\s–6ì³ÂØSÎ:Yør7„ËnðMžý¿‘u=Ću::Áûê{³>ßc Ó kQÛHb ô²°öØ#ŽE d‚LéåýO^ZÙ¾Î[yݰÝRå>ÈoâÎõKõw�Ý–9Áj.ÎqŸ»þYCm.Ûx_ÔrÉàveÂ-î8m¸l0ÖÙ�%^‹×èî]´†ýîŽÃ¶ÌuÁ2þ¥“öìå×'#to�AÃ쟇v æÝ½A öΖÎC$6Í–Û=Ãi—c6ß/�Y`ËôAð›fÜŒK:Èêãìo6g¹o/x¹Ý¿PoLˆ�‹ùÆ�ÕÜÆ'eÓ«-ÛÞö0îÈõ&�Ø÷ úIàCtu8÷=KùdêGz—DLÇðFùoî}ÄŒô‘¶iÜMÂfNå¶Þ8È/<Bˤ�f Ô wiÃ`Þš]Ç+[{‰ö #yÕêo8@‡;.ÍÑîÃnñößÃþq±ø`XöÛq{lÝì`~ìüå´¨ÿ-|ê5öÚݽvuÓvrÒROqÕï!Ž"ÇÌÔGzãw…ß?9 ­‚8hz…í·o²Ëx=±øÙatzãÔ=ËtÙ—83ä0vƒ¨/,K²Í…ò|á’øÙ xQÈe¶^’cÙ/8/^MIŸ‹)ö$Ï#�·eeËcWcoq»|ºr0ìY:^ßeŒ~oâ½ &<!éaâø§ .ŽÝe (ì‚1Cªc¼¹Í±Ö»Ëæ�hš4€o&?gTçu[Κ"jUsuÒ&͈ä¼ ‡[­¯H‚¤Aâà™;›ÓY�²;uª¹[ »ëLͰŽŒµ÷.Á¶ æÿQpª<©~ÒŸB–©€ Üia¤°zêQ+»JxÏ÷xmc’¸f6k1÷9pN…Ön.°q˜rBãZÇ\ÇÎî §™í3*c¤£ÿeðм,þ")5•D¸�³âd`×>±6 ÞB±gâPÌ)G%½.2\ÐÎh1‰Du’ÀôòöÄâ�ø/oCÚ;ÛÑl%v‹p°nÞðÌš °o³ ¹/G¬<&¹±a²lʬ5^ò×Ù‹SÇ[Šª»ÆïYh8”£n¬§ É×õF‘åL™Î lµaé1JˆÚ×Þ"ÀMSæ#IVß§›‰ÉPßJøbkAÊæ mªu B©+¦%‚ÂVõ—Þ(»h[µÓêDzÂtpz¬qÌÝw¼Ìåã)ŒÐWyP½uE¡@ùö€-(è2<}B¥–0æ‚Q.SxãÄ\æa{qú”Zpâd· ˜ †J¥kóŠlóp¸gf%œ\Õ®Õ nßBZ”RÑÑzÊ«vÚàËõˆq,Õ•RsãÛϾ‘�¡D¦ÎÌUÇWœcî)PsKªª¿™j:P+Þõ21 kpy¢àªÐN¿0ز¥â ÃC[LúD”áu,’©C6Ÿ)Eôº�¢ )�ÂóÅËüÚ„�Ì#¡CóâRVÍ‘‚åÎÖ”Êû̺ ÐͲ·n±L¸84T³a}Xæfè²Õ%+p‡ Vq]»‹ÁèÕ\aŽ4€.V‹„UGO'îgo¸½Î£& Õh£Öâ"LѤzw‡˜À&ŒYô#+’‡´W7¢ÿ°ªRBÚÞu4Žqæ3‡-bYt rv,_ĭД§hܸª]Yé.K\�ýG@tOG ß°fûÀ@V 54Š'ñÞ©A�jZ¦Q|�ÖIpÁµßL.ÜBë¥É,Îk劼~±I¤ �1®a¯ 8 šš¤zýÀ¤K<{K“*¥ùp$°ŽÃL¨F\Œˆ½ Ê_1¬ãV÷U,ˆmZo©í.% Ù©ž7´”rlcÅZŽ>G»Þ,š-ž¨ˆ0 ß©q"¡Yç,a(€8¾,´…¸4^æDwF%•\雯¨e»#Н‰ë¾×÷ `‚;.0c©U[Ührè:Á°¿P„DÓe9 ÎCA‘%1ö2‹‰œtL%tüLBÞxj¥ÑfÙŠq§®Q–±ýÄ€gfëE¦¢ßoh›‘œmö%u3%ïÿ!çsv–½JIf· úý �s`ØQÕpÆÚ¿ö!Ìü@1ks̾B¥Œ'š ¢y@Uìæ92ÐÒæšO>ÑH«ï›ÅþæR DÃé]*à*l5h=`‹¤À¯ÔÎ*QwÏL÷ŽŠ\ˆÞ%ZS`P®˜�ÆfŸX÷AzËéœ2ž„ å9öŠ4»ñy�Ÿ7˜?ÔUĤæù…(†È[¶uÇÆZ5¹BJÛ~e!EWŒMïyƒ6¦�úËPb ¯Ôã0lä韨¡€Û·š€l³HüE7ZæUž1 kÁDÃßj¶¢áAUø?Û†bÃÈ í ™‡z3‹ÇÌ»£M³!‘|™èÄ€$ÈlÝyŒqJUͤËb…mFþP¾Fy„KP,¬jrk®¥j…P@•zçD^.ZÑæÒ×€W;èÄ%‰åfƺöú‚�›‡JŽË²j#"¨Xž!-fS”ž#Å43+=j �o2„;%÷Þe�@¼iïéï`,Ô>!£X!Id[ñ÷ µ¯K_XˆfoŒ±™ÖÇ;+_× KDå¾±Ë^³e„q˜„žð!†-°¨WnÆYųšDR ¬M†j4äÍÕç7ï�@úxϬc•pÅ«K•ÉP7ëè–À?û)¦œûÔ í`ç­îm〆/¦î-) 7Øç;Ä}�1!žž` 4�æ¦.@)ÜG&#d”àQz¥‚¯\†ô ˆ �²g>„Ap¢±‹#õfüÌ:÷x:Ë0-¯³\=åÐÀ×X7…/ÊßRìÅÐ+0hðÕG¶kÒ£¶lºG@´ܾ%Ø 5Il¢zÖe]X0P`a¨=#®e­ƒæ ÇLW1T‚Šã̲ÒÀ(hóæPhÆýY—W– ›àB¤à,”®Ë¡k3}Ëâ-î¢U=%’‚×ÔÁö4à¦åvaP^<ÌkÑ›õ‡ Ãjw…îZ²™9 @VÁ‡»6fÕx÷†xÛ ( —W,ÉÁªW%(8Ê!ŒeÖq…¸1„p¨S—bÔ)).rW˜Íœ˜âqU3¨Þ^û#¤¬SÔ�Ñ@e8�q�.ÓcK¦>Á%ÚÄê2¥WÏX¥T¬•ŽÐ‡P¦ÃOpŠ´n9•±-ƒ¤u¹©F¼E1j°ÖUgW ­[MÊJ29"\ifá–)åð•ÙÉRÜd(TJlÇX€ÓjËpˆ²åáˆ,]ï2ú2ÈU±X[ýVbÜG¶.(dã–á�—V¼· ]r×0ö5£‘9 › Þñæ^×4`¨®–æwŽv–Zuõ¨²ô-—ø*üEe[EYc�½·V% ó¬ÿrÁBhÇ3d~‚ȧ•Ôm T—‰Afä€Ò³ÈýV*_`I åÔ%‚Ï "hˆýî)(Ê« àF‹ {¹H ÛÒm*U¹ñ‰vRêR·c¸…5L—ã¡‹;Âõ¦¶ÁYÑ1ƒg9o×âd^´œ•n¶³‰Uˆª>%Š‹Œ9é Z¦Cîãu[¡Ò]I�´/S˜PP,z/8€…UóieׇlÊ™2o¾º%T¬Ý^,`v¡â4s°L[qˆèÎ Y`E„ªšk8…`£µŽ²ÕÌ0»¸´£,Ãôb€MUK,ÙÜ y|<ç½Ê·Ùk|D ÂqÚ ¥—Î:E*]9t”lQúŒÚ›®�Öå@�a*¸RÀ U> ¶Ds)³ŒC+•ž*÷ J«I×" Ž6Í|G\°"¸®ÜËP1zGâf‘PVn^Î¥¦,(¥-çÁ,à5.¹=%:IUƒ%W†C@ŽÞ«�Ìâ ѧå*N…Ð8b*¯”"°WyK"ÌìþÜÊ[ÃÒ,°B­T¬¢%r¥úKר¬~%]o*ô–úg!Vn8†”¦Ž—ÏH±M]#\VJe9å�F:>±kÚââƒKe#¦VŒC-bÚuÁì�"©®o‚äjÉ]¨ˆÉ\�Ö‚¥qÒ–,ö/.¥ZQØ’åUix8ô¨©®Uº t*´§6±ª«¢ÅÚ÷`‡_®ñäÊ‹óÁ)NÁôŒ¥§WÝš„0%.Ã) F�Å€J+%{@ç·î}%àð ÏDÕ\ º Kâ’à²Õá«øÄ¨�,¢ŽÕ’¼” õ�Ƚ]¿1Œ'p·äÇË[3Ú/zoB`6œw|«â4[`¡kªèš­¨2ï©äÑE¢BÌžrÈZß{š«ƒ÷b«Ò·¶(q Ä>û„vl…Â2 Õ?ˆä]Ø„8›¹”áýË6…+F"ªÒ8|ElK�ÔÒ¨UIp*Þ Ã”.ÉÕ9¢Ö-A‘4:¢g¤7´ WcJÃÏ0$X‡˜íyAÆvv‰jÚg˜!¯ƒ3^ûÀ F"Ò[yˆâ£Éí9â¥Ðþs,´[õ€1Ð÷.hÍ HøÐ3Цs�L¦&ë:ë ×�.¾biÍR•ëy–ïúâÚ2ÉFµìäZÓï4óW@€xa™{zŠ•ŸKÌ!Ò%¼F4X©6£9%�º“pÀ5´ïs.í/É�“ 9ÌP±Ò¦ÏöQ¨OUPø*õˆ*Ô¾y†1¶®ùšÃr)À™Ì%�|Ü+n±üÌ*ÊܘÌy¦„ØoOâ m469¿¹b »D 0J(Ó3Ž%Å~³·®zËó(3ÉìÁѤ¼FÊö�þõ�QDÙË yuÌ´>ùƒªðÝâs‹�O&õHˆRÛðzT`�ò‰“v~¡]KO´´’Ⱦo!ÝØÖ|_ˆ(À¨\¤e¬ª*ÒšÀÿ\0[V·+’/CÛRò ióó@jÄgý�dÐzN’f¹Â[ҨƎeiÍL¸Ä-çPb¿Z.®·w¯BñKˆ‹¥Êªæ]úrã´ç‘ÄH6…\üÀ WGžò–•±ŽÞ%hƒsÃÚP+J¶ûŽÔ¶÷QQDíƒÃÀó˜‹U;~ÉJEi&UÙÜÀ`+èõ!f�cUGòMÌ­µ~õ™M›º)jóõ4&`àã¾³æ DƒÐDÕ÷˜ÂËnÀßÿª(�#+œîŠ¬êø• Ó9/C«ä™@²–~ Ï (“äÌ#²¶Ÿ˜UcT õ”•¤ažž±È|øïâcJEV!�7KTœD ®ªÚëƒkÉâUT)/=MêX5æ� qÉžû黀m žÿ©OmÀ ¿Rãá)Ux>¡—†J-õ¸Xl�™—xÎ:«Ò ï’œuöÑ+g±G rI»ªüÄ a•jV™`¥vnqõn1D6¥¿0å.›{Ä0á&¼ê'X¥üóˆœ7 ­¿0bݤeÖƒÊçêJ› ½â÷™}®�1üJ4�›A§XŠí9y€îmké.(¸ôÙ‚8À‘VÃ:í ‰U¡jŠä!…hM⵨â±Èc9 Á&ÉKBërµd]šAmžÃ«8§� Ë1÷X58²sÞÇš–ûjÙmq}x�ÔÑEJû³O‹t[Ù”öC¼|À�86ELÙâ –‹¡Š€ ÃçÒ6“•nmŒBDZ•ÃâU êq4(¶Ñq,RÄí ·u�¡BªŸE–sZI› 0‰Q»„pÎ!™u�^°m�ž¤Èi`¥»8�ªÇ‘\¨ùˆÞ†'9•…"%.ú=£nµp£¡– ¦V]6M3±Ï¬ÂeN“"ú"Ô&ÌV<æ(»Eñý¸n»l¸þ¨&[ÀRîËĵ&Ñä‰Aš¥EUç‚ -{1aþÂÙ†-¢•“ ºó*Ij®››X±MÇÿ&«¶»D ÈV•|×|Ëÿ$Àø¹Bi[/ý=âh 5Öÿ·êŒ8/¼cfQ:œÌW’¯yÑÌ¢68V0Gš’-[jX‡;õŠ¥[¨®žea Šë]qpª86 Ÿ„¦Ñ@84ŽL�N´.¦óÌYiÒµtâ’>[Ø©®1ï/ P—§5âZÇÞó1‰¸0=ã}C–·ªÝFÊñIuÓ4Å@Eœ@½Zš† ­}Xu-¬ ë:Sƒ+Ç='#0…+ÚØì¹zrZ€øÌeöRiíŽÑ•ȗѹ–VøÏ0 GÄk!þZœ°n ¨¼ÝÝËÕp¡Ç›Šmê€ØßIrËb±×S€¦¹ó ˆp4›Å¼Jªë8Q¬6~ã†àÒ9o˜ÖWjT8wR�ú©v°¶P%…rb³ئƒ™óŒT8éº+ñãÅ”±üG§béný!$(¾·p ئ(»]Z´&ŒFb…KVy¨V�¸%'þ‹š [G¬2 7êE0G‘Eå|ÀЊ쇈EK{3Cš÷ŸXsgFj·Xw(NŸÝe<‚è GŽ!(x¦ t ͽá¶U|Ô×JÀ_2”òçç·Á)Õ9G’.­5˜ñ,o6Ë*Jšˆ2] JˆëúÏ9Íð %€ßkÌ3h�ë¢T—dY†š,õÏøƒêi¥^À¾Ð$4”- b")Ó9]gõ.£]kˆ¸÷ƒ-ë+þÌR‚ŠbÑ ×R‘ñV¢Ž±ÖrªDSaÂþ˜ø°(=¿òiAA¶3G¬L:GËR¥°-Z¥+PÍ*)¾j+ä8G+V¾#‹�Žñ¶;:íû=%`tVÏHk&rá÷æYeZ㼫@Å ø%dalêª)ˆØÏâö›³Ý•-Êã´qQb­˜öœ²)­•c[Éâ£�ö#÷•Š T4b1�{Í ›E‡´³(f'ô2¯(;¤V ÚáÞjŠ�=ûL:ó”[»·ˆÙ@ÔT² }„U…wŒŒ+©{ËU@|ÀµbUžeõUFm?^’ÁÑÇ#¯¯¥‚³rÕGÔ#®m¿˜�¡o w0±Õ“] K8Š=E1‘œ1†ÕaÂR� õv‰®N®³�ן1™´”wŠf^]G(ïŠwþÆúÑÀbå,�ÍkÖ=<wp v—Neö«/iQ™lOñm�ZóßÞ*]ÄN†?»Gjì P´ »hìF°BhÆ›¨ t¤Tn.í4ÄY™PxŽ)Pëï˜�};…3Ǥ¦¦¸fòù™9¡mºÄ< P�ܽ`Õ-¬wTËÞ»qsvƒoUC·q›=ãijÞ"ª-ߣ€-R»k1â€7^{Á‹PÁØ–wÚ¥Ñ)©\¼”xÿ ·SÑã‰r¦j¥ŠƒMð¼úÇêPÃÇÀÁ¦–¨ñâaòÂ÷mž5.YD¦û)¨)Åo¦RTÓæí�P7VXè\¿Ž[»õ‚�YÖa-˜!jžn·K¦˜!ùó(‹ñÒh¤Þ_YßxŽkÿc¸¡h!FÊ´ñ.‡Vl.#–€Ï0»ˆÜR¥]b epfÞ'ò«™d¡‡,«"«m'Ô¤†‹4Z_lCì(ª¹à—Ý{+Xþ&²#§¬«I)‡ˆÙ7\ªÔ^D¨q5ŠÂÜ5¼ËËV££}ÉIÆÎ:F_ÄÀNb/:­ö–S¶à‰dÖkQf °¢l笽o’ÂÏ8‡Üž@F¾L€Ó·XNvcÍ�È”Ž†*Y*5›ccÁM˜¸ü-2°Ð\T~HµGŸ1·ÛíZ×ixÐ^Ý¢AU44ŠXÆ2 ¾%( ðYŸ<Ær\Y\æ`ÁŠÙ·šŠ‡yhºâZ´Ö%R ÅÞñSq”ÓZÌÑP襶ü¹”0ZCW*5m¯9¾þ³67ÈpÌtU@j£FÁ�Ø„-VÀPF›,,¨øœ_±Ÿ8Šrõe~dl8â[5Wó(¦µÖr°Ýv€kÙÜ!E‡S̼JW˜:«š¿˜¥›5—Ö6 ÙiÖ-£E=î6Ы”ò•…ãÏ\Êž%Lêv³#ß%Ù´W5¸ôJãˆ`æTÐ  5�u¯H,)m(Ê@-Æí)Q_1à©ðå¸A˜8UEµÈ²æ¦ƒ3¯J—ôˆ6ÂüF¢Š$üö!v`z/É=q3â¢�³˜µ,7�w–Ò=k;Êv5äEfÇÒï<ܼjª�c‰^ûE)a}kR¶–6 ,•¯æ9ZÛ«Ôf´ËÒÌìâ k(�õ"XûL¼SvKÓca:Í3x�Þ„_Ì \ˆÃU`P)Pá¾cÑŽÙož`²Ë‘>âöµESŒDf ´s˜²ÈT¯Ì%­kÐÇÁ”‹AˆàÝ;ÇdA¡¬úÅeãÀ\fÛ÷:2Ð –FÝHTãLë*ÑcNkü1ÖRÕwËó(û°–ü îÀzñ„Qjm¼5}!¨5 0Å÷æ"¶‹m5×Y%VÊíõn&Ò¨Öp*$ÆU 1{—s ;i¢…¸b*„&‡Œú%‘PVˆT6°å¦kC"íßñjµžÚ-èL1.Ú$t2ã1…К?q…£¡¾ùˆSJãHä®6K®Æg/WûQxVÔGã2ñ1¬µn¬¨PGâ—7ŽÐ¡*Ë<šV.Q­ƒ/¸ª°ì5Ú"ÅY©E-ƃî5 �2ÓRý‚--ñ¨Ã% ùUEÅã1[å–þ¤½W1q}šÓ½FFh˜&ì<\P¥FŒ™ôüÊ4”Ö�f :µé �GpK@ Ç_ÄuÆšb˜è¡ëÕ/Ašæâ2ÌpúÌ“…1Ô‚[ÎYêæ*ò6£¥Â/x#¢<ŠÇïÒ£¶p³ˆ„æÓè©÷l~¿(™÷”:0µ-è`Έ<09>›�ˆ”øËP´8†œ Ý}¼ÓöF�ê9ªÙ¯XïO)�Ï!°5—b®µ4˜ëCÈL£É鼅‡¯h]0"%ʺõñí•õkÒ5"ÚνÑW�ƒŸ¥bâseØ»õ•'NORŒ-¶ˆ«rf¸ïq¤`bÃæ¥urÓ(Ȳ!ŸfT&ÁoÆæœKAǼÅ�²”¿^%ÆÚX�Dmeö)zû‹‚·R9;À”ŽrÀxÈ—QRU¸h® 'Ný#Réë,í,¬D9ÿ¸™®R€ñŽÑ€¡@{ñ^bŒÑ¬ÅïMÆÇJ¸&X?Bý5¡l4ÇX UÜ*ì…êÊ”Ñ]o�1NZø*ž°JÍ9¢Ús½\0‡ZñTt©m´Õ�SÖY¢„£‘’j³³P¨)z¼ÀÓOv(o­*ÛÙaÖîK0H«EÝÖÞÎ% A°Èè¯xýZÔ^_ì&*:BÌñ@ÐPåîCF’µëÃ_Hd~•§ˆÒ�·Ãœ'‰o\hMF«<¢Û0Û#]"Ü5ÁÉ,²bW¤(àX Ð�v…îZ`ºýÌ=¡” }%÷eÍŸQ `œ™å¶p ;v+’¡=¶Îï¼°_Ë”.3‚ªÑŽ¢Ç1¤*ÎzêOPñŒ°�]Ì> G©HG©½�LiPÌ’¸¯Ä J¨(*ýå�þ1ßXÜv§LUc¯„M€µ¨h}á&…�·¼ ƒ2Ô»éþóŽ…´è±w4ðÔv³8#âc†5O,q®#Z…¯PÍzÍH:¬©N¯ûæe…V�OíÌêŒ7m¤zŸ¸x`r¤pQµ6瘒¢lô !ëF£‰UeâЀ.Ýkǘ­ÈÞV²×8ñ/q¼³ÈŸAÇuð¿ü‹ló<Ö‡wƽa&ºÄiôƒ…n¼K@>ƒCBÌ6�br�l3¸¸Ì|K&¡– ¸Ž1OH �膡-jå°Tàg]l` Vªžjm‡BúG\½˜:‡œq™ªDi~n4±kø‰ôÿ*&…Œãâc[ÛGIàܰQ¦áW‡~ZŽÔ#dºùQ=ã4tCC|ù̸–]kÁ- »•7çÖ/5ñ¸ÀXÎYpäÐ^ÜÀ�MR¥b¨NÚ+·« \mâ©#o^„0°4*êdÀÚ¯ê)i§ˆ#ê5 ®æ¶Ž„ZæÝèö‹¹€ð*Ð †ÌŽ�ù„î¡wŽÐFwއFR¥¶·:+O¬=ºØ¬Âº4\¢C ÀÒfàÓ<¥ç0Â:k¥1X›+òüÃÓº‚ÌÙˆÇIVªîns)amÉñ×Ú&+K×A€ÔQ°93ë©e–ú‘[˜�Ó¼ÔÂ1U‰0t}ÎeŠzø<í&ÆfäŽû£AZƒOV3 P]ï0!•NîªëëÞe”YË+ýÉ讀 6L’�¼P^·2l#oCrñ騂ØY˜íÙb­3[ñ´åwéNå˜;l4³aÝ:ø›Tpp`?pPîrÿ¢Ò‹é™@k\F¢, ‚Á¹L€G‘,'*Zº% ¬D†Í'0µaD¶+Ú+Žj2�k†Uòw–[å Á®Ãͼ0TfWÅÃJÔ[1+¬±cXý|Å ®Êë, °*ëµJ‹aG·_ˆ„Å.^ûFÂZí+¤ ^ÖãË:cJt�«{&c�’Ê÷JË<ßù/£è¢á%Ä S|ÛóŠd-]áD8”ïÄÈæ0{!ëO¢½óö5m#šÁÆ Z8›S๗˜\÷Nìl¼Ä(|\<Å tôĉ`o±]`g³½“í™æ÷p"Ö7Zç¼*qu¨$cßHÒ¥¢UO­~¢$Ó&Ó…<2Âí�ë¦q ˜*Âé:ÀдDôL#܈¢ºðtÉ©mq-ZûßÚ©À§³Y˜Žméq¦f.²GúV”Á½½3.�·Eùˆ�8„Ü®N•–(üâ$Êè�Úë9†ïø 'G¤<ÈÑ[ó¨›3DÅÖ¿$Fõ­j ëò4}Ÿ˜Aÿˆ|:)…©E€ ‹Ô:ç[¹¹+²@yŒî¥}q°(î~ábÛeÍ%ÙòBª6šcCŒqÌLZ.�t•L«ÓXï*ânÄ„8#pètx”^ Š^ˆ›ŽªkÑ):�Ûn~â}äÖ�2¥Ã€?ˆèôtHªýe˜ÁZ‚›¼a•Z¥Âœ®:(Q‹••O]Wo2®&¬to[”Š E¬Ek.Q}w-(·.ï’ÊHà$áx¾&3xÚè”t¯v Ž9§^±ç¼ Ö=¦{�÷�¦Có ûÑ]}tË$wˆ§ld³Ì=U4à½ðó ¦h¬üJ‰P¼¡ÿ�âq•IŽÑ1¦¦q ³÷ˆÜð£6ƒz Æüâ” é§·HÁE@Y|áÑëˆé–,3j¶úHA½¨Íõ‹ÅpöºŒ CO§YB R�÷®±-á›ïYš—…÷yŽ„ÜÀßu¸ âÈx†‰±ØÙ¾3ÐÏ*«ó¢Ôߤ:¸Íˆ«c{Ë,BË÷®.ŠJ–€ÜBl5  “8D¡Çxf�kƒ®yÅEšUkô '¤ÃŠèã1Ì+ÇX‹]柲Z À3¸Ük¼AÒF2.þ�Æ4ìN/ï™I¸´)½ÿq™`.E¿�JU¸äLj¤§¥R�Nðm8�_tŠé¹iôKʱzéx�®rÀ„8ŠúYÖý#»ÙW÷ù`)Á}=`W hër™�q�õŽCŠÁ| bqãŸh‡³c¯ñ:8Pºar²«¡š¬{ÇS£GäŒÐl®CX˜(¿‰„J4¶V6u•Q¶ÚÄ*圼õ`b¯¢ øŒ!G‚:R)w¶¬JJ›Ü�æ1vñz_$DÚª6òYhêú¡�j� Ô È)2þë6«¨ ÇW7‡ ÃÖ®'nÛá]ñ‡*㘠‹µϱ•™C¡%¢„ͺ1’«Ì¯¦n¼Üs¡ËÞÂ8�1pž¼B -º$bBí‰s7´"i¤áe³llÎ Ÿëhþ1“0C@e‹%ÞΙ{]6((¯¨ØBЪ½"$¨Ø=<1˜+™ÈÀ@œ€«×QÓä BÙ½5.:O¼f+hRßO1½8­ yçÇ´-‹ —aÝn˜v-ðaòË:“7ÆáJA^7¬Ì,¥MyÌWÁÀ({•-6DŠé¨Ù¡� wå³Tz5ä¶nª>12$/n?؃ ‰—P¼©¸¨�˜Ë8²<£åDÉfR°Š¦T ÷̼kS= }!c”—˜e·¼¥0õE‘¼OPê›ÌºÊ[$ü™kÐ&ç{†.}ºEasvç1 kÌÅEO ¸”�÷ ¹ºE¼ÙõGlQ£]!q+ýƒxƒº`ir¾àQ3ñí­ËÅM°±Ì‹€;‘Ð~†�RÈè6ÁL‘]dàox±4)öéÄP@µU•¼ßXІ“6`:Ƥx<á~ }' `TëÕâtfp•¢‹ã×fmVÛ¶1’¥BF)_d~âqV°Ö%wkϤ|F碻Ê 5vqªOÇ%0�|Dì­Ðuz\XšÈ ¡:nTMª¿pEb9ÿP1)žÑ™6©ÍËÞ( ·(Ìø�¢\*‰vtu‘¨wƒf€‘:ĉaìƒ#Ò� t)«Å¸!&SÖbéðe—3HÀ%”í§z•ú“ú±¨äEnéºö…b°UC=iŸZŒ+¡U5’RÇ‚…Xf»B Z7.Õ iy”p¥Œ@osëª/´4¸ Ô;Ц+ÌñGm⊆ÿ L858 u¢8—Rëš PA•ccCÈÊv1rÄãPX­ªæTÆå—p>àX«€iélR1( Yox,²Ìƒ´?àÆAꘘ7@µ”å@�L?ÛµJ'VÙâ-poÒ}‘F)W›�€T…ÿé)ÀF%×6@yб1ñ©á–� îh}HœZÕBåýEd]=¥" ˜õ3bC§d£h3Q„ìÍ�¾˜:+u9–¿ Q*®âþ£þ‹# ‰Ue:Êvx. Kâåwã êf.¶2x±Ü¹“_ ó(ÒM—æ&ô–p~àÜʪйƒx€U¢œJ1e\¥âgÚ»~lË R½‚Õñ!9a¶â%*x_¼v ©Á™^¬°ü°ßpEÔ@F‚~cþŒF /pÝÉòýùH×’$éí)3�è% õλKЇ8`( ër°©õ�ÑB=‘£•üí`ÿ�¢÷w–  g–3È=R ²õþæM>?ÔD¼Á–Ö†: ¯Ñ¸-Kö¿î,“Ð_XêjÍÂNÞ»‚ ~°PXÇôEG@ÄÂ. âßB 蘶¬ Ê™(`Vê9؆2‚Åò\Bêt™‚k£©„å%ÈüL|`Yµ(•^‚ êwg'0¼·Ý©ž^£¿�C(ž€L4¤&~;�@öˆïÚ™óòF e¢MÛ;–‘³d1îYP¨ÿÍŒµ+ÔV Ο„´ÿŽ ºÃ FR,gÑ„$G¢¥x­µÑ×c!g·î[6]Ü^$4^*ÏÜ¿=Ž눜Bâ‡â!_/ÿcQ¨Ñ}žðPE¸&ɯ ‚üÊV!®Ê`ƒÒ<7â†ÆÓÞZ]í×0[ÞÉ+Y0S‹¾™�òø„€-X¿b\ª}PÂÏ}(«äIB‚�mŸˆ =&Å£dw¶qÁûŠow§î äyI]Äð‰[`¾�RXdG«Õ'Y“À»©eLê”ÅS©f„-/áö ^5Ì ê,Û6`F}¹®ùÉ`A»C 8w€¢ÇRï).sV³d³”#²°âg´j?ÚØ&Ï…p�¥žº‚.¬æ E¨(Tã¦àmìôX"Äz±cËŽÑ�%‹1ûOVÍËvØíø#ðÑëH@¶§rÜ!é˜j´•+4v"óE[Ö ÷Z*Ù¦S$VñÑø@s0h&Ùë§ü-9v¼¦½¢S€¡€Ÿé„Š…rÀ#G7¨ÿ)Ú0f+jýå,êÒ~!ÀÐ㘛’’••*r·ë¬=ž" À¥±ŒíôŒÃÍûgt~ìž�ÍV³ðŒ0“ ¢ÜKôPSÂl ãð�K Ë•ûÐÊ( YY/|Ó(ú¡rc5–e±°‡]`R†Ëëq0|ÊÕ#÷e1 AýL UQÆÚ¡Þ5üÊÜ¸â‡æ(ØÌ65·CË:«·PýÁœ•µ êP€ï<ô”ð~iA¶su‰Dçð@U® n$ÒìûeV¥D†G�bKV¨4%'ãªÌVKš.�°)KÞZ(¬Õm¬Õ…qƒ¼H Ùr¢&BmùUÜÉ…Ö%œ›P‹gÈ,ôÄ^˜ç16 –‡Š!éëÞ6g÷UËÞY—¢ë¤Òd¢‡0ˆé| üL`ÁpÚ¯ü.�ž’¢*=fk´]vŠá*|I¸nnxýßùO%] îWWˆL(÷§ÜÉúŸ¸àDdu%Œ¥¡§—ênÞ¨” ƒ4âª8Ë�8A;ÜZŽ;ø•ÂÚFäâØÑÄ.-|Kû�Ðnª�¾°C=©KÖ):ÎÌݯa�ZO[ý%õïqû¸µA†¼š Ò™ô™Ÿdk&êæ}¶%�²˜as¨Ì"C�Ù)‰®[1#8%7Îoâ6/^3ù˜z½K%$ébª_»#Þ&Ù„í/¬pGì# ·ã¬ jˆP(¢Ö €šÜºB¨;0l†Ç'Ä´!z劻Æ�H¼Ç;‘ÇÖqª€àŒ¸:¤µm§÷ÐXi»Ï0PéZ‘T$ã2¿IdÄ |²P:Ô›—SŠºQ¯„ƒB[€‚-ÚL¼Œ`@ËL åŽY€2ro‘�UÜF¶¼+ …3Œm(Ž. T¯>q÷-C*\L­0ò"ÕAN{A›ù—þ ¥;Ÿ�†w†‘œQõ—¶m¸kd`0Ùhn(ø­JÕÝé¨]~.#˜¦nf}ŸÏqu.ø€¿�Á>!¨U³­@¹%R±ÝÿŠ•10 – Ž7Ë ·)‡Í%b¢ô6›¨€Z„ƒÌ0)gÉK˘'5dž°rŸ¬FëÃo™B‹âÒýÈL¬K@/F_Ò–¸´_©qB:£òÀ "ÍÃ�„" fVñx¯Ä¥ÿ ¨ ™ÒzË0]ÂcËiæ�©½?—îâV$rxÇZ``Ö€©Z-ÚâºÉà¤ôŠõæÜ)Z$Q)]dÎu°•As6z^%£ÐYã0XˆSÊÅð$H†lÜz­û"«œËÈkf¡¹³×€¨†qÜ»„ð%ÐPç¿0Ž ÓZ†±e¬IƒxVy"+*�«\üD2‹PîŠø€8„mÃ3¦ufŽÒ 'np6wÅE×»÷_2”ĬhðhùŠ÷í{YoI`‹\ÓŸÜ 7 €{²óN€� EEÛ‰�!O¨kÍV|Á`j´H`õ…BzÜ-/íkUHó£ª ÿ‡s?èÃ+¸º1é1ÒÅ’àÙï‰h$¸ÉPòÀc®Á`Š,ÆÈåÔr>³­—ùŒ–WÔ#yŒto>eÐÓ­Ùï $�F(²ºâhºBkE²Ì9­DÏøË+´®?à'¡ˆnØ­NZŽ”mí(4ûëBŽä« 5jæ$s˜ ¾ÞÑ�$‹¡ëòÄ a›¬ÏÄ® Õ]êŠ9�³ÌQ (‹Í»™Y�f¨1uóVÔ · Ö!¤vb *În¦zoÜ\yQ÷W$¬…�{ðâ^° #NGq|ä]4a8pÊ0îY*�2ÖXç–IÇIfF'çõ5u�˜@h9ÿŠ @‡~ïðÀ�Ux˜À~ìÇ'Ò ÃúˆØÃÁq¬¶îfÖôôEšÞE�ÿ-æPSjç"»¦ùû\Y“Ìå¡¢áQ†½V,õ…?™ð?1 ¶—åòE)�ôø�´Õ«e攺Öþá„ÛúŸr±A(ÅycÒXz’÷ÿ D®óŒ?¢ Ç,²XKè¹ä�Pp@"EõbÍ™“Ó’9Å�Ȱµ²*¿\ÃÅS´†vïD‘ U€Ì¨Ù¿x\³1‘›�+àa ÆÒ´o±m)-í:@eWè†Ñ7Püh%ì÷€á/,Ø R(¾D°Òë–]š¸Ü¯(†Þ¥#81±–”·cêe~ËéѬ/k³�FæPV|>uqÑT+K¾˜ìúA±µÌ¾ÿ¤­rŸ­|K³ÇZž8Ž¡¦ø†½²þç ãº%Y¶Nvü}Ãd`|D‘N«ä Œd””ÐÊùZ=‚z¦Á|°Í¦4\DÌê?pñj?r‰QÕÿQÓ±Fį̈Xz?q9ö�ܳ&ô*‹{<@î�©Âž¹öˆ�ÑýTL£6²Ý@MrüÆ'IÊýËnŠcîlþfp ^IMEåÈ;᮳̎ëïÔ$J² t;CЇDýCJ¨(O;È%µQ/ˆ–‹Fª#§éú˜1P¶;RëfýX1üØ==Ü¿û#±5»P£k1Gc€%ú€/P„cqm5”tA"v—·Sºç>H@ v–åyªñÂÙÂBÜt–°�´}@£Ì ‰¼½á@9„�’¥k¡�‹4Ê@cˆŒ:vEÖZ¤ûJ’<-»1ë0·,VÛÅî ¸T¨xK¸¦½%à™Ñ½ãH3n{J�²FΗ)ÙnS&ð–{’­™®OYÿ±“iÙž ‹ ò{B�]tˆ& -’ï‚âÐ-ëVЙ–‡@¹’nlI˜FŒê,¾/B_æL4¿-̪Ï()îTÒUä”ÉUð?sc_Üö?¸ô>ßÜSõ¸ôÔnPá°=šº8 ˆmÿ x¸J¶-¼u‚j§ñÄ^‘èJÜÏ3ó 1 'îÛãÿ`»Oöh%ܯ¸Íè&AqX‚©/ÜU°ÿ½â6^¿Ìç®çú‰éZE¦sRŸÇH>�Oò�õ?Ž"VÎG˜×yH:'ê76•“ü�¤�cCbr&AKsCa¾9¸AâÌ|\{pZþ-ÁP·Š§½¨&Õëà k̳±£'yÌiŠ°Ì¾já™VŸ×0kQ½ßîo`+nq”ÿ 1&ÑN겤×}û<“º."ËýÀ4}'ø˜Â ¦ yìq„aÖÍ‘?ް輑P•—•˜Ä¾á?¹Iac*³CìFA€;Œ{vþd&êT�~¤ÇAC֗Й]Ï܈´%‰ÕSŠ%«4¸o)Í}!x/‰šª©€ÅJ¬½p¡ ¦s.Œ|Ôl¡óQWòÕeÒaX,¯±ê•Å ÁZ,*——ƒÖ‘yýÐö…¥·IY­âijØn.Õ®ÖJ‰ž¤Å”�‹. Àf> á E(Í‘éRÎã$§Ú+“È…Ke™a?è*3~%£ó—̨fY_Ÿ±ÿ�ȼÜJŠ Ð–µ0ØÁ(¬)[‚´'ucŠ�jú(厕ÎçÕ)Vô�Î>QŒÀ^…]R7•1k̦%5Ä †úqŠP,Ä×EyÙþ@¥X‡6TÍŽad¼/´È™¸ >äoZ®!V\ÜÈ­é0ýÎ%_Ó ™ü!O‰Ú{E¼Z�§´Á£Ú¯¨CsEA GœCx0..²Â�½à5þM2¸‹Wv˜¿ÄÁzÑBS,÷¨ýë (€qP²]0P¯ø\C]ú~ Y€á0ËŠ¥JUêAv!éåa—äÊÜ­µRòF”ÍÑ@(7RXàù¦Ò®£Ì\Õ€†€<»žUÑŽá(b¡æ¥†RãuA3Gó�ùéÅѶH|Ç›Ëõ¢†¶Ê-kø•G½B;�¸§¿~Ñ›D±!i*PèË$º¸Â�ã•Ä*èAxWUå÷E¹–aH3&kö—±m²ã LTØLo¼Ì$ÞÁgidD8ÍÄd«C¼ßà�:�`"Y {Ì„ˆ€îŒw=–}\z0Û·…ë á¡A‡ú¨[ˆ3QxI™óûC-àŠÞ·P3,£:U{J”²-UЇ$¤K:†Ï•{Á² òö"šæ‚üÃD|ó•`B?–�0CÕÒæzÊZ~²–l©Ž%På¹cAm¸ ¨©aKi´�þ‚íÏ�iXTÀ;Ð%J‚««DC¨�¼†`â^9gÊbž?&[Ccâ—ÙéR±þÄøˆ…#Ô• f¹ª&%bÎÞ E�$­ðH…‹…Ûõ ßáfZ‡ü3­eõ $xa(&9´šƒ�ÙöÊØ2¿¨e – k,/â¥OÍJÀ…ëfe[ÔpQÿ²Ë¬«`±èó,�Vî¢PÜnà•Pwæ#b–9æ €]†+´ºÑ­‰ÄFÍSPŒÁŒŒª‘,®!A ‡¥wž"—(G%«äÓ`Ñ`¶a âPCLÆî©À(†¸†°fçO«î�?Ô Ê™v î¥}Ã]“Øÿ…~(a¼�–—eÜvU©]à–^§Ü¥‚ÿ–§„É+,`Éü×ý¨†n‡Ù ¢báC˜ëÓ·ý»±†Ñ X°ÉhâáÑñúDáqQò”[ü¦×õQyùŒ¬E—i.ÇÌpY ÀÖð;7Zó �I™Âõ µÙþ0`ÇüWðBá·1mióx˜TÁ¸žÜ£¬d\½ã[U˜øìº}Æ`�%•„¡„¦ËÈvÐŒIŠðE ÕUU×YAãl?x!®Âø JŽq˜õ¼, ¬w ûMþ°ú‡ZW¬©Î YÓób%fçY µÑptÖÎ�HÞpL±º )ë10ª»ŽÐ€Éš9”d…ÁO˜Üý°ýMÕRæ¸g³ ��qûÔ:¿Ó´¯ø>%áº>ƒ´Oöú›·ïÁj×Uˆ.†k‹�É›�Ö»c³Œ =᪼¦:Ó9/…`m˾?Üý…%œ$ð–¸ð-æ!"‡4ýJ>Yÿµ|L�ÿ½¡¬(Pî{E@¯·Ä*á넼¢I²ÔçÊ…±ÝþJ ÕÏ÷‰\‰°”Ê‚ï†;X Û+¨®B¥éZ×&eýÁÒ¥)º+½òéQÕ6�wŒEmŒP]öajh"ˆ²\šÆ’åÄ+:a;%ƒ.¹`·$À«ØŠu'x÷œ‚R‚ǼÿØŸûÐ?ae¬÷ŸúÿR6~hÂÙTϼB�pSw«ø�O8^#Õ}˜Ž×ºg«}Ðe*�]au]Žék¿íÚ/õƒïúˆ9÷§røQ4ÎFÂÚ‰ÅÄP |Í*ø_¹‚±ày̲i�l±æßµ?1¢‘üLá-w®“*d(ñXÐX4qkàc‰éÑø‰?=þ Ñtñyéë£õ8hyþ¥¾îÕcÍÎШeNÍ“¬B¡Ç5�˜°eŒ›Æ¢:>™ÅÚ4sN¸ðÒþeŒÎö¹pRÜV[æ gÐ0tÛÞ±l½T‚ê!€H3¸ÐöH�?ŸÄ%m?�FD9C§x©™ÞQQ¬Ó„KPu"/�®¥D÷Јä=`Þÿ#ûƒ¸¾|F¤â2´#‹îL< .À_£ yý‘Þ^9_ÌZàTµkÌ ‡åþàNǺ›t{ÄÛŒvÏ¢ (ÁŒ·’qàD !*^GšCΖ¥©uÕÌœôÆ =°hÁ0¨‡B8?NYTK*â õþˆÿæjÈÆI†Í™:Ì¡«!pK»Ržª"®ìD;Çpl”B�w�˜ t’àÅ\±ƒ¼¬¸/ð˜�Í~¬4i­7ˆÆú�©{ÀÈíž°:@ºZ±û)Q°:½#ãlnà. WQ±)jK,KTHDŒ0í5^”Ù˜ÛuŒD‘+G}YJ2LþâµRÈ ß!©î¿ÈlÂ*ˆ×~` Ü(B€û•.Ù×T ©v9eBës,ðxŒ·gó´æ0Fûów`GO«Ø€ñòË<:r÷‡@ù%#ñÀ‡´2UÂcr¿|YÓé…!®è¨aŠÑÜ�j¯‡ê .ëØG+²ž á«WI—ñNŸ± ŸT é·à h„hÚÛ(çþyL} ú1‡üùI¡.�)ƒràŒEb Gµ‘úeÌjÀ¹3^+ªŠp1q³0¶Â½Óõ*:ú0A!€\5æ ˜…[7h­µ‘p�ëm+ÊÓ,;ÄB‘ˆã&Þк]’ã�»”­04 ¯XœÆ’-ÃÉ쪗<•ÞüFγ£Ì‚ÙxfF+TÅÅY·µ°�è=eÙ*ï ‰¼ Ã- vVöƒÑ) Öèhi‰šÂ$ú¬ÞüÆK…qU)ƒÅľ-Žì$cPȸY/‰«éú”Ò¶¢,)˜sŽˆ•©Ä f2îù¡u-Â�BÉÚ9�m&Ü…?™ó8ÿ„´iÌÄ&ÒS„µ{ ÒLØÄUÓèÿÀ¹\Dºbž*{ ´SÇŒ"TFØ.3¨äÈ3ÐEa35šL±Ÿ‘(ñJ—(?lE3¹ ù— «€…¦à¬þuÈ­–XÛ]W–Qr�x/ys”S¸ì;ËY|c”§ŠöÅp ßÌáh”³ R¯cu˜×i$ÁR†K¡{®ð–YSua)íVl)} åÊ_Äm|0zr¨¤ú˜˜¯²{‘zl­ß,`+•‡ËÎØ·]g°&P—œÊT×ûgþ“êý¿õÐï‰{òóõÌù‹1©ìÔ/Ó>Éx™a°{R¥–L(ë/þ,mÓöØb*.ߦf\¸Eº¼x#]!STBòŸ2ŒÀ«b,±£U_ä€Ô%D•sù ÅEæ1¦¾‘�N\òjQK¢>î O£~•+p\þd$Åô\Îàkó0•ƒÅ ~n6—«ÂØv U6ÝôD]JFëF}áKïj–5ÊDe¦ˆÔj#/39,Ék"Š^ÐV™SHŽ™� _‘)bªæ˜$æ¾ ]±0.ï„KëDwH–|Ëñ vKR—ˆ*6}Jj1+Üœ)Jî¬chµÕŽ‚�ER½&q˜Ccé¹ÌLÆšóó;ãò–<²`YEÁ¹U™ ä€×<±çó-¸&R„«æ‘›*§ó:.ÖZÄ»~‰�°[Ý!U8—3_ÞÆû’ÚfË%­!æ Y&"ë~æeX‹”Ì ½e¡ ad‚\ Ä#Õ‡æXzàD’×f# J÷†’”|Æ` %y}ÙÚ@‡YåŠÐ;¢LÉÇ?,OtLôu¸ˆ–Ê_ÝîZŽœT¥£¼¾ðô=¹odõ9]û ¥[Ü88éRóWXR6'F<²•_Hàõ• ¨Lw!9Œ"K&s͹ä_ïxµ”£{‰«`A„Š|Áÿƒ±hƒe®¢Õ‰Ðý°ÿŠƒ­\íÀ'yc/J[…!”wä—ÑÄÌ!''Ñ.\BÅ�¶ ÿƒ\ñúeX*eÌDkÿ” ›î)0Â…¬ßÿL²Žº£¹©¾§Û —ÿ:^>�Ô¦ø!….ÃXR—ÊWà%%M‘Íb0þOÀ}înh¼ ÷–o&¢´ßøL¤¬ ÔŒ¬«É4ö›Ì nðĸGSdT�x&ŽùÈ–YHDÍ ”ªŒVå5ÔiNê¾!Ú»ª®#¥åovsWº>Ƀ�R~NòÛ @äá™ó©VW÷Xì#§VäåáÐâZØÂùlýL-0&LEì0*ðÞ%®�YÀG@¶ê2õ®-Âê<‘S+üÌxx–LM�¦àµÙ_˜·‚XzCLÔ5\É;¡]åëb¹Ú”»g?Wó“Þq©Š±ÏÖ–xŽù]äe'�ý”èâdr-¦cÿ"ïGÐ…YK;J;¸*÷‰¨,/þ ‚Ù,Dz!ÅìQÌ{?Ô°ÒÒ¨ êŠHl½«a}„ìD¯å¨áÒ3Þ(VW¿Ì ’°äfû•s\G`*¼qQ´ z+à š.Ï“ •a°\ñÒ=~©k›�¢²,PãhXõG¡øhK=‰¨¡aYwÙÄ­ 5f%z©Ãt@Q`àfòxŽ‘¹CDÀÖ†¥a%+<Õl‚3o–çQÌ$W‡ôŸIõÿ.ú¼Kÿ¦ÃŒ�а½ÿaq„i%…Ð}LWø¦p…îL<¯¿úÝ�ü!116ñü'FnŸ +­¨:E™ñ \8²Y Å=„Íè‰ìŠÁTé !H³Ÿpu/UM(sS[¼“PÜh\þˆMÔ±éÌKµ�ë(R€néP/�ZBÎ(1£X¹hÌÊû~`îl“Œ7¸m@Qw¼Ü2H[zô?È­*?ÂÙZ�òôÔ(ÊDe �À\Zt}$.·SóAȺÅ�X‰_ ˆð. o¼ |þ)a³ ,î%\G ÒÙac å^jT9­� œ_âñj#P¼¥ÅjcŒ*ã#莮Qîõ`�t¯¡Ë°5sæ_¸ú%y˜€Å-XÒBÀòÇÓ¾¶ÂPÎÝGÖ ·ýSxX·¸Û„\~%-âc©RŸà"< •ÕÄB‹Á€B1«�¡KÕ ÕiXeg?aübf˜OâxD©nØ­\?rŒÁdt·D壸™.·-D..‹î'0ÿ”@³è›(éV$\nüÊO¶æc|­.áØbˆ‚* ­u˜ë+0‡°%S·œTn³Œpõ™ºEDe焱й,•Ò9(%‚„³aÇ8Œp)Ž¢Yy„ˆ8EzÄ—yEu2�§ãúà™…QEiaœCe2ƒ¤ÎèBŽÏ¡ôœBšÜÛø†ÿíꛥ@¢ìzüJ+Wÿ2Ÿèf%?âÐ0Ã0ãæs¾åÁž(;¼ËlORO­Eˆ&BÊ1.X‹d —¶ .ì¹yŸuòGr¥öALoÃõµ> CfT90gïÚ@ˆÄ²ÆÏ¢�é)«õÿû:JjÊ%Y¨)©n~œ/éÊÑâ*Ïs˜ /=¸Ãá3 tU×YG�Ú8QÔPÐEëÿÇ–�¡ïzíRÝbÝÂÑj¥�¿­…«ˆiC’££!CÛ($Ñ,;B{kÔæ^á=ÇÄ'Ì^adCß”Ø&βš�’—­+¤¥Kx�!á>æD4\0Lÿ¤%ƒê` ¤F%�FÖvNÔ Š5:Þ`C®Z^´Ñ~_©›•M.2ÅC7s(èÕ¾â[µ ’Ķ¿0â Ó£²,EøgÌ<¸�Rºá\çôKA‚G¬ÀcZþ2C¨y.#9#íô�~aé5ÄÄCPχþ„³S!ÖŒ.4q a¾Ü˜âþDÀbVÌ nÍù•®ÐZÛk¦}å5›¸±V ôbÙ¬—^%� Â#[F3JNñšÔ:nª^îÖeª ˜ÔWOšëöA rÝ”�#+ `çÇÄêØàbbkÛìBóWù§þ”=E~?á¸~aV1—ê‘)<$%ChOQ“ó*þlK±]Ù`²Õ¯Q«‰ÕÀ¡x¿Ô+e—+&Ý]Ugâ|h~x—ª´Ü¢•¥ëÉ-fß‚ ¨b0¬Î´Ž-?=Y™£Ò�Jè0ÀE3X™P_¤÷�O´ª¨ ¶tŽ»ÃÒ–V6!P­ÊðË-MSAÁ©f´UÑHÑ3pRÐ�%C3.P3ïÔ«'ê"ÀöR�]ò�j:…Ç\÷åУJeô>`¡ºFÑzÅ¿ˆ¿ÏÌúƘ(¥5Ô&èÊê/ÛD²&K>àÐJ¼!Â0µ ºèð^²œkäÅ]—¦,<@•GÍø‚ê÷•êÑÙ1: äy,Ûxí‚õ§ñ+(}QðLßÄ\,›¤çî[Ñðþã¶}ƒû€ c„G÷²AE¦�>5¥¥ælN¯ëQЬ®¡œÎÏ‚<%ÌÆ©¦b�]ê|l®¥Ís9Íj2�·p$J¬1N�; Ó*Ôµ¤¾Û€¹�ht®·÷.mm#ÄXBCShæcŒs�D牀Ííû—Þ.ÜÊ„º%³Â˜’�P”'C–.þÉÓø?q=7·îë¸k'T¬fÏ2ßÚ~án�S÷;ÿTˆ% sÞ©V§ ê)ë©âdÝIë1]ŸÃ Ò û¬›9Ÿˆ.¿¿´û~#Ø(û•ÊM(ßÜ)!¿Î{PùI~3 ×造 cö$ ‹Æ({À»®Q¬Kï‘Eáy±š�é¬ðR?ùb¯Mø� '™–¾ ®÷¸µ{î¸VbÝ +z~b{:CÕAY‚”¥ràï)qÿ{ÌÂļF“tµ{¶ëÀËp~?LYƒþúF£€O�qlÇþ%qÉ”úˆXZÔ‚u…±ÒÊ;LªýÓõhýOԢɕŠÕtè åæ…|K‚¯ üJÖÜó€’¬�®©´¹ìbæeG¯í”ÖT`éqj»NWî2Ýí€çª¡pjQÃFíº9ÍÎ+¦ç�ýÌ¡ÑÊËvö•©Fô™ït.ž±äD½³|¡˜ƒ J`ˆië‰$'ßJâeªð.fs4!�®PÛĨ'*A8Ĉ�¼3-ÌÇÈEj ŒéÁ…mØÑ4Òÿ$ �ˆº†”DZ®÷ï,`!�怭ç茶 ’j~bXb�û±{.ŽÑÔEÅÜ “˜jî“á i艑ö¸ïÇúEjÍKKb�ßè‚MÁÍ�E3YG-Z¶ßq¢Y5líNÈ`†\Âß7âåx†¹1Î>‚*- aHçžò‚5öŒ2¡ )~øÄ,TïKÌ{l3RíÑuF*âœ/°x! u‡ªLßh�4{�Áá~%O1IÀcÞ «Ës«”4qR‡�ZAFå�``f«õ?àÿʹôÃþó¡Ø”y”žÓÒz:�ƒÐ¼Ì-¨WÜÅÅ𙳈ÂÇãœÙÈ6¼Ô¹ÉZŠâãVÖ)Cõ÷Ô&ÇxÚ*=¬P3l3î‚­ˆdæ<0Ô Jÿ–½hÀˆ¹qû“§xéíU{C`™¸Ì·‚YwO¢bœêg^ÐS8yý–S9ÍÝ‚’e”ÛêŸëÒVåÉIœÂ¶N=¡tDáêBˆ�¨¾±/¶˜=àÜẮòãp ñ¹D˜mD{/87mδY7'Èbdê‡Ô æ–Tèî‹·~ ¥%ß‚#µ5¬Õðø–Ã�|epa®Ý”#.n/’ Á‚Ðæ¬ÒD…¡/á{KÛ®"3xAVaZö•XƒÁgHy/†¢¢RKЛh3KGXñ@!�Ó*ɾµø‹6ˆVú“î÷ºÊ|-ÊwíeÕšêü%ñ‡X¿x• #±èA@U�ûE&l ï,¹Ž#‘k™�ÄÁZD=ê‡É¶Z½Q ¥¸<1•O§Y™z"“V ¾ÈAZ”qnÿB`‡D ÓR{áŠÊDBR­G†Áàë¶2��¸Ä³Q8†÷ ù¿(‡ ES‚¿0Š ñ.66T4 Ge Ç25‹‚*9‚:J’”Ýé�yîÍÖ˜ƒ›øˆ¬wĺÆÖ!=?Ô°iǬŠ{0ªS[�ËâW<Ç5Ã[MwƒZŒtïíp8;‰¯D¥ ˜Æ#¡]Ø–…}¢ò"戠w5øŠ½™vݸõ#\Ü¢Ù|KÎKÜ…°Àr33§Ö Hî;#ŸÀ„J¤4ÃSUì™ ˆÀºƒ [`µüa ‰pbÙ{Á¨ X.à,ùù€``‹wH(…œNfœ}Ä‘—r¼0ýnKd3.êw¬AæÅáÓÒ?R½ˆF K4ƒó;¿Q¶.D !_ð5…u++F1_ƒèCm¢¢ÇÔ5ì\Úô§Ä²|½£¹qH],°;~©D·[oˆe„›§²¦iwŠ–ea|–6áI|v�Ü€nËÞàî'VB¥¡JÜ( ,'g³WfŠN‰Ê>© k¹Ú Ù´ÉOx6àŸ*�¬`&C. ä¬~PìhqˆšiPÁ¼ÆØZú�ŽR•QLžˆN'b0\írûE[Á©ÄP¹‡¿^‘Ý!¾^èõôM‘ZLàæ‚mjÈöbÆÎÐàWÒ®šëRâ`G6©[¼¹*!*¯|y‚ìÑÅ0X8ï¢Wtæc >Piw à…¦L€8cž0»f-ä`Aºãã¬ßòЖìs8ꢯ¢ZªÕÕ(^,Ë••÷ûƒV±I· AàDÁ!eší0 ×Òùåô#ÎpE6œ÷%Át­#óô ZætH;‰�/è�âwOÜ™«“÷¶[µáüB,%¿ÝbÍûìÀ~Ø);+�65†Ày™‘¶M§6D‰| ,¬ù”c>ÔL=ңܸ®·íÊçüÁ«À.Âø‚‹Žµ-Z Uh¶�w…MnŽœÂ ýt�áp3µôºÊ‹·Pé°ú²ßb 1Oth U“Y¬Àؼ(Y×™ƒ¯f¬‹6ÓÎ<Ìa‘„°Yv„ õ§ó)˜((�n—î•´¾=Ð÷Aÿ¸•‰v�TôF¡ö¬-Vy…E (J£Ò ·Úþâü„J,z)Žˆ7„²WŠF‰Ä°¸¨Ð­L]ñPmÇîR\X¡Ý¢ZÙ3´0ÝcƒgF"jÞ¿HJ‘Z Æ|B(gK?PuM]‡êY“Ç'PVØç‰˜]OT.V8ra:à-©»8†Õ¹)‘,;9•Eº7ß]Ê‘ŒŒ§¾ãâØ‚w‡îNÏtá,w`Ó‚éKˆzÜ«wá�«»2Ì—|Ît)‚ižÔǵ-Þo„hù ZÐH¾ (×´VrÌѱÉn Ç.æŽ#jÙwÃ9%GÍ&„|l½»N0¶úàÝìwEÊTYUKIE(5âcstüEJÍ÷‰³}‰—sYˆ@»¤®„u)ÉZ® ÔÄ­ÓuÌܸŠã´´¬±‹Çà–AÓ´ª›/·1 A]™£ÚdÁ§’0¬xõ t •ep�Ø~ÂÁQˆS¿˜…½Õ.5a{_ø^6©±Äõ V=ˆS R‰|+áë ëÒÆéšž¤¨n5€ ŠÃ,¢.Ý=áÔauÏ#  ”[I“azîg2ÒµÜ÷€C^ JQÄQÉ LËñ¹B9Cù‰P¶Yż°'G‰‰‰[<Ì—e÷‹0Ë@z1Úu™Û?†h W1x¯hŠÄß‚Z›–ztʹíbPA×*1GvZºãmLs”Ø\¤°äó}˜ 9EÄœWåK*MÑ)o¥Ã|йAL-µ…�KpÀÖD!—­îNb;¥cuTÎCÙ™¢Ö.1 •,• ÿFÔÍʃåœíãè„@Äp›?ŒÁEÑ5ׇX6JrEcK™ýG Šu16K†\䦘i×ð”ÄÅ›ˆ]7ˆ)™�õ(d±�"-Ñ%°èn]ÞwƒÉ–×Pv†uW7ÖáBZç?ˆì¼\µ¶7w¨êÄN\,JÎeIK9‚eÔj §œMÉ‚AMJ=<ÅŠ�#߉^�Q¡à–hiyŽUiËÖc`–¡R—˜¢´îû"ŽÄ8]? m:øOr]‡ð™c©ÙЗ‰w›É�½R˸Wæ!>æ”& ¾Ç2Ã[ohyŠPtõzC@3OëˆTƒ\§.Å"å6‡¼­YÔaËüs 2¨¨â¼þ†;ñÂ¥)æSú¶ÅLsaëQ)�a�ý²†.%8 ‰}gÒf\«Ì^#hÔbŒP7¼f9À­æ uÁ-�BÅm3]m,"�Ë8A˜˜-S2�²=c-Ð?3�± ðÔ\Ù“Ú0n�:ì>Õ÷«yxi;1Þ¬¦æªwC}ŽóÄ~‰%.ªï2ýiñD ˆ«³†<¨ÄEÀ¡} &  ³Iy[ÙŠSHØÀH ¯' ÐÝܶ,«˜]\UËÚuþ…ËÚ «2šÌabSÝ7ièJ•ÛÖXƒþ*AÈ>äJ2Ðö(ÆÚx—öq ø¢"B"D@bó R6ÀlX\êma53.ë± hÊ®Ì&…À•*ßoÊ},HÇ$öò{ÌÃþQðA,Ä6/¤ G|}'[­xæ Tt(÷†|‡Ü§BZ`0H×ZrD«�_4)ÿ˜†�¾ðeúÁ¡}=æ´ tˆÊê°c@�u¡)��Œ•š �TQ³0ƒx¸* Ë5+!�ÔhÙT­G¢ƒÒ+щ®�XĪÅr·8™`7Ÿ@y"qG6~HAò3o„<Â1Òt?2«ŽÅ3¼*ÕžX¯º#¤ô›n¡½Êå`ê~¨Ž²ÑNëú…$Zà÷†²‘õs.Ÿ'ð�à;x&r•}ÁWãýN[·Àb"åá=Ø(TõOªÐÿ„6y…Ͽʃï5j6¢¡âå¶ãó2ñ,êWM}eß…ôÍè�Ì €®:°s »½¦s3+IJ*-.ScËu¹`Ñ4˜Tºû°l¥8:Åm.³µßÜ&®!yÛ1Ú Èž±›œÑ$>óO3—ª)ú—#–¨[˜–W)�e_©t”x¢¾´1;™è”b[Ø@g�Tj†b8ƒ®œ¾îPëÜ 3‹« ( ¢À.”ù‚¹GPÓÙÄ F2ËG×42׈UoªÎ-‡�qéé¨.XPޱ:Sæ&Hx-Ÿ$µœAVwÁ,þ¨«èÄÕ�P 5°ÁuÝ€Ô‰‘éqÈy𙢮„ßÑ��Ã)±Ô…ŽM>ÐPú Tľ#[jìèÌJ@-·q pŽŒ#�D !¾Ø|øaþÃu0¡Õ–U•n8ô>å’z ç‰–s”¤tôPM®&"ËîÂ1¶�‹í15X3¥ˆ@Y¨§q um€ã3sk1Bâ›X#�m…À i�YTÀ¯L »,'a îÕž!Q2ué5{CÞYD Œkqá�¨šS¼›ŒV³BîRP9é)W—h6”ߤ'gü0w¼ÈAÿ–Å×”ê2±ŒYPÎæê¬ûJ¤#!ÖjgWYi`ï�Ìðk,¡ù€; Þ�Àúðñ„*óÄ)s\DÐmN6 yâYZf[˜®ÏH>H¦W=£1 u•ô¼Ê?y O¥ žç}ÓåŒî%×`öÏÔ®R´û°ãÅÖ?$ "Ú˜l~â~`ú–9Ü œZ„1¹Ä´1Þ’St¬àº>?À�À#’»Û0c‚Ðîþ#&xpiuŽ�&�`¢Ç-º/á J² ›]àIš\Æm²Öoˆ‚@KCÃÌ4i¹šë¡ P8½ê×dêÖ33æàkÄ W°Šc”L€Ìp\ê¨nÑ*)„ E× ”ÐÜÅ×_iK%/@úÜ"Á_ÎgE952Ì~…éVcâl<Œ¿3¤ì¿qìÌJHRo ­•^òé à(�OêV+4˜B >ˆ´Ï²•ÔȨ Zè”Ðj€3P�G‰7\ƒ™³n6Y,\ÃXƒUe¼KÄ‚‡ëQŒ6Ò­gÜ«gG57ˆ)˜•¨´_.˜‘ Èaë6ý4Æ�à ³ˆ4±I}Ãã2³Îˆo’Bl�ѨèïUŽÊ„©w£¼4UŸLw(✬¹lÉâEêò÷Åæî`ç¹ *¼¢Å1-üÏ챉"ÓŽI´;Î[ù–Ÿ²“СšDS¯¬6šQMí|½‘íò‰\8v:MNQÀ!`Ð¥= åm+²æ™(®(}RÏÑ,)®+‡*ò,'i€n_y<-o¡þÔ¨å)�ï¬gµ%Õ àd¹] y’úBº}©h=àâåÿ­TÀ!KÞ#ÀëïDX”‚CDŽn…ˆ§L±ya°ÁŽ‘Ù`™;?äH ¨¦eI*û,‰Àµ¾¥L�Y/¬Ùq·ëìÁÑöúŽ�[¹DZ_^`O`ðRƒ%Ü` Qø'\¸ã¦¡pc³0K^°ØÍM  #„ý@,ó©_-(¯§¾(@»Åqrè7�-$VAoê(-­{â!cë:#^"Œ  ^„Åà9”@#gH�B•?ÂR¦ÖË‚̱ ò^¥ýÖųωbŽ8¸1•ý¢R‰ÒußîuRÃq#ðë2`!º{Žbgˆ�ë¹qÔÓb†Óñ:Ǻö!�£Âv~HÈÐtq .­:•ˆÈâ ªC-û'¶£¶þ.,Bmy‚XØ>X «{¸�!RªÂüÑ­µ•¿˜Qqã÷æ[Øû—7)�U�AÖ–Z®�ëÿ’’‰ƒÒíËß:$ÑKëÉJQ’íç]"2@nâ©vWĶØÏ=&G$®¢Ãw¨÷¾˜Ä‡¸Â‹®Ö¥_”lcp²†¨Œ‹(zF4 ¥ûšÌ—‘7¾å„Ö¶¨’œWI}%Í‚k}˜Þ%z°Ç˜©_òÈj‚‡T|L¼ó‰˜ó:›”',Ø›¡mg à›Bç%~’à8¤LZ±÷ Á›~? b´Â»*}D®ÜÕÏê%¥ý%±SS[> „¶�)ëÆö Z¬JÜ{¥¸m˜ÿ-€ëKuyFÛ�T¸”x„lÑÄ1`!a r—è™±B>‚§™Eµ‚/5�7ê‹[c“ù„÷(s™‚SkÅD ¹}ÅZE9. {G0ÓÄIá°¿%Ô¦â£�“­ÿs‘üfW‰ã^_ɉYdXH'fò¬½§&¹ÄdíS–°zæU�£+ÑSî.ÃÚ\ö¯T| AÁø>⃠ËR,ó§,{f$BAäOBÉa¦+.ËQx·ÌPkT`:AMK*C�”nò´äyÍË"¡WìTé*‹ÎaZÎRNo¤¡Ì¢ö�AZ,ŽÊ¨é3 Ö&Øc®*Y„4#ˆ+ÒŠ»üX¸TÞ¥Kz°3sÿÀt×ü‰ÔgÄÿœLÐt_s8y³)h ðQ\—¶)pìݜà ´¯³ÏÌ!|GW¡úfäëçå¿¿Fgû<"“4Í?ÕŽH=ÉG„�9‚¼¯£þ* :»T<ÕÁ@ð¤r÷y[tLvœ¨lR%Ñ Þ&¡næb‘ÏæX1ª×V×y~"àŸÔȆ;»Ü4+4°=žó: ()Z`àÇ`éh> 4Xß�æL)1zWÔÎùü‘N(¤©¨6¿b Dz>f-Æ%âU“t{³]µu¯Qà—öæ0ŠZqíXøCPì€Í…H厘f†½d_ÌBŠ­¬DŠ6°„�]oIvõMñ-`µÌ¦Ê ޱ/vÖ^‡Xç »Çù Û†Qí¸9ÈFã/ÌH+1S®Èu#ÕÉ¥‰<‘Ë1fo{ -™]©nºýR°¬Ì[°”ó ,†”D‹éâ×Õ e«•…ô5”¯hÍ7ÕJv,Y¨b£¨U¨ù{1Zˆ´nuªˆd0†$SRôhrµ6aMèÁ¸½l)‰ÃÉuÄ�>á†ÆÀçq˜+ÕY~MŸ±t_K–ÁQ+ÒZp…f!X3,Sƒ˜ ­S—„Ô­¸<mâh4祺æjÕ<ƒÚ(è}¦¢5Ú0ÉuSõƒ!`áˤá¬F¶õ}ÇY—Cy¼T`IH� â-Ú¬Ä(ôŽ™Ÿa±ºÆâÏbÃ^‰þÀ‡>L‡Fa�¶xÀ¤?ÒÌ•OÊ&Z›<P–%÷¬AºÕÁhÑÓ†ï®ß‡çÞ ¤gÌC–¥=ÿŠ”ü‚žÓ¬½JUÌ –$ùs"R& T¢Ê€maÖ¦Ü`1(V¼ƒÒù¶ÇT§ç¥ k hóú„ùXh¿‹„œq%ZiªfϨ !a®µ†pEæí]9‹êeâ¬Q�œÂÎ+£?©žcfÝÓGâ`¥yêTÆ7kc7(@‰s¬Æ�q•È6u˜6�OZˆÑ¦|Ç P¼,Sž‹C†Œrsllðø11 ŒÔIØ´×N!€¢º�ÁíSÚ l&Q [tj»„èv¯øRŸlÀoR‚Ìa ‡{—ŒF±:LÂ"ËGHox eƒ‡H¾ï½£«èƼʅRa‰ýÑFOÑs3Ph¤±Èž Šá{ v=ätž˜[®‘¥ÔY»°ã�Œ“ßS,åÓ÷GÝ]üs"(© õ˜ïá~âÐCã ?4)@[—¡Áã?!®6Âþ¦:îÙ=¦`ÚVŠ‹)ÃëŽ"¦› a’li]�nÌA`ôŠ�ò›ŽõÂ¾Ëø™eîÑüN• ˜Â5M^ªñ½}$hpŒnœA�Õ¼Ä V»ÁèÊý?ÊVÑå‰ÃþÞ%{ ùC5V ÃWsM)Ìõ…ãíÆÂ�u_Ï0Dh‡òÄ?Óî6ü<Àµ·VInÓ̤k€ýÃJ0P³ÊÄ],ªÂÈFÚa– ®’—ó`àfWlb-LKWÇ̸><£ªà¬ÊpS/Ø@_´¶Ïx„ŠERò̇ôâËÃdjÛîæB{ÆP³h>ȼjãE÷�Ь>ìÆƒqÏøB+å…3Ê WwâhçöLz?t!jk¥ûˆàÙ·ìƒ_týÏW c\ó*çø§æ`ŧ™›iÙPvÓAÒWþd¶Žƒ_¨­,NZn" Y޾" ª?ù—µúƒß[:�¥G.A•ü¨î,Y“õPfºýLuÔAÕôÄäTõ>4’ÿáÀ2rjf+¿ƒõ.ç &ípž�|G}ÍÛ¼8sÞR‘µ­Àã0ßúR† שhníúލ Ðà™›¾o§Š¨=ÕÁÛë Š«yÂB/(oxˆ(7­Ÿ©bþ'ê\g?)Çg7Ü%jÕ ÜsÀ·5Ò[ ^ãaýazmíâH7\÷”ÅRåÎψlæ6ô²hULËëÙ�ÌUÕC×ê87Áo‘éŽ(ÛÙ†pX<õŒ¯X «X Šé(ñ ¹÷€:±o> N« {N¼ÿ<Å÷sŸÛ3|ƒw¬¥WQù„tícÿIHó¨E´Ö÷Jê]©k(UíÎ9ƒÏm†16éN¾ž"“„xŒÅ¨*uÀé “ úaâÙk¯hrEUÒ\ ¥e¶R­1Õ€Øæ¡áÌ=U3Ö7fÕUnW{æ\Í„éè„DK1̱|"åÒ�8b_knS˜Zç¾8‚IA^§ì� ªÖenÐ@­ÁèÌØƒ(5ùOðP¾"”b b +ºjŠ€9Xº^í ^ò㕬Í4£Ž»+pC9·Ö.«¥\�Ò`¦ÈÚ05¯´Eií+z{N�·å}R"ž±ò¡Q¼g$½Áõ‚ëÈ6¯éféveÜO+¬.;ð)ë†H& U —O“;¹?ˆêT kuv¤�kÿ&ÊÊYÒc ©NkÔæ0…KÚ©„‡Ÿ˜m |\´;¢�—-µë×’Õ²åU}ã”a0Šð®£ASÃIÄ`Q(1Ú5“.†5À×�V¤kŒTtbÄËÇ•ÿÛïš`ÇOZŸ õ‚Tl ?+­BË·ù¦‡¢àËÌ·aDGÚ|_çþúklÃÞЊôe¹Q‚ÿppa4Êz¦//‰ÒV}ßòs¢é¿ƒ,¨ø–-ZÀê³ÀSÊ� (3QšîQ(ÔéûŽ-¹\¬ë9ú%nâÜpEàí*So‰ƒÈ×U{ ï÷‘uâkÅGŸò»„: QõqIêÑŽÏØ;gâ …AÏ€€µŒÊlᗤźé˜å9GÂ/íÐ�ØÑ2>�ê CÙ�ÔªkRëp÷„-Ëé ŽqNh2€�_–e9±¸ä”:¼V,Ëw=QË6KÏ1¢ÝÃ/–÷¨@8ò5�‰–: €«;_Û² Õe X=ùoêe,¤rCf£mþq( ‡ŒÊca>è˜0·xOÔN Â|ħGHm‘5žeóŠ!ŒléCb·:'îgæÖ!w+9Ñ}¢¨sVA™].›69¸ €n”pÅN­BQoÖ"œ#‡ü"QÑù²ë¿.aÌ2ôÃ’²†¹eô‹u)ÆwK½XüÃâes9xeHeÌQÀ÷èÊâS=&!jD|0`œD¤n‘Øîû”ó`B”½§%ráØÀh-a³x• ¸âæ%5x™´‚Ò ¾Ì»FŒÄUUn¸%ÀYCz–±5X.:Î#Š©²‹kg˜ÀÖs5­vgÖdŸ-À;Dª_7ù‡0ð*¿a^!‚ÌtzþoørÁ³áW Á‹$^Ûê Ü �?«�Ä'“%UI¿‡íÿ�R¬IÄ#ÈŽâ6Gõ=)Ô™y�'Åíõ*Á‰(…bþ¢¥Šëkùÿ˜ÚÊÞY¯Ä äHe)}cdr»+@ÕÂâÕkgÊãW{•)�¯Ñÿ;ü]{Ê'&çÍKÊáq /#dÂp¡tä‚dm^ÐÑ”ÔZéÚ'_¢›®²¢„ `¸¾?-lK>bZÓ‘�LoØÜu¦ÀD¦²yÿÄð"ü‘bxA.þà‚PŽTQù(o™…œý80VæhÎY”´á•—T€/EñÀ+�Kaäæ%oA¹d ®Ó˜TdêÎ{ÍU%øÛõ€D,�Ðqþʼn^ÓÃ,‰»}Gj4Ý®ÓIT†9ÿÈBûR>ƒÐš‰Yt9…î’ Œè[ðưZ®§$ÄxöDÖ´�̘„¸Å#p;¢†³iý µ2Á"Îý¢CXÝÔY9r„9„…ù]×À•j˳0®¢œãÌÎ,|ç¢vP¤4ûbwS¦áj±{¤ªã´§6˜aˆ¨{ fd¯KòŽã4„q˜6 "ö€Ñ¾žˆ¹KŠGT@÷J?°Geø–䄪ËN"/qc1j HA — ŠUÿ�ÏÎYj¾å†ao&UmZi8ŒLp´:Çqw«ÕÔâ@ØüÀ4Ðôx˜5ЃÛU3…§\A§�m¼Þÿ0G=ejëÒ àTµ.Ñ–ÏWr±páwq³�¬6Uô�]L@H½¦AÆ}£Eµ|ñ�UÖf JÚËÉ"™wú‹7h0›TÃ6І¿á#½ó .¤SW1FEb/çÕ—˜l�"á’Ät˜ÃE�‚±»’›õ…’E÷„�Dòpþ"«º,?Q ³+˜B; ô‹Œ°µß¤Ü«±æ“5W+{+̪ ùß!p�Á0-O†(Ó ƒ,Äq©éPm%n; W@”ˆ&:Ý£yU“îV®ëЄ€9x—é!zWóƒ˜=%H2æN¨lKÕÒž�û‰a½(3T7ž%Ç‚Ý[TUÄSù~`·Vϳ6¯˜*P÷I¥Íz²òôŠj°ßÄ Å–OM&d^³¿b“$UU“B¼ÝÂÔÆ  ÊðÝj$ÇÕé‹6÷eíL^÷–a¹-w…å=2ê›Ú}�YuË'=æÐnÌË€ÞcD�+f ìzÂ)lµAC6×D*ŸHB±9�Ý)¡Lwc¢¨®ÄËÑŠDð¿÷�• å¹`áƒv¿¿0‰7ZyFµå–\mj«½Ëo¨¥ !âÒlµ”çØ�]^vKã ×HÖXeàܔîãÁŸ(LR~L±$lŸ1ïCeÙuØ}`Ù 2ƒÌ�ñ–€‡†òÑÃKøˆ–�v‚ý¨ª•?�•„¦â ;¦+0{“‚ªF;‰€œââ.¹sé6b¿2ªåí%.žb�Lžö0^"u@Ï˜Ú Ôê‘â‹Ít•p`Ë7 ‹Š)ƒ§¬«‘XwÎ@ CÀŸ�7Eƒ=ƲÿÄÂë%Ÿ#C};= ØüÍ7¶ýË!*‚ìææâ{´:WõÖ ù�mPµÆ!p4F¦÷Ñcâ ãßñî•aޝø‡ñÿY“þv�ª¿S#6Û—O®þÖýK'¾>¥’ðîþ¥–ÈJsœ³Ëå,;ùKŒmµ¾Ñ2îÛø–™´Tôdvºµ(P|á݈<=˜e§³uIOQ˜õ«•…A»6çâ#¯}úŒ7î?©A´«Lx÷_ÔÿÙcÓ=Y\!ËÑ p|§Qí`ÿµû…šKΨ¡ç¹0+ri¹`|¿²72ƒúæSW¤eq̨?‚ë,èv‚‡Ó-?p¯rÉÑx§¹.È(ºóC%ñ7Ödô†Åâx»Ûù•.RÞeÎ3¬À*ÎF²_—Ù„ «†b± ¿åÊ…±£íH*Ò•ôHj&iÁuˆŸJ"ͺ ^ßúFÇž�hêÎJØÕþ&Ë5ÝH­«Í\§XGEÖé#S%‹Cñ6 cÒ4×Ê­yŠ( Vˆj­ 'ÒÍp¿(°eoÜ,ºg¶3P9£1UI.Ù–,[7ˆ¤ßÜ©ÂÁ÷,Z”¬ØÌyXzc@ã*sï)tàj›÷�ÛÂËRPôÿ¸ 9·ñ ÎÒw…ýâQUêñ=hL¾#" R§¦H´Œ0-sÓA~+âQÊ8G�@ûÁþ&9i¥úLÒƒ¯ê+µ{CS ¿ÐC²xÄ·ŒÐ¦<-‹,.~`sR½ÙccŽñnGg¥^¥é ¦L°ÅÈc4_–dµ?®±²b6nù†‡ñw…™_*dèJs3{G”ðÂÄ¡êÇ#z2æ;Fãüj5‚ àŠ«òÏýè ÍrŠë0£ò¦kžì`Á×D�4Rò(_GºSbÛó,ré¾’Ç2Âï‚¥ëoPóÐ:ö¥d�XÄh®·e\_¸E™¹ä–PmYÉGübL™É?£»ÿÁ{¬X ÉìA•È.Ži­ª„:®MF…¦ŒG`A«OˆÞ”¼Â<%”;òË€ZååùˆÈSú  •¸ÔU�÷â0ª7×r‰pƒ4€Wü# ¼ÿ©ž�¦²Ÿ ø e‹µCþ�Þ¥¨pß舖¬¬u�ÐÈê£q�Ö«Ï5ñ7Þ_ˆã<¹{¾#hSY„7"ÌÜÏ8IE]¿©Bçz”Ðy¡Á˜Ro¬K (^`©‚Ü»(›�û¿©Ìa æìBv Å !Ð.R¼ò4ÎαR€Ç1]‡Ò_‡Ç+WÞg0hòÿÀú>¸„Ä=/ˆ¥,ó/$©qº˜”,Na•›/SŒM.òþŸæ.b__Á/5í2:f …ЇÁrÎkq¼ËAQÙ†v±2‘QíJ:U®Ôtz²¸èoæ¬l‰|Ëv‚­ªïİJåi£O®}àk´âT Ã?ý'‰O‰‡æòÊ šéæ‡0R®%VÈ™«åû† Ìh×Àƈ.ü“pè áÃó^ñãÞÌKDÍêaBÚæVf›Ywb-€Hj ÏDÄÒVïqàéÀ¥K�Ik]X_8�6†jf|ˆ"�b€f ujŽLT9éËâ< ,–$ϺPäÁÍÎ §@¹Ñˆ!¸ #v>TcÚˆê˜ö?kÔÜŠßñ–\¸™°=B)œýCóÿ �£¬ ºÛÕ†áÿ4òüK‘¬>™²8¬A!ç_¼ÈºŸpê&¥b¦¼Y‚:ÃÚ ñÆ §náÉè_/øV‚êZ¶‹`KÛðì• š‚±ÛÂ>­bõ—gý>fu¼1¶$¶ 5˜A[%.<þõû†×ú¨qr¯U¤j£ÀìP …‚Ï2’ MÇ*Æ�¦é‘j=`b΢v©ˆù}ÌçV¯Üú‘–ÙÈ:—OÜl4Þ«g ³3d ÷Rˆ¤ÜD ´ûÁEbÕO>%¸ÔF[_0` ·ÚYBÝÑÂ¥ÅC_@�ÀÀC.¥„PæêÆXí0‹Çå–‹›j>°éÉy~Ñr2ÍôfÝe^ ¾…ÅÀç&kRÃr¢¨¾HÕ¦€Â\�X²²F*?ð#¾<Ú‡Ô8•7ãÚ7„82Qxô JÑK²|ÀJ Dµô!‹$¨ éž|A)!ßXÒÍóQAy�%ñVìù—OÄ5Ÿé„…ïü°ô´úf|"1œJÁˆ-y~åD†Z…fÉëM%|,÷¿Ú†ŠZaé ¾²Ÿ�â‚§Ì0V–*��1. ÑÚËé(ÃÒ3%Xƪ>L ßĶ8ÌBk›Ìâ¬\ÜÎHÌUójM€.ùbPS.V½áYÞAð.c Hæt‚¡‚í5ZëA2×¹�¾ù"Â0TÛÒ;𾡠„}�ÜÿÆ%”ÀÌ€Iëÿ®‰XƒÚœÂþ�˜Ë, þ_a í$Ê8à‘ØZÌZ Raâ"jeÿ„íºT¬³ÚS™|ý>‘`¢êAˆƒxßX–øg̲|•Psñ~œ\Åw¹]:“Cöüääë‚&&&a¢¢ÃÙKX Š:“+0N•OÌÀ BËŽ±0P†ä(µñ3Ì…Ü‚²aÞp@5·î1ѳ34dÇ–äëýÖ$(`é€ ôN=àÚÓg»)PÀ/ÿ°YuÄ£‰X™Ñ¬Ç)¦ «A–Ù¶ÈV£“ûÌ6¯h—æoè<(ª'æ)¯fßQ…3 áya4>Û.áE`�RlŠíqø]‡S’_ræ8yŒÕªMëæYÁv…�$Xòf&Ï6nV‚�Öα|”%gßX£ÆB2"T¦pU �Ýy–D\b=A²Ï‰BCBßsOu§xQP@ :˜â ÊškóAµCxZ*¡\¿h€HõŽ?™rÞ £|L0âd×Wî$IÌ0�òW0g ¼wc0…]`ÌϨû•1'Ĉ @_¹TŠï¶&£gx7¼w”�±{¹C‚]]Nº~g.‚š‹BX#Íæµn[„šK+©Z´UÍâQ—‹ºš8 ´`¬µÝøB<]8ˆ  ”î<ºD…&̼ €¶ý …ÓÕú—i¼7âP`^¿ò€ÓEêßêX@E2æ‘ýt�h[üq-gù;Aƒ¶úž'þãõßñv�ößPÛ™˜¿ó…­�¡´ÜoCaTÊz|“=>I‡ú#hËÿèWp•yö5+Õd¡NiÉ ´~º»ï€,©ºKå „i’ĸ?‘ 5ø…›rÅ·ù�9Ø•.½ìÁ�^N‘kæf| ýPɲÚ?Ž"[K u×Ä<��ñM×SªsÄ ž$ÄÌWCLf!¿L‡øˆW3ÞŸ2êIeŒÓxÏyYÙ¡]e-þ?ÔE95Ugæjú ˜¦ bÎ{El¼þÈb#üu˜‡Úþã‚aZU‚ûE5ìr¸, 8ë…Qt:AÚíDñà²óE—iœöa8�¶õÇÌ­9ħ¥äÏq/baTŠó|!ÏeLû@Ên»‘x¹z «{÷�ý‘Ó¼J<…ÙÒ «H†T&…yÌÁ]Üxç˜TO(вxaƨ^pjù–XÚ»êÊmKè ­Œ^R¼ ?(üÄBAB•1,¡b|Æ&á°v;ŸnÑüÆÂI@íZN1«o êaŠØóþ±ø|ÿ9…©˜P³ÄkØîOÄÃ�†:XÀ%/¡{º—OcFýˆ¤±T†×¡ mõS¢+ KV¡PSnç8nÅ~SÝ}sM¡CQh¾ æ}̹‰]U/‰«­ó„AWa· ˜þ>&KõÏõ0,}_¨Xhòý@®…¶�Äb2x¿êYM(­-º#å¿R²ï iõô_¨Âÿ�ÚX×ñé $ט-¼Î ÷—è÷ƒÓ8s2¹ž,5ß´ZÓÏ (g¼Ì�Ϊ-ð×Ë÷9'±�Ýó'ó•©J:(U_#Õî8j°í—-KH·™—Dt£K‹˜¡—wîT@P .ŽŒŒA‹*Òï­ßĦŠº~¥J´ÝCƒ�…œwXmT�éµàÄvÒ2¡„Ä**G¬5€=RîUÍŸÀ̯è@Ì!”J°‹5 Ãq‰ 3Ú%bÆ¿OÇüB^¡¨Q]úOàìÌ{‹Òì‹i©êù -ÈüD»†ñ’ààåÜ%U²{*—-]QÛ8–¹qäâ}cKbâSé~¤¡:»Ô•¶‹/“óŽH*é·]°Ôºª7W»Š*ö%>îþÂÂ&&3Ú ò}’†Uô…_^YÀ½ u„C R{4´KÇ�ÌÉ6ò2ÕBˆÝLzGìÂq6Ž3Öt>ðÌhynŒä™&žæ#1·µs‰IQä hã™b°þ¡b‚Ý •r¨ùRUZ'´žýͰÕëy‰(¹ª×ܪ ð^á%1mšÙÿb–½"Ow(« zܦáU4õ�ñvŽ&X}ú̼²€¥@™&.\‚â¬_$µXh0ºJ;#oÄpx£â ³¤b Ñß1ß`¤K CYa±ä}1@¹oüY–¨è|̲›†S‰ß£1•(2´A’›÷*Wü ðþ°Ãƒ�2ÀÒi¬:f‚Ðf9¢^¨k˜îcyet¸jêõ|²Å¥½ WY�ÕcÄÁ(ž)Çü©z¿‰ÌMÿ`hFR¡xR )î ƒ ö&8š�YñΈ¡5K·ï˜„«XIŽÈBÜý¿ó‰hrGCßþ“Oæ8ÔXh¿/â9Ñ;—ó £–|¡°w”‹c,§dáÄêl�•ßQ¡Ãƒ×¬æc•ÌYO™`LÞúÁYxKOÁ.ÂsïÖ}3_™‘ö|æD1ÄÆ¶Ëw|a_1»æˆòv0§l檖H¤턨\'°ÐqÖ5"ª«õe\ôŒT*Ñ-b¥Ky¢ú¥ú•¶P&`ç%Q�üÆ(gw£9T¦§ 9¨•ã/Þ‚¢”ÝZµßÚUAXD±14Ó7Õ€ôĦTyw'¤6©]w#ó¨ÙW§éj{½Äk7âm%t#œ_�Ò¾jaê¬;ˆ¶À†šc¤=e[aO†ë*1P½¿²gøAð‡ÏdD)=$©”tS´LÔV¯’XI×^XU÷Ý@€ôŽ*î�-ÿвYµæÎÈ„®¥K°-KÀ+K|Ù�éLJ¡ÝÄ@A@©z¿Ia ÆŽS¶Z¦%Eý)˜9§6Ìu/¦/" †úKjn§ÊAˆ“˜ýŸÂ\‡˜ì�ìÍjɈFXa®ðW‚YNÙkº:‰eCBS´¦œó2ä`ŠÞñ8H®ÇWïþ`1x}Å`ÿÊ×üfq8³w™ À¬ <☗¬6ïÒø®88ë2E£ã£Q`"æ)âcq)±¼˜!ÑH´9` ,¦œ@¬‚¦aÙžð $£lP5ï V”îõˆqý]âØ25ïï2l|ä±n�܉ºÔ7)DÀ$Qí+˜…™FÛi‰ 3 ÌÔ9ª E] ˜�p@÷õ˜_-SÜ1áLj «äÊèÄ28 3ï+i·Ìuíép²³y”RÑÖãa«ê¢TàõŒÝkr»uQ̧S]8}"â»�@êº1XRžl™K}Є‚¹K ™4CY0]¦“yÄZÃcR]‹Óø¸0 â¿n“Ö ×¾Î˜�ã+½ç2 ¨A)¦œÌ”0÷æ ]Úa;ûÍ wt‡=çxv}Æòý’?Ú¸!–P)Þ[uà]Q{æVmÅÖàpo^½Š"ÁÀºÈÌã84x¼=aCéVPRôÁu¾ˆ¼Ã%·£Ù?c0 GdU)ʧ@À*4RE蚥Ή˜*¬øCœúÒ.IÙ ¿ SÊôxÕ©®‘›¤²¡�„˜³¨Ô¨q™n¯¼î>ñ+ÍÕ}à-“Í‘VÄI¾ª.ÊÐâõC.Õ¨"Œà¨s]!Ñ{@Ž"•ë(£!ЉX¯t"»áux@@.V¼&ACÂPà/€AÓê5 Ÿ�7ƒí‚´TÐb(ÞÉ]õ¦nOhðˆˆ05Í¿¡pÚ.ô�äôFK^QS„X↉ãü?RìƒÖŸ¨’TD4ì_´Ì0½�Áx{ ŠÖêc†ðH˜Tѧ ý±àº Q¹2ØÄ´ÚKˆu˃„/v0�¨Lyu–” O‰]tÄS©® <ˆlÔ5€>ÈŠJŒê °E\sŒÕ~æ\ȯÓ.0¦RÝD{u+Çhmþ¶.ô–’/*éº!Ô®²RŸ�‡g™wjÂÝfR,ØíÌe†ZaêF‰ kψ«ÞJ¶0pЯÚSí pW΄¿?ø@¢Q8íâ°Fha±²Y¿Á=".1x— ÈT5žã(º+¢¾Í|G¢Ê#è‘(ÜÀÊVü‘J-—gÔÆá}bò ©^BPÜ·—«öÀõÍ‚¼ðFÏ_úDûCš p¼øŒ9n1Q›d×£†<â7\�HeÔ C ýÀM= …)—‘kÖY׬²H%® Œ`Pt€™UÂe¨×Irè¾°¬¢ê�<ÍæŸò Ч ¡Àì„FœçŠPÈ4„vÛdå1è·…ÜP¾ÊÊB“ˆ7¶WXÚ¨tùMÃd[WœC„  D«ü‘• ÿBlt˜õÃåWW,„X¾!Ã5ÂA«~à Õþ®†âŽñ¥WÔ5 sg‹~ 9�PârßhGð }å[g:€àÈGq†qÌÃÐû#íÔ`€çµSìÊ¡oqï2Õb¯Êž8˜ �uÀQUbTABïPYŠ:_„ÒZ¢\¬u›0dý°LBpG ¬ÀËYÔr˜[ 8À_’,àêÙƒ!€*^w¤[YuΦ ÁÉ#–g¬Ì®’9€Ë‡DV~~ãþ2• íý¥õq;%«%Ö§eQöq.õ<Ø?1—ÐῘ¦£é‰pkœEix1zÅ®Ó5 Uáa‘vÊþ™€Z:çPX¯aÆ ¿C_HÖ{byàŠÔrÆr˜µ†Þ –S…¦ !‚»˜ÞÕŽ*Z�€ÈæíþÔF QMnþYx 5\ç0 ð}j]`ÀXÖà\iø�ˆ*hÏá”f´\9˜ùZKk¥îTXkéŠÕ'Ô¨�˜ ŒgŠÐõŠ�êø�WC÷¯ö Έ%abý`Ø'1Е*¨‹ÍØë3¡ØMÙUÑ ÷ÓL@Sޤ!—GÞŒJBY 22¾u_j²ô‹pæ†×£¨j»ÖƒðJÇx Y,ž. ¿t~è~ Ä3èõ�Ys‚cIÕ0òŒÙ¶—S‰ŒrÀ©´iÀ:&š15‚ãSñ³ìEA‚§ÅG5öŽÎÐj°ñN¦¨Ü1V#á%ˆ=e!¿xÇyט¸¾ d^N|Ëá‚YdEªz¨�•ï7>ÇîÁ9÷Ë-¸‚Ùfûù˜2û*{"ââç+†Á¾ô°¯R÷ŽféÅT fîB]W~Ðf]P!.t\‘ï©ÿfÿàú¶cÒ`ÉÒ:|ij—$¥ÁÎ^?30¤@tˆ,[ÛªúÛù™‡VTÎ ¹�•þ]§‰z„·bþ„Ù™’ ë`½néù�Ò’aW9®e·sµÊ*_ST®7‰W�(�•ccr¤·Uû¿p­¼�¸—XÛ"îN&`ËRÕã�üÃèsŒ}ÃâÖ¯Idp0!f1v®:ËŠµw¸�±fã5J%<\†4ßY„Rp=`F‰¦Hi‹ëWþP&ä+.¼w…Á²Ä®°µ‘NÜÇr™Y¹4ÄpxWî"”ÎÃ’! ÏgˆLå¡ RÏÎP|µ:žý+õ+¸}% VhòÃAÀEýÂ/(Fç,î?Ü‚—¿Ú ¹oï e„¥[W–µ6Öå«.À/˜ÙUy=À){¼Dp†áR®åÆ«Š–å,•´P$kX*kª3>¸ öJ”œK. &àgR§ÇôÁ£l̃nX-æS<°ÀÀ:@!mq+}£ö¯ÜÆw:£–«8$?HÎKö„{9ˆzÓLƘŠ?ðG;à�—óQ_„†À#Ö1ˆ aP$B¶UÓÄ.ý~f. ¬[²å…6è‚¢Û«˜vê"IFcàvÔ Æá /Z"V.ª·Þ oês:A‹Ü}‘iíù?PÒ*¤l¦ÑVë,+5ò“�ü80ï �8²ÿÀK�õ˜·Oèñøî Mð–ÙÈ8`3A@MO� 0ñ˜ŠµÞ«ÄDáezS_ˆ4&ÉS“_ÂR�Øj ¦`Aî|Ü.õÚ‹ò¥Åi¬¼K…Õó]\W˜nîOÌà!MbËv0ü£68¦&Öî:ˈ4§=È�mï�¬NI™nmb÷‚,Ì‚X¿à÷”In3¢XäU£í òõU£Ú‚qº©r‹P ˜«N0n�½!]ÈŸ#üLˆœ…ÓtwbÅ•—Uun"é(È,ˆJOP,ç:2D¸´âU8"ÇÀ®fªS 2·(/ËVâ¯/=e GR^&H×ÑÈ5ï —`DéÒ+ÉM¼¯ê!±E®ˆÔáα,ÿª%¯O¶Tìø…c´EÇI^&rFNû½Ñ¡‘Ð+f«PVÇAm;¸ ް¶ ¼l½£UOˆ¶v ¤�;0ØX³É‰CH�q—L@”gÒÌTª"¥ë³+¼„¥kò0ÄÌÖ¹ÜZehýAßæcêk#1�Ž#:ç(Há·Â+%{DT)�aå¢d€ÃÚ*ÄrAÞ^Ó±_¸vcpPê�zA-GX™ÛŒF˜¬qiÀÞ  «,Ó¬®qׯæL¦ñ‚â Uê.rû•S ïúŠóñ.‰~Å¿óLÐîú†D%Ê8%yb)¢ÐŽ�¸˜ {@zðÊ›EÒ ¸½‡Òàe¬Å�{¿ða©^å¿PcD:ÅÌ£Á@ÿ�5=!¢X%£y¨¤È@õ2flË…PF’Uˆ|?müðùYzöbevB+Åy�,Ñ®¥%aîÂ�=ç@ù–2ÿ„—r… få�H©©þh�°øƒƒ0‰lœu�WOµ,}Ù~!¬Á` y´ JY€»*—LpŠr¸†J𩙬þìñ ˰ˆÆë”À4Zº%G ôBE‰sÖQ+‹ÞV(‹YŠR‚9½ªPžàÞi V¥ÈB‹±hû?0í«OÌ=:Q·¬ºÕµ@»\‚×�ó¸ý1bŸÊ<Å £—¸NÌ*µÊ]_˜Ãl)˜Ô ª8p€R–:Ë{äL$€` þï+T±n*­Å[Ÿ…ù~�E¯íKÛk‘¹Ôû¡Mû¿³•Ž´(Yk˜‹kWYÒ¡É×iÀñ ¸d߬wK’¤�–Ss¶vˆi¯XËI`[ÀYpsô lÖcj5Ú¶ôq0{—šÔ<š€ ,KÁÒãiPpñúc�¤qÃRØZ±€•šµÏ6Ü Â ¸±¡+bñ©`k Ô9w¼¶ÄbemÄTa™<'3hSLf‰BPƒáþÉ ZÅ–F¨/d­±ÀæZ©¸lT)8¹gŽ%ÅbÝ6×̺1ÖRÔ|@2b±®b^¢ ””ܬöˆÚ®½¥,Ó^wÐêÌÌú¶ú”r4¿øƒ=cðœÄÚ“•R­<ä?˜®ùgü£˜ÝHlôƒÁY³ê$Û�@¥ÙýËøO[{ܲW9¿õÉüë ›~†< QËD°ß†8ŸøˆKYÐ*‡£–Ø·‰@®ªòûŸÒýÌX³ùÖÙ€.<ÂÇGœ$£@¶µ¾Æ*ºj«Mùœ4u× ˜±ï¹R×pkˆÑÿsº@Yùü…ËÒîQ$iL>ž¬§Vwc´óD»k³R·ç)Ìû©¹¨úîYV�¯®ê )FDW÷êŽòÏÌoõû˜*ÐwÜÔ{Q؈GÏóæ®°](¿õ3Íz©}HxU´÷\ –Ž;KF oPfc?µ�UusÒY?Ü Ìz¯Ü0ú Eû”qÌæà'°ð©Þš™ ºCI´vÕŽPͯĪþ’”Öº¡¨›k¤µMQòåžÒî®ÔuÓé+\ÔGy/÷!²±”nV•x˜&0[Ïúš;T6©}±+¤†ÀÈÍïùÒF µaL~3j¤V>©ÓéãT9y°£ºb[ó¥]x‡ò�cQ{Ľ�–eTã�3 ŒÉ!ð–ÛîO0r–­0ѧY„|5e-·Üp¬º^–‡ ‘‘À©Àá@¶ÑΡØc²"•wwF}Uu³‹ ¢ºmÁ{Þ /ðÑjãÖ†/*¶÷üC®¢kL¤)rÞÎ EvRz-Žäf@À*fµ½¶iÆ4ÇS/”mô¶G.�9)R/7)0ÅZÈ`RµH+׺o� ¶ãJZh{Äù½¡QrÜ»P]{È¿ˆè�„uU�à¨L†•XN©¹zÖ=YN4ך…f·µâ£”…†RÖÂðß2Õtœ�½.4rêPzÊ“4ÞºÔIÁnXY�жÜj:‰@¥ÕŽzE Åæ6B¶n4råÔEÓ‡2çÉJ² kF¥×¨‡æbVªQeqо““‡d÷Ë Ó×{±è*µ^%Z·Ú`©ÄµßRyG Å�ŸÕÍ/â�-í ptæŸl!.n_ô`æÎ3_õ’b¿åÅMß4A§Ì_”– XYBËÃé3:�Âq))|.€§A4WÕ6A䈜N𗞉.\¸8k¤·ü\ùÓiråħñ‚;Š;”ðb4¯vÅ9‚ªYFm˜Ì ¡D×X*“»`&:ìdìmÂ<‚–\tĹKеd6›¡üÀZ„f¥§&T­KlW«õ1Fô‡ÅJî°/{‰²hW¤ €žeAlÀ­°p”VõV1ŠìlÎOüˆŽ¹;�1GvÔmñ�8l­{°j63ô%ùW$]C¤p{`÷ ô†•W %¹=6¤?ÁË7TË8ué™Ã±b‚³ ˆšJÐÔ°¼YÆÑ›¥+¬µ©t.`›•b†iÇ2„?R¥õU|@— u+9Žmþ)XL"Ÿø%Ï‘™Wª²Kä?`õ%æµ&×’’ s,»-»­n`,«×|±ð è€Ø[› Ävæ>šõ”Q{ÂDÅ ´±öd‹c’^PðÄ8±R7øAÊãd’± Ù%ÖnÌǪÍO ˆ.ÌæðBŒ‚R¹�P§ˆ¶Ó˨Ú…eÚrôíNòàÑÌu‹ÁùÏÄb(5sîþ ·`ÛŠ’€¨3wý¿æKÄ!Nƒ^Ñ‚Ö:ÊUꟘ¦Fí.ÝÄQÕCþ .mñÿ #EÛÿ—/¤ÃÀúa¿ùp-—ÿ7|Ñâ 06–MÈipŽ5à—K/ /»�•ªQK§D¸v�î!ÁI×3«ªB²?@2•Šº†0².–®U–º�Œ ŠÄÿÆ€(1øR”H¯°eúˆ‹îË^Â07Ù–“^•—¥Bý¤#¯æ$kÕ°{êXRëõ‰±’F:±í’*b5|ÇT¨M*ê§â;�F¤§]ñ�{SúƒPShœ£époòY±u dÚù�ÅÁFL|R$…t<ÄbµÑ¸f _&Ú*r2ºfPüuŠ•Dm¬#GW-6f[‡´¬ÆjÂ-fõ¿s C•Ë/ħ��8̼£m¡Ç'Ó÷/àx¸±î4ð¦ f\D_)e'™úê[ aL ^`±™’ëöJTy9azqNÏß‚*{»B„̽n TÄÔÈŒBÎÄG$SÝEDìbYM л]óxE`©_5¹KºÌ< ÅDÿˆa³ÂÂ-­Âœ�áÄ2úá7Þ‰’‰g9ïUiÌ:ß英6÷–Ñ¡Ðû™|Çhõ¶_¥±±9% tœC 4�Ü[Œ0\Gp¸!‘i3PÑzæI¢TK[=¢¢­s†«˜¦ŒE¸â^%(—€j8ò{îZ¤¸“1<¼�šQ Ì[EÑÌvÞxˆ]Ýñ±YíFöß±.‚ê¥Ç\sË¥¹k7JY¿íMZêø—¾üþ®è«eHâ˜Âmv獵ÁœÆ°Àç?ö�¤¿Ékãô@ûtÿQÊ[4QM;NDö2 ¹ ‰\ª´´Õê�÷ïcÀùÆr‘ÂÎj"µ�_ñoœ û?©“ªU7>Ñ]Îà´�ÚŒ"0ªõÛõxÏ'´O �äí /Ÿêë ä÷ÑNQCI¬xŒ¢ª2ÿˆç§õ~¦ÿ_ï�¿Ì2¤Rü¼JÈ“ÿ‰bh9Æ Ð#0Nòå˜ œÞb�tÎ\\°x¼Ê’x"\�¾DK¿1Ëæ1Ö Œe¦wëÿ¨YÌôL|ÎO¤¸‹F« ùŸøÐ½zßÍËÉø`ú+™šÝËbÊ=àê2Œ ò’ã·; ]�ë7_¼p:¶‚e¥½Äóž(~å¥ïµ\ YÍSî.DnuÕBâ`7A”:8]?û‹A0e+Ÿ˜ˆ&´¸šïs¯Ì¨*N~eÍ Ý üÃÍÕæå°¥S^a׉A!ØàÇ]Fª!åé1àJ¦0÷0F�`„¦¿2eý¹“q1‘ý¡ŽôýÅô©x1Í)8é2WxÕüO(2õèÂ×»Ec,¡x¿Ç^fh©»nïß¡`§¸~%#@•ÜÛU,è—Ãú¢@Û”/|ba¤øŽŽ2RNì•*j£O]C˜*exé’®Ž%ˆ[-ÿ1“(T§a)Š7ÒÇñ7œFÚ%A—'f\i_ÏÁu»1úb­»ÇùF}f ¯!àh?ºŒÖ?ïQÔeR4ñÄ(ÈÿW¢”á|ÊÈ•pS Hˆ•s÷™ñg˜›âÞfm-ÑpÔJxýÐ*Ë�¢»~Èh˜_Ù*J=¹B?›¼¥RzBëC5YãPÝ$F+â%ˆiBÈLêû�Ç |L²ÄËLjg2ø‚¦‹ü\æ\ÇÇìeÊ$VU®R�]ëìœüCvŸ—ü‚Òã,¾ì µƒwSÊ›}¢@*gUÌ`—**µ_‚]O 8Ä7蟶ó‰¶o/¿üðXkE‡Gþ 3ÉÓìšMAƒÜ}Gí¾¥Y¿˜E’oç÷!§36-4®òåÁ–QšÒ1{Wª©Yté”Ë®ÃxHŒÃ5GÉO÷JCaÂ0n/˜´Ju£ôDª®g΂¼‘Ð *î·Ú0 åð@:ËNñ)ƒ¼U T"@æÝ\Á­E|Êl\¸ç‡ëe¨H’dôë5èF™)âJ¥·Z˜÷ôm ÀŠG"ßÔÖhpö…zÍY\cªÛ˜aUdª™Çê ‰ÒdÜÂýSñ J�)– ĘM=È^—$1VðüͼE¸€Î%ÁdØñk0‘g´ÌºÆ3‚S[+³"¨]fa:gfX¨ré[‡$ÀØ¥æ5�ƒÝ*Eo‚9I_R«¡´±â'ÊpKWOi`õSxT%…] ”DZ`êÃKyW˜möþø¦!ô> Î$S[Ž`X×$J´6„vgd±¡^ SA)9º½Xé ö�ÊÜD*ø oÕ•‚ ¢)ÄÁfïe13`¡J®;NÊ´ERŒu!rÌ "jAœªŠ¯H ;Ô)Eá¬Ë`t–aX¾S$ï”@›Z:ˆ¶,¡ÕÄîk"ç-LcÌ«DdÓ?¥Þ5<­åJ»™õ}¦hÏ5>[~¡8NN§.XuÑ �ÇdxA�ƒ6EºQgdö—Ò �%*sûÿÇ`ô�Ô!.<½~Çü¹sâŸdXƒ.+·«ê+n§ê ¸ló{ïyA�kTk<Ų¥Z€;\¾bï»´p¦øº„.fs¾§ü⬺¾¿åÁæ4$_ù/¸QkúÍk¡á* nÙ�„vq…[ÞeŒjãE9­%#t‡~"ä,ØVŽ‘té ÕÃìÁê$ž�ŸÞ³ �sžßq¶q GZ‚ÉI}¤k‹Q–²Ïuü úKäK&¦DÄWIWV'-kñÔ“gî Þh±É Ü7Ë"ǰ¯hèTeö†µÊå`Bèç˜hWyŠø u'îØ_ˆ0 ÙÞÍ,¢ U£H:ÑJÓj+¬ôFóÞàê,( Üi6¢Ö°y/$IØ:‘¬Úº"iÙôÊH8¼EŒô—©B/˜Õ¥IÊžáü΂dQ¥j – ‰\™]V¡Þ vÉ(Àr³áýÌÛ~RæM=~Ñ„H?l˨h,¬B¶ZŒ\Ó’(A¹k‚’ðÜ«Ke3/2æ¶±ê‹X¾|à ¡¦l`Üu)Z k•¸XGDöÆTDt2öðbó]å8bœÀTA2_2£ª ðÏ5xÔ |ƒƒ œçâ d:uî³õ¦®ñêæŽ>Ô# Ð ú0•êÕ•qÕÏ –ƒ48Ž+YÒÿ‰Ø‘aqAYv¿pšÔ“q­*«³þÁ–¡M<ô—6ø±ñ. ¸·¼ýˆ´^ûAœï1íù‹ðbØvbþ.?åÅ’Z­Ae›-ÿ%âãÒ±P8£ó,»}+}¥®0›ƒQ…ÏÉ.\¸¾Ô¿ø3b|—ÜÜ»Ø Ó|j%–Ø*¢³¡xïKÖu¦+YcOXÊ8±žßÔ¶�¤c¦_´ ‹ÕÑ4ˆÕáU‚x—#a�/˛⺎ߨ)h¡§¢\¸caçô¦Ð*™ØŽTÒ=ëõ—Wı—eÔDÃ04…›Á îîWP”h&t�σ"µ’¬¸Y�‘Á-j#«§7Ú1�Ýÿ’ÝÂÖ÷´4rq™B˜X/´Uc@ò•ˆ!_ŠN.’ÈÒƒ½g¼U¼õru‰LºÜ°CZ C+|²©ÓþFPÓÿyŠ%PÁXÒaµ”çÌQ³³¨�Úy@ðÍê0\ W³0¤s³k8Ô:Z€ÀÊ^ ÖKÞ9„ ²¯³þÀíˆÅÒÁl¹Ô†¥Œ.LÜϺO/¹v4nU”‘Zÿ�¸íRëz#”J€Têu\iMÒv^üK¨Šj€UµLÇÅ.b‰´XT][³Š[¥LºÀaLj•¢Žñíq�bS]Î#µf{À–a˜,®]eο›4̪uM÷‡Y›Ú~™Ó”E¨è¿p+1™zÇŽ \ ¥m¾×7Ìvöý‘ML6$3¼ÄóéêZÿo™I_iû˜ ¡TZYÞ/•âв�ãæ/Vwó€­+8z1 Vh~bn=¢-�ïÞcÅ.Ýüª×¿´ íF½ânÎ…ý|@Ë•‘A þ/-}è¢ã`¡ÒÏõÇ µMq‰FÅÂÏñ5ü�¡Vl D˜Í– ¿èñ<¿WøÊ�þ›}óÐñϪ2õ¸ Æ¥ÐÄÝ|Fÿ¢]þ‰Ÿð™È&¸–tgƒí<hJ�˜4dfV›L²#Ò鸗£K‰Ï'�ÌÆ4»Ë„Aµ¹[£dÐÏQ=&=ÙßMËY(s¸ÑboSKF´â à‡)eï*•*ñĬ™ž …Ù :&Îoûq¢ãl hÕ[ sáZ4Ã㜄¥oy!ñÈÓx¨$�àÆwËB'Œ|Åe:Ô``ŸÍ+7'³kŒLŠ9™" ø-`C…puÿ�s'Þ,›o9®bm+bÞB�Lj³5JëŠUyåZ‰š[éÑÞa' Žb³ï«r^³¨ÔÁÀV÷‰”(]›ãµË9Þ °0@‚:&ím$â<Ÿ˜rSS†~H2qsp< �@C (eý!÷zX<ÒDQÓ æZ vÁAtÑ�IeÁk} «âPßqÍפ©5L_;|uŒX±³¤ç2ÆQ;@ìYT®lÕÇÐÇ�Lu©B ­½Y¤›«ZÇÄ!v® Ð—Œÿˆ—P´± X£r‘"®Ø‹*æâ ‰:`:B ¬U–™-Ò •*e&¶¦Àìò™7ÕÓÒ4 #R²º5 DÀ†ô¸¸‰àå–Uµ%¬ÃÉöN&ÌÍ¿äaojbÈ.U¨ëWÒû7�q©·�°tEʆ_,llK•æ.ØïÔU†Ø‡}ϨÁë\á¿X%Ô¹JnÏÅÿ‹—–bÇÉ †Ïà�åôfô¾ìU^«õ\Hž†Zó)¹Ö%âî Pj£Ä;d¤ˆjZä }KÓ2Þ¬·¬·V »ú庲ެ·V ܺ�¤o´·X.¬µ sÒ^jÛè^Ϥ{Š*-˜0Àª¸#@íÒ¢’Ä]÷…ÕIÈDF‹ Ü¾«6Ù•±aXêé»ó,ÝÔ²ôNe{Yb hÛ[Ô¾Žâ(i7wŽ ÒVLÅKtÔØa2ÄTAoRäÊÚ¦Xx ÈQ Ø„K3×¢ óÞÐà•jñÚ`Ë0.”ñ0ålDë–zÔ ét‡øä-üH+ø¦D4ŒgÄbõ0 ±d›c#Óqd^ºR®ÅûAj1¡ÏyIw ªL™n¬£+3]ḞµÊ а§êcÓ²šUBƒá¥ýÅíiV2^’»0(V+AZM@.á߈ò¨Viæ³ÈŠ�AyôÇêX«/'ê!y~§ê]¿�¦~"Á¸.¿Pqþ&©Ñ~ÌÙé.\\Ö¿\ÂŒ®?xx—.[Ma¬@ŠZXúCsé"+ØùMÂZØ_ˆ&Öj"Hy¡Câ'z”9¬§ó2̇}@žŒªéÀ©s7ö>ÿç„ìKe0"Ó,赘K 41ëľEÓ¢p���h@»×Ð@Æ¥•b<ŽÈH�¬²éþb¤œsž£d톨Þ5ëšQ5E¶Ô~à3 W_¸½j—S2¡KƒzÓq—&+´@qW-³ðK½ËàÚïÃGì"wnM/P~U#uÛê3hœñ-�áDu. †dâ¢ö!�–T¾Š¤µž‹Ò ç§XXƒfc2u”u¯Ù9}“£íì;38ß©Ïyxa`°å£ÞR6"ÜP;þâaVí èËA¯Hƒ•sèŠXÛŽé]Õ1ž–”·*%_¾`4Ž.ó\Ëã¸SYçyÑ)"Ä*L›Ãl«ò�Qš˜Åu¿h`Ío:/±P|ó-RÈ91 ßHZA;WG£¬>¶àìáé8ñ«:Ì2»™�ßäE^³ 6kÌ©nb?�4ëKâb1!Œ9ÿ„vb˜™©¨0vtfª‰ÄX›½ Nʬ�ÄÇ™‰·Þ\àýÑ—‰–¯0qSwcæU�"èÿ¼VYÝ¿ظV—¡·â(Rj½gµ”fv%êÃþ?3˜`¾X«Ö`þ ÷bÃSàU¾ô�.EèÊïaÏØŠm2�õLxÄ;ÌÕB0gÊ|IróW‡ÜÏRƒkk—üZÎáK›º~?âh•Mt†Z‚‡§ó Âà¹êDE’9aýyÿ—ÿÔ2’ò£i;c`AX<į, "¡)OÄvwcÐCsl,"À…«>`¢ÔzÙ_ r•ÿØBc@a¯PdÓž&½«°‰©‰oKà2€,­‹Œë “L°)îBf—¨¨¬]_1Ê…¬ò°뛉!@:‹¿$·…Ü—¶³+1ëïú‚juƒS"õÄh‡aðʃ´6„RÄÇix<Ã$eÍF%7¯±Ì`SM: ®ù ÆÖ€¨-Wá3,çáÞuõ:B[3°"Ý5ë1.Ú+,USA8¾¸‰S4nøêDcÀX]lh…†ÃPòÍuˆ¸'cVF¢ %á¶¡�6˜½LíÄɧ®!vƒ+§©”ÑX!7—.¦š:8ŒF¯œ†:SèļBTØgªà\˜RÕwot,®2¥%À:ÏÚWq˜pšo ™®µ<ÌQÁ–Ž “ÕÓø›� å9ÿ€� Ôe�=âNëq «lÅ`�ò×ê%«:æ¨X[Wìæ!Së±ðÁ üâ;ý  eW­ëìÙÅ%€&P-1õ(Ùæƒ¤RCcg¼=ÀÃÁ2nÒ¯…/TÄ×÷ ¾ñªo(w*ü0\Ñâ"Št–Õ[èG5|Ž—¿˜æ\Õ¿{néyéâ _!Èܱ{!/˪žyu¨ÊR="6¦œN¾eÙUýø”û‹C‹Æã»0Ši�y�Ò7(  É¨ñ‹`n2¶óõýQâ”3m¥Ëã`àe²¸Ä©Õ'~m.³4¥,g1´§C´TÔdEçqR(xn_×ê­Vôƒ!T'!éVÌ¢þ nµæ®A}èõ– • Î é(Àr8Î7,m]æ6ÿ0;Æ¿7Ú3B÷ˆ£W‰ÜÎîQ†Bd­Åù•¤(›Î6 M³W+ù"èB]‡h²³ÍŒ…ÆP‹‡g¢]…êT•@÷˜•‘…�ö‚€ÜÂ4TœY«‚-š[mú™ÝÛŸQ ²ârˆ®Hãqm}zB�ÙÞ&�ƒ]³ÃF—v[”�µõgdœÂ S<¯¦ ׉„/‰`p†ºx€ÂËâ:ð¢ˆBÆYo¡üFå0%@/¢gTÅLÈyô\e�4åªzî%Â³ŠˆZ/~±©µWÒÁ»ŒN¢¬ô•(“¹Ì (u0ŠöâÜÃÆúÆ sIöARQÝ�ÀÑCÁ·â ,pàxý¡ˆBºK”«­æQQÚ©Ôòžßêeƒ1y¯ö–õeÙ.Œ¤¶ ÏxiîG(»4ÁEÎúMâÔ"âœÁ­b` ê_ƒ �¦Sã‰à£ÄÅ_ kÓ†b`QÜGhzb…>Ò8iŒÕ`Ï«jzaᥱAËЙbN%déV©²”Œ3J_™q´kØâ A€€Ïx*3eÆå,€ìBqÙÌ"ž~,8Òðà ÖÔä’õWËú‰©2î3Ya+�~òà±¶¦Ï;Àp·I×S?Œî Œx—¸"[ÜâóÖWåªË)Õ‘æ1.1‰®· KWøT*­ŠÜ‰¥î{L=áçamª ÚÅQ•‡›8þòùž�I†R¾#ä°O$±þÁnÃd ŒÓŸXax_y¤÷£;Ï3zx-o¼Q8ˆ¯0m¹ÇÃZ:A$©ûàD©çË3f0ašÉp)QsXhW—5Ý,ÃÕ4©wjúŽÍW ËÕ÷|ÅÄÅ¡Hp0º)h#Uêû—hUVZ€ + àä¨b³Ò¸Ü+ д~<ÁõÂâ± :Ü{åhëº 7ª¦ž=åW뻾¢5M×�‡(ª,ú��6}Lèð”-S[À‡¬,#¦ Ž`êèÑPbŒÞÆWz„¾"ˆ¿·µDÔåe#Ó¬Q¸Ø%Ýuùœrâ#÷S¶Ì&u(Ž`�0¨m½¡ab† FÎ5vÀypg£á:,Ö@:Ãླ�5�媭÷•�o~å ØDÎk†WÞ ’†mºë¨€4ç­ƒ«Ù&üÑ?2ÙANL,än°Áf=u‰b�ãˆë˜ˆ&/�m¶dÈnš+…\‡¤5äEÅoò‡.QW³(�•j_ñ/c«–~#B*jß©jÈ1gê_,—Ê?#-îÿPb—c‡È–¼T£±èþ ê‘ïþeµÙýé)^HÄÈ: yB‡rz8�PÚÓÚf‹cg‰�pk,U#x½sN!¼ê-_¨´--DÌãõúGRÔ-![¾„BrôÑë~'’Úÿáé8Ûý^R¦v¨„5Jì:¡.ãg\L›˜µáÅêKj gyÿ¤¼Áª¾a{¯ô ® ªÇo_ø¹èþ] à‹ ´ø|A0ADÓˆ€–[‹$+Åb¾Ð`˗ҿȃ/*÷–R'?ltI!¥Ä.å¶`tÙ^!m_ä€÷Žå‹PMªÿÍTQ\ßâ4+Vep\kޱßàLxŠüd¤�’ºðÃ2¹J_ˆ€wžUšT°¡Ñs¡l=%ÇM²§®¾à�¤Ô­0U èS™�z³Iµ‹Ré0殦°ù„„Šä|Klk³Öjx !æõ•áæQv··@9�É\Ê-,zG‚ mr™ö=âªS›–è[ŽÑ)6¥ÃïâJdã«èÅr`²žÜFÕóÍõŒÚ-o—;¨å2Ã#Fp(2.± ‹2‘låÙœÍEž&zfeÃ?«–UêùpÀ¢7­ÆÐÄÔæ½È˜V¸ö�õ˜ËyÔ¸,]†¾£g‚+Î/ÌK£¦8‹ |?õ�Gˆvzí³PÔ²“¯¼ À(7š·ÌÕ#4«ï �r‡nЇ…6¾i„\«t�[X¸^b R³«ÞPÍ3FMóRš—-@´rli"Ó5C"§\G6ʰZ!Ôâ ­eë$h•@¼ù——z"µ9bެ̶÷®òÆKˆÀ–® X¯i`Á—¶S4¢Ù†ËÁ(ª´N´¹ÔwÙ|1H Ø—OR‘ê4�LTÜ+Í¥€q7†‹ªuŒ+�vª#µ`K¼Wæ\y‰I³ê�¶d\Û„ª@ˆØ‹¼T LZ>„Àµ¨@QJÈåÑ>p9õý ȳlÛŽ°hFhV+ôšÅŽ-—AÜx„*]Ô5®/ªj7ƒ}áÞ® Yÿ¹„ÀU �h•mú�t\˜1Ð4ÂÂ^`Ædª½ßˆ´V¿RàÅ„{6µû°`Ë̵Ûù`â^%¯좪éw.ý9­ü,½„$Å7Sļvä[ä‹(Ü¢äÏ~%nÁQW¬#_Ûä:<ý@�"™ ‚0Y[R„N½² †ö©tEEÆ.Q"zïÎe²¨²Óu9%@ÜQE­ú“=òÓñ,¬ên e*ã†ÛA�vTµxz“zïì²¥é-¶¬+5µ.펹¨Š„7-gªP:Ì’Â]ý¢r™x:Ëq‹iw”›*<çâ½³ŸâáuÐ㌿쪳`éÍ.aû· ,7WØL8³ñí*¡T0µÿÉBšÜ×…S¸Üî’åÝŸj•1¥º–¼GÑE¬Ë¯Ébc+ƒâ#Y æåpº`²�—JÇ÷âY°VpØ# ;Ì`V“¾óúbUòµŸ‰†[YN ¨ÙáO7¤TT,-EñZ�—ªG¬ "õð[ÉóýR–dFõC£˜[ á ‚í[d¿ó‘1¥ JiÅv‚¡$SC»|ÅG.�*Õšñ(6Mf¥ DZ|-¸¯R] MZuVâò\ nhKE�înh¿ËÒæB™ B…FPÃæd'ò¦Æ]¼V¸™–ú]L,åºÉ®“(n b(…©.æ"Þ‡Äê"Éâ¹jj�Îfn¢Á8S/©u(mœ5¨Ä%ZÅË 5Wx€,]Ñ�¥ÔVGv_Ñëžeú.´Ä1ùœ&aÀ®6–)g>—7:ÿo—Þ5p((1ÿnSƒÚ2æª."Ýü E…à¸CÔgâÿTt—II¶’�/2›ÖICO¨%çàD�¦kVƒE1Žì#þì£~Ú€Rë9x„ñ«×p·›Ì@¹hpa6ú€Þ Ì5ΨµG¤Å�[•ÀkçQ™ªéõë2 —*Z”eŽ7¯µÔ€y–nfMÕ]µ)Ë­Ã�±A³|7’ €�¥9ë �¸·hYòCrÀ¨ëÚâ· T¯á/ 2µ@ÖÑS¨.¤£â3ƒb¥©�,B´–o´pýƒÁÚYdz·ñðQ- öÄD`iÇV¸–93JÇ[Ï0nq·üK›�yJ•l [˜C0x ?Q+1|Ê XâqQ•Ùnèçû¬$Ñx¸âÄZë.³ÄqÁ§|X�`®°z… Qt±ª¼}B{º)ÇYíw‹ß_rŠB½D²©Væ ¶Ã�]›óp¸[/Ìj š»õÀ ¼»ˆ 4BcdQ l”æ¦c ù&gAµ»Æ¡Ý× ¿äPë -e¯hõQµ{xe¯QÐrB]o5|xæ`RQU�~â2Päãçs‹ÖdP`§{2zü@2]"4pÕÙ Zªç5Ç^±]SÍAÚYh¨Â4?Ç{‚S' üE¦œÙ¬Ì\]@ˆÀlÏÖ ט‹³há9”Š-Ýuƒ•Cšÿ»Ê›fa¸Ï! +»ù€‚¹æíYE>"an9bÕPð÷—­HÀдÁé0ƒQ‡nÖUßÌ%Ö¥Žä¡å)»†6tŽ%hU_÷i�SSu“Ž�„o°µ½5}âó ÝÕM0mã€fR˜•å‰9"Ûó(RÈ©”ê(šD´Sà~¢Ú¡õ?Qæ'[êbK ìÞè‚¶“@×´¸ÎtWâ] "c1kåäY¾äAwH ¾õ ’°*ƒNúĽ «:Ó_^Þ ²'ŠƒžÆT7}ø"�°R‡øó1Šà-`®ˆÂ‰Öà\Õ;»“¡ÞZut¦*çT8Ëqðe(6¹ºõ˜Æp_Ü+¼«m,ãΣë6¹jï3š�™gÓý›+9’êû³<¥ÅŠñ/U%iT¼bXµŽ(›ô¿ê‚VD¥.û‚Gᘒ©¨<Ž{Æ’4½;ƒˆn9tÇ⥴ÛRÄÎPT%Q�YAÄ_â@-)VWõb6�ˆ*fô_ˆj+VÆN�Ÿ1ê„ÁÙֺkÇÕ»w� •°!¤eWÚÃCŸ¸%°‚øÄ€ÓN½»@’‘™^‘sæÙZ Î¥îšÒg®eh”áh[,€•ig\0Ä6.+eeâÉ�FõBrίÜrË]â³R¬Þ}f XW÷ 7j”«Ç=!ç =úÁL�… B’eDα«Òg® JU¯o¨1D7=JÒ%âšüÁ€;dàíˆv€á ô"–v1ÜÄz€èÿ€ÚÕþˆ:ÝýqŸªk+Q0«ÁÞ P©Ïþ0[4f ,‚1Õí "ˆä¬õ37é]Gâ Qoba‹¸$k8ß`TÅ©dq¯.“]îZÑT©¢'/õ6 <¿R•pv§¬AJ ËÏĪ+7ºW3;Œ¶Â lq­c© P°âõ fÞì ”1™¥@ω‚ ¤Íô‚ë£~ÑÈ%/+m�nש~jžNð(!<$KÁ‹ÌtØÓé— Ó²U?’R.X¡Ú?{õ Š ëžYtIWÞ]H7M.MÁõPËŸ0Á ¹ð_ÌÌ…ÝEµšwœÆ+myD¾Ñq9†Ưxàò¾²ÿÉ�<ìÆíGhQto}嬢‘”`ºÄ¹ŒÔ¤»w#D2â‰JÅùƒˆ5/1£G—¬ví(ÔøA³þ6áy lõbæ ™uõB6¡ž«U¯yfJÆ‘— 4Kdžt?ùeg XÏ1¤h¥ÚÇ\L]qZ—˜µ—Skƒ·‚]Ú•r—L%³ÝH‹wNe sW“{ŒÖT*ã ÊÐ_¤¥SPs{•,(ýÀ%QÛúН8xcC3,÷•…üB(…Ôè R°¥Aå”à…v ›ÊúÀ;¢¡æ¥,\áêc¦ThCUÇÄpZ±ªÌ2+B˪jsëa+OØåø†É­Ë•˜H´ /X‡8JuÔ‰Ëp }ÌɦªþåÑ gšƒ_€«âÈ”®€—¦Ú âÁ—‰‰Ñ£¹mDäãæ%´w”†¦l¥¨Òô¨” ºú\ll»9c2õ+·©ãê!,�`K.Khe¤1€J¦NÍÿtŽ˜»ˆ†ž[àˆWJ«/ 0Ë1mAœÒdþX¶Æ¦á)­ôýÀ·tšÅ�–+?r2•€İ1 ì®"6e—UTPË“˜!BŠs é¬Ñl+§Xð%6y”,3ø ³` t­}0 4XtñŽùöŽR^=&.-xaK]K5]X4bœ$Ä<ô¡goîÑ)È”Krµ ¥µ3ÏB·;“&My…ζü¯ê_«/{–­Ë v¾¦™K‰:¼�G³ÁÌã Rm ¯ìKo»ï ¨é7*ÍàÒc÷-{~c#.öB¹€"M+«*b^!Øx«™ð‚1(0^¹¦ €•¡ÝàóBö[Xçô”ަ‚³P¼Õö?P„Vƒƒc~Œå`—\Œ‘¦©N…t—Sª€ªq—.§´>˜æ’ÝΕçP–¥*v@°Î%�Öº8AW!.˳˜2ÁË—RÍL3\LbX7£Jgõ ±-¹°]§2çÆOÌ(g1̦­Ñ߬jÊÞØ–$õ€‘¨]¹›•g.:±¸ª޳(cÎî™C v̪´Üº`§Cœc±Öó6®j.>Ò�óyá/2é¹ITªù�VÝ/Q2bZQÛ›LoaZ÷?X`y†ÊÒ®VY–µÖC#¿ÓÙIÞ42ÞehëÉÁ'ªŒí2 gš©Q%¨„{=­¯ˆ ¿Ô¢ºjŽu¥Â°Ò ü±œ@b·$-]®9ø›IËWu¨¤Ú˜Ï^ñÀ•òõˆèÀ,\�u�ÜcgYŠän8Jf4Î/¥@ˆ®ù‹S`«^ñÀŠªK¿?‰{KKæ¯ï/¼·p*×Ç?¥Ep'î•-ÏLËþ7´Ž…9[ñÐú—E$BåªZô¸€±NrÔ§<µrïÚ$P· Û?òeWC†¯êS‘H5ᨇâPr+œÞ¸ú˜üÁKg.“2o4Æl{¿¸Vö#2ŒßYbä.ž’õÐO|»CÓ ð˜ˆHv2vŠ¥ì�)N?¨U]â£-fŽ Xh˜NÑ�p7ÄX‚ÐßRÞ·-pfdïtÌ thló*k áíÏÌ;º¯H�Ã#LAäŽS.P°,(Gæ·kÐÆ¥B (<C¡äÝùéæ-` 0ä)�äÏöeñA±h³lþ¢FF®+.°Çú‰{Ú‚1ÏÌ;pu½Q ÀÇ‹Ú�^DÊT;ºà…KÍ&q+†Óû�ŽË_¹±SÜ[ 2£©Q„Î[æ4¨·[ –­ë—÷ƒ#�h›å¦–aJx;²�¶”ÅnY¡­{@*Ô_¹…Ö—Ê'ÜEZ ^½.r(F‚Ê_Ä5\8j¶}F´ÍœUÑk“ÌjŸ’UßiE ëÌ[H ÞÔ–Þõúƒå)é2=BÛâ!8ÆõvN2™F–œCŠN�VÉwE¡pLõ ‰Ñ‚ä#™ó«êPý�û²#—þ.S^nR‘™RÌ¢†àî®Vœw�UÜQ%5‡Ì8 ê¥~�è-ž"¸`fްCnkÛ…35Y¦NñA–y…F‡‰9d'~^&×p1ë³ñ ‘p(”UÂù?q[Ö W¬±Þ§ÇxRc’¯ó ºŒâ®ëÒÔè¡ï,£×�Tä¨é…+ˆÜ­'hX[ŠæV–èS²ö*8C¼ÄÝ(D  .Õç‚ãv¤Ñz¨AÀ)]’ýJ·ÂÙ|[PâÇ¢ŸL_7_í(N„¢¿¹†ÅÅÚϤ©{µ§‹† G%¹kP¡¬ªt”ojB˨¹ï¤¦¥gk•PµS“½Ä¨[ÆPáË䆽"Œõ5çí……641X¼Sï—´h¶kÇWtzáñ(­]X2iÇ9† ²y1TE)eäщZÄjÄÊ]Ý &KÑ�È:€l�·ÒÿÈ©`È »~#4.zïÇ1µé¶‡Q$jYßMî §%áí1¡B½w×qÙÒ´¬Æ­8³^²åkÍÚ+™Ì¦'_‰%›p8ÏŽ©’‹tÛ8swýÇD¡ªÉç1ÞU¢¨ß3Â%$óp^äcZéŸH/æî–ys ›±Œ™ÎzÆ«ª¥´­=b¼5Þ ~;ñ mÈ],‚ UM¹•Ñ …Jñ4ª öþüÊÁeu½xϰ€Q¢”V÷Ÿî`¯søq=&Úxÿb€ÀB�e �7v˜;–C§Ï »·Óó£[¶Ï¹NÆÊ³]àîÈÐd¼]°Ð¼E†%ô�KEiê§ipB=àÂZ,R†ÄaÿE5–€AÔï¸jebÌ{ÃN]"W"åuj‚vˆÌÂËAéÒ q:i¬=%ð¾œ�uêš•¾—•›ã:úŠh»ØWn±(oXa›EÚÔUÊôNN!} Ù…?�¹FùÎX†· êýcHæúÊ¢J™‚ êµ,©ž˜ü�Ô"Š÷“^Ò¦‚®Åå†cª7RÛ8nhc¬¬èϨöÜU1œæ8§lßXà`Qs0[­æ&VXÝ�!,í¼Å«‰µ�ïYõ¸ÀâħÖa»†HXJ¾.†Øßiq㜭@UK7Ú î;àJw°îƱ´áâZ¯5+ßÉå™=A“¼’ˆ(UÑË{Ò»ËþEax|@NË«¤^J•»l‡òİZ5ÒÊû‚�”: 8K/]"ä¬ñQKÔõ†&’¼j.P^ÇXqA³ˆ–§�ô‰BG”6NíÉØñ ‡Ý1qÔ¤ðѶ Ç!@<^’ª}"uB��ýÄ¢lèª1Ê� °¬ù¦ ôZ+ÞÖR)Hšã¤½êÒÛd±¥Kk¯¤y‚Õ5¬Dm-l…]æ&ìØ¥³®êeÜ–ý˜É¥,ÂýKùSW ÝIW±kt |ÌnDG8n\À°K.$ðÑVk-U²ÑÑÙï,ûøâ2¢É°ì…ÅЉVXNYë¨Ø¶#’‹—r�ßþ19õƺ0�IÁipWxP.þ"6íýæ0FºE�æ¶�uP~V±À/·¾Ò�3eƒ`PJ5²ûýìÞ‡æ: ö:pK`Sž•Îa!om…¼Bi%V_òEYåÆG?0#‡6/ÇÃ1F —â¸$à9K¥6 Ú¤|dLøér’�JÚ®Ð*º�·Äb žs¯hTÊVƒÍ0'6�²ÀĦ.âJ¨°•nžÓ h/RP'`^Ü&"¹¢+R¡S›â¢}µ-w_¨±Êp÷™¥#�¦]क़¨ð˜ö•®Ud;B¬¾jø–JìÏ×Ì {,�_ß´!‡¹’ßxØÁ‹b€5Ò#w^?PxÂcXé• ,C’œ0W(rtˆ/©Á€±ì””Ÿ¢Xߥ½Ì ZQ¸­+ÙÔW~ûà�-Ýù—<|/Ü…×2¤�ÙKEWÓó—F¸/Ì´«»ï*­*¿˜ Po+ù–ö¨;[ï·󘵻�Á;|þز[\§æ,‘­H+ob×i}¡¾\ Åæå‚n²:D$�v´Ð>ùŒçƒà£ªh® Bc 6f…°™ïn™é§ WÄl¥�ôèøë0ªì;ŒK©¾DL‘ÑöÀÖå1Î1ë×Ò2yâ]b˜=—l¡{ÐT(í•[Ou˸�\^¸"š3:ÃPÈØ­a³¼æ)Õë-E0Ö#s Ö°TkÒ NüÅ›´¡Ë¨‡q0 ¸ B‹„°!Õ™ÞŽî‰Ýð@n)’ùŽB•‰†£fdaM\2ÁÔßo¨b‚¼7º;·]ûüF“X+Œñ« 2;½1çU¨Ÿ–¡OÞ%Utú€ü¦~Ùl6t¼ÊÄ,îçÍJà k¹+ÄBhÐ/•BØA†ÙŸyt.‹}bVt�_”Sê3NºJ…ÜÖÌ H•¼*,™\ô`Æé™$Äe(vaõ„%šÛcQÇòòP³ ×Àt*_Qà*P�Èí¼ÌÞÂR•Â0Û‘ê}úŽ`Ñ ÁÙq]¶Í•P»¶¨çó“a¶×ÌãjùMBÇ=%ÁW ébJ¶âX‹”r¯ý€*Ã~~fg½ÖN�F‰H&ÜpÊL†~XäòÚ´‹X”m�UL£K&Šëuq+•­_ûqì–¯W‰~©¨ÂööŽ´±3aÛØ†ÛTßœó÷†:®/�´«˜Â�´[8¾°èý4F.®9…¨XìwÞfhòŒ{¡ñ�Ì/9k[ô™×ÅkQ‰Ô¦j:µ 'zõ&-ð.À¯39£a¬õ®œûÂi±u�+qÒ¡«î-÷…©�k °g E„C¾3ð¥•Ñ¢[¦Ã;G©µÕÅ­µËмù‚É0Ú_›ègâÊ"ψQ�ÕÊ]çâ"Ç7lõ©×sÒ>Žørñ"œæÉ�¶œ¬»ˆ6�ËÒ º ê€�©)CnÁb¡]È6…¦;hPRv¨€n £¯¼:Ð ±eäu™j«(,lj»ìÇx Tµ‡^sýˆ®ÎeÄÞ£–<Ú–ÝÀ¼Ü7̶³.2Ý3ÆXU–ehô¹h¹C ôLƒ„¨î!w,(/qséŠJ´º‡ qB‡vºÇLY i;õ‚EÌRzçÚPBa»dé}N!r¨¡XNÌ´�0ΘÙyUéz²Éfë j6 ¸�rBç¾ 4BYã/— ›L4¡Y:šÌ¢ ZÇXÙ � Ć«©T·'LGP[KY¨·±\ヤ14DódÕ©KK *γ|¥�´Ô\ôPi~#〔„ZÃå—Î…YWˆªUÞ¸— +ˆ† á*S,æ5@Í”«=bD½Jô™!£a|ŸðX5ŽN% •uÖʵÒ5ÒÆÏz– ,V®±AI..G¼G^U¾P€‰ƒ¨ÌXZ-µôâ-¤4V«Þ±„¸5õ)IDµO¬Ë•ÅQåuS ·qOê2˜L}nå© ݺ,¯È)ÒèØÍ.T ÷=>c�å$Èsd=#�a{þÜÌ@rS¥LûÕ�Cp`MÔï—¨ãtK* Q}TÂ�«ŒGúð#g«ö™ŒNŽ¢7ˆåØWimvólÄö¢ˆRáªö�2ƒ ÓÞ+±¨3¼ï´X^¯7QÃXÁ¥ânVg!]jmeLg4‚Ò”àW�H×6õûbUYÚ[ûXô±ÚbºÂ�>O©SUÅüÍFJžêä BLÓT*ëS!ŠaÏŸ3â‡ËQo(àø„VÊïdÐÍõ¦6'?؆�ÃÕq~î•{ï °Àø€� ¼æß.Ÿ¹yIlE”äaœžâÈPC Smñ楶 ã}¯ÞXZ‚éCÛéïV Ì.I-Çjv×|@·ðé‹í˜ÑF 's‡0Ķ—GXóo¹¿‰eES~ …9FÐ(z”Þ!ðÈWOXÕ  ÚSµÝñ ÅŠë ‡Ì¬&À=Ä)�7DŠÜÃê]JâÀÌ n”.üžñºØPjÞž#T@,â»@ŠÑ wˆm1pö„âŽ÷Í‘m;ÝÕ\E+C¨0RÙ¤{§’PLUÑtG8êng m¶ƒ³mV!¯¢*Î6­ÜtÇÈ«yψ٠¦\µ¯hŽ¢x/Ä Œ+BŽÙ¢7 Q�K‡T¬Mª±ó,� Œ‹ÉÄ^û­}:À JÉÄb&ks|®YŠ�cÜv—Á‚*ð›õ¯xlp°cxº lU³,Îld`¯+SL»;1éAŠv÷�¥€*ëybÛ2Ь_ü¨ 5dy¯´KÝM“>OhM^jŠÉÞí¼¿ì ËÞ*"�¨N]æd ì]}b`�t`¾œÎ‹«…ÅÌ!gtâåÙ“§ô‚€VÆæpasÑÏH2ì„e>�î-l:ÖÉh´:�÷4ÆXÈ%ôec¨8JžèâúL&“­ìóàáó«þܾ7jy3}£¸Å ÏŸ º2Þƒa #»ï�4ª:.òCÖÑÆ\=}ìÝE Rrw—"а¿¬Ëm�MoÄ|CuŠøˆZú}Æ•m¾Jô v66Ê\ÝTv[ 8 „Åïo}ÙPi®‘k–£Ä„ ²¹ô�H �<‘˜r2§XŒ(R¯–E^µx¶bl›uU‚ÚÐñ0†"a§N³L×i¿F-«&Õ\@¬çBϘA•3�ÜHÙÐBħâ •ª4Ôàä@k?ìØ÷*aôéC¤�|Òññ6^p(½-ÅWir«”¹qÏ÷P+ÖúEVà´µùa˜¸AÛx~ýã©]•ÖHlˆ¨uGLÌ`œŒbN¼ð³ûR¶´,b™Šä.÷¢©7Û +][t�}•ió,Hd»àÞªÐýð¶„¾{J-6í¸ù*q}!�`ej'Àð5 v‘‹j«å„Íc–ª •‰UA´¯1�¸‡�‘8Le,Vf!ºTn³ôijƒÄ|ϸgÎ8•¬�  ©@wù”´© \°¬_ƒDT‰@Öù¸Œ UÑaþÀy y# brG1£¬·çî "ÆýæPs+F¦VÀÎñ±*”h3y`¨ ô�E‡Ô’¡û!]¿ömànøXÂ�%!Ç™z#~Ç÷uâWº”«¦ŸR¼^e9� ÁXõí—Å+„3Z®!€MR¼î(CTQM9Šàšàõç=atÁ•ÖU wZꯡ}+²Ú+®&W@™»9ìx– ^z;¿Yq–œ›/r¬Ö¬ª×mÄ>…•«ÄL µÍ_¹L È[0a£Z¨hè7Dc¹ óÒ]YÕ”Ãw.uϸ¨i�ƒ† Mëˆã ›)CßW“€éþÆÞgCƒYܰzðå† "q.ü23 Ô9 }DP„ѾüJy.ƒ­Íw¯˜Àm¹Qo>Ñ[ b;"ÂCcmøâV蛊N‚‘ƒ�š[­ÀØvm¡××ó+ jîá ÛW˜~ k¬Q9èJ …²EæpU‰¸G|=›óDr…ÅŒž³t@Ë’ï ˜ äzî2x�PÝu€mÂPnó�f4Å®CiÓÄ¡“ÔÃVnÕPë(á뿦(€´Ý”^u È…¥¬6Ä8 ™-Wνâ}7Ú�šo¨´«| è]=^±Õ3xÄU}4Ù»û„†�^‚$ »¼0ߨ…bï0qäDÈõ¹¶cHäM Ï?rù(1Nqÿ°ÁFQŠÄr*ÈZðxŒ¢4‹xb{3‰X`%�Wäsé/«XÜ,Tõ`Í`†e…¹B½�÷– ‹ Â]¸±ûˆ™ß;LäxÆ&(†5Jê?Ù•7GÓ í¸>–õqÈœ�-3l¤zŒ²!¹ªë­B±æ%§5Þ4‘m]WxÖs…fº¿ºC¬{�†Ÿhj.œˆ�ûµæ[�Gψ:ð¡Úx–ýQ;¬c³‹í‰vÑ\€G?ÝaÓ/‘„믩au[JÛøÔÜn ¦ ðÃÅVJ—‘NGõË•.ÀYttuë ƒG|jQ” S„7„¿gê5Ñ*âµu*4*âG›þ¨Æ×o:—•ŽÜk‰J#ÄúÃþ!ÈyL0Æ™wIÓê_ªˆ��/žä(;ZÓërÒ{(6_yŽPq¥~ׇÌí•Êë[â;F{ª{WÔ LZ°èAå2½¬ñ@ckÈíÞ(ˆõ$zs zÁËUXn;:$Z¤áÉ´¨zf Éòˆ®BŒ{0Ê@ vj¦ÛÀóå+SEZ+îgÞnÈ üÂ,h.pãÒtÎÖ´?2’]¢5Ö ”ÖÞ2G¼H¾#Ð�×Ás5`SMúJÙTc¼RË\Á£Âs"ŠÖ£3˜\ ùé—\–*qcö>#)ktÌcÒÙËMrËe¡´=`p hMõœ…Z¯m›Õ¥ä†#'U5WV3_ÊQbí®ÐäUñ€›âAž+÷Di\y�µŽ¾"ÚÖpãûÞ˜HPÃ6�Ð>UĵwÛØ3]á’µnÏ}KJ¼-#|ÁL›\ˬgÖ UmI’ãzÑ[zã2µS†›n¡æZ +®ãÙ¶ÇK÷®#j¦¢¹ÂÖ¡: *âÂ5·ê0­‰ƒk- cR²Q¸íèD‘  Ý¿‘9ÀFØì½Ü*‡ Rá÷f0zÁ y¯x©³Š˜ª½ºxŠ�kVÅ ¬¯²T—# �ú‚ 1£Ì a²÷+AjmÂÇÄÖÁ—Eâã*Îqhˆ0÷»üÄÃE¢ûgƈ6´÷†NôB×J‰À!««š¾7üÊá�#ÏîV½­à»:¼}Á®ø1ó,m ÿ¢8·a^BÛÝÔâN¾*'¥±hp©]|³yí æw�̰¶YBŇžH%QÁÉ¡¸kjl×íY%o½]üD#¬Ž/+Ó¹†|¤høÚŽ:�fng6K³[ _2ÆÁ”·�Õñ PÂ`mj¹òM¨XØ]î5œ²mÓ¿¤¨]LÐo7¿È±(Gƒ�èa©¥ ‹éÞ Îý@tD·Zű…2GdŒÕ–y€Õkâ&ýh‘½­BÛÖ-«Ì0…×ÌU‚×W/.â¥ý3´Ñ_úÊ‹ƒ¯ŸÄ­Rë–ŽÐ@-TTßZѾZÍÑ—öúL¥nžOkƒþv…Ì� «Aõˆ��D‹C@ý÷‰®ù…p®3Áb€LU{B¶6{C«� €V· $]×KÓ/Ç º_œî¦…ߨԶÌÁÕ«P�»›¬JMª­àWö p�U­°üCágyˆ¹.�n Ø±YiˆÆõmVyWæXr0õ¾‘†ØÝtgI7FÊ?p1¤a^}à°€Úøº¦$ À»aD'SˆDQ×­À Væ²¾µˆ:YC&b ÜJ5-¨¢ž”RS•í2¸Ø_Vâ�†’;Am¼ "VƒM8ú•¡Ôäô®ö™ ‘@ueA v+Û ¥Æ¢òïÒe€»`P™Š c›Px5ï`ë¼r¿r2½IP¬ â"½{ ·þÌT,¢òÖû™R ÂÆ°õˆ‘žÛÆ:¥º¶¢‡¤Ù„bù¯ý–°*íúû‚ý©cæÈ[AÐnů¨‹�XæŒPyK£%Þ4B x6èúŸ2ôb©mév¢ƒÁšþëQX.ž‡f±À7bÜx…x%ìq¾l�DÑ OXi+¶Q-a¦å#·4‰ÑŸ0Õ6¯(AãNn¢~²(Ù®£¿1ž°SÈê|Å�„¾àçÇMt–ëyVxž°¤:Ïìé)eÈ£´Ts€7kë,“”u0‰ï X†¥Ðfo ËÇdn“eMØëîz Ë ýÌÏÄ�š3øû� Fï¬@SZì+Õ˜E |‘¯ÄgcÉ�L¥Pá{Ç«9/qÒÎ&¶’;W¦Àej`—’R|ÌjÏUD«îçÖY„KÅ�fRý™C.®sbœ\BËh(”·};Ï%JÎ�k€}QEÊ`]ÁÜ6’úV�H¾2¶.bVBØ…œõ¾“Öp ^ŸxÑ�¼´ºÊ„‘Í({jpv¬+$´! Ô :̽W–¸¾þs¢pÁN‡xÕCÁKÝ•XW›¹L¥Pn&Cœ•¨Ft7Þ=jLÝ&qŒebÃé:ýBÍÊ+Oaéâ1Ê/c‘ï"«}þáÜOS¬Ò>í0ѬˆçIõ,M*éÿaÞ-Ýæb�m:•Ç{ˆ©„ÉÜ>AoÇy_ú¢ÂÍ-·Ï®O˜Á‘Ú�N‘È †Ýòú ¯BµÖi!f¯^›–E,A¦·é3Ž ½e[ܽ8ç=¡Ç’Š7Ú¢êk—_ÝaƒÕØy!žˆ<þáñ X¯ê"Ò@]¦©î_Ürø<õ¿ÏXpªå5ÌÍÔÓUÔÍâqÆìË„zÁÄP�œSÖìbd¨U©Ò¹h9ñÞ?,è°æ¥ mX"k!‹«ÏĹdpîïoÑ :Y¸Â®z?ÌpD€jÌçÍÇÅo˜È¥]¨ADÃc kPÔd²%û3êÜC°«�¡fFƒ%§½úMjеÇ:{j,V K°ÖœBÀ6»8­W®laÉïR‚ÙjÁà!F„ìb0%Óâdèà¼)ûö”¨(âÈscª0ÕãÌY�ÀÌa%6rf(«›`7è¿à™�VëÌi˜âèù—%অ}„,nvù7Û*,±Ã�Sÿ%0� 1)gC¤§c…¾ÏE ]/�5ciÞæUøÁˆ�êÄf·‰Q¶(­!( …8¥;K ^,ˆJÎ6Ô3lUÖOXᵪí.PtUg×­2›6@°á§‡Ì4¹vò•T¡ÖO¸BΕ7*’æM½à-¨£œ:fŸhåbµ]œ¼îÛˆŠ§1ÀíÐ+¹ßæDÛIu,@Bì*�|GX/µ÷%0=´ùŠ¥†ò Ë1z–¶èVvÊ¡[(tÇ÷Üy0×$±dU8nºL‰`—Ô–ÎļN‘R�ÉÝú�ìÖ¡_'´x øzö”ûÊWé-N¥h¥¤­]3ó8g jÿqn¬ØìéÚS9\޲ÉWÂïêM:ó/0ãÍ9 +w§|Kì‘«mãrûƒuÍC/­zÜ^ÚæÖ©®"ÌEZ‹æ^1O.kÒ v;�ë[7 5NqǤX«C%ã»æ¥« :î¡Øt)öþ¡tN8q¸ò±›ô”­y ?2ˆh�¥3YNÕòL5Э.˜ë\ óŒêµŽN�gµÁ^‡D>€Ú+îs]ï/Û3);#…˜l:šÇN&£½€óû€§J¯0ê@¡ÉæRC˜^ئTÐÓö)|Vaß&!Wá_hÆÐÀÐk`÷ù—xT"©î�ÐÆ½À>õ.bªeø‡‚ ÀU p”¸¸­È8‡jBµ(ZZE�Å…÷ë58‚¡xÖ�æ<6|ó­ôÙpDkìoõ8”Ëm1sŠ×lÔ5H]((¼†|Çd£B€¶Æ%Z�΢¹ ×{…ðÂŽ¬g”%�ƒ*BÖ¬á‹ÝÆÚé0ÊkYû”W-©Ñû‚¡.÷¯î>BºMùŠ/‘àÁî䆌H ¶¤ 1p?×ø€îÇÔ"´\/ ãϦ`îS³ÂIÝtzö±”? ã/ü‚[�¢ óß0‰E@¸ «â/«š¾°—+YÄ=gª„[Ô)§Ä¨iUí­Z¬ù™He® ~e‹æ»Çâ¡j¸`ÐÆ�æHózg‹bTL”á­ ¹RËUwž§H õ3HØÐtÃÁ�ÓR�Gl®³Pº5— àMwõ§&ñwgv¨‹AMÒ�ǧxÒª(SeïÝ�ã.êæÓ4&U¿¢¤&�«ÿa,ècç5(pŸÝÊt˜ev;eï1 .k¹–“7Ò¸ QŒªëÒ"°,P÷$Ú©.‚-+_F¨¿¯¨ÑI¥…FªAŸ¼GE¥aG¬Ò¢ðØñ«}fÓ8‘3p·¤KQÏ=Ï=fŽæ:¹Šd…ÑÑ j®”¯*B>@*P–ÉËàqÖ]ã ‹"ò4ŠX•XçWÝÔ)wns¨˜è åÛ34B³Œ\ a8w™Ž¬ŠÆ=_E¯zý@B!WF.ºMh¨Tq,F•ªÃE««zjWš/óÑܦZ|Ž�ÞýazÞhÔ7H0…#­…÷æ"²–põé è�€Õïê+µõV»}Á„‚×6´dö—ª°™ëÑÜçð ïOO׬³°áÜ—æ&[_ñLXK¶)¯J¦×\ËÝ‚ÁyÞ8ÔÏaÝ!\oÚîßù­*‹?®.Q…iÀ—ÓýŒÀr¾ÐÞ¬A68TJh 'Š�I`<…ù€…+TßQK¸ çX»%»õÌ.Øã£s¾c\P}¥�*éÒ1=ÜÂ"A¢)Â�@D_ ׉³Égóà…”C(ÌÕ²µD½âgbzÂ��Uƒ–ËÌ.¤=y"Ø%<~.!< ¹¼åàJ3/^°¶ç”œ^kñ­¢€mUðJZ ào°_xPUnøô——F‡ý{æ øÎó˜;suB�í‚(YØì9ñ™fŽ€6)WþBà9XÅúKêê¥eJ¾æu)WjÐ=€øä僠*ÐÔ&f­È¥[®RÆ€xó3‘#»üJBÆøÖ#p`#O2üR€þ·UPõÄ hó*rÈ¡Vµ]&€Ò­æÙnÇ$åȾ�^ðÐ%eî¤-ò,Áu£¼mu|h}L\ÌJ³À…–4V2½%D€¸¼Þ?Ù‰Œ»sÌBm*²ûé*Z[ƒýÖcèÍ>Ã,ä÷WûƒΣb„ £ž>âE˜ Ó•ü15-J™ !w†Ð>â[ âU+U[Glî> ±ÝEªmâþì}�è.¼Ds\“¼�@h�€=S2СÎ:K“€Ùž jÒ· VÂÛ´ _7‡õ Õ^Rœm:Ë5èÖž—*–Uh0eª^âvR8]ÃHNzòZâtÞ²ºE¬9³)Aj) ùÜM}iF¹f5šé¯Ì²ª^œ³Ö;Q¥…Ò+€â³ŸÓNt²ºvpÇ$€Eи>â1åœ(¤üÀyc`åkGzÌ: r�Yñ1²h ­Ä³ê„ú[,ÍÍãÖÆ|L¥*„¯‘ž-Õ§~?RõÏ ¯WO0è©°ç2°ƒÖ®Yï¸(.,¿ÙíŽNƒõr`°¡°·KºXJÅ>e à8zʶ¢#%ës�N ýçâoÌ®Wâ Ý»µ‹tKY ÛÚ>2:Ì£|Ywq¢²é>¡E¤vÓS*[Ltf,8–Tö¢àÜ€/œT¬üÒìSîQkê]ÇÈw%Q¹Z+TÞîWAJ)Ýê™<úܤ*«+‘é2§jJí5:‹‹N/®åòTë»lË-AëB£†¡­¢(êïgR,»:€c“2Ô´ g{–ø:м„Ô°�[Ì^\ƒVÛKòŠU¼8w¢ë¼NªÅš,Ã8»g#á…H±/7äñœgæoHlí7ÌL¶XSÞ÷P¿âföaT¸â tƒHõ-€6Êœ›G>8½v¢ÛÛ2õŠÊv¯“Ÿø¶º°Ò[gXM«18©`|ªý£1Í»Lz¿ºË´0š=!M­ÚÔœöÀf ¥¡©¤P+¥Ë)RÚàB;xí(ôk¬ @wºðBèVSÓ´¸bò†ÛáñL¼‡˜²úšòÅ©Éà íóœF¤¶Õf·þÅœY€ uxó)ëñ _kª®orìÎ ÅvœJÿ9¢Þ ç ¼2Å@•`/¡“Ü`0c•uÌÂË’ùóƒY.‹þá³00i¿!ˆW+1oX."J¸å^F5ßà}q‚�]F6•°Xñ¸1T�4ò`b0X¢ëP}¸ æQ*ho—ù€·uÉÃRÓKV2ŠÏš+%WÜ 1Ѐ=ÿºBþå-U2zãæ, TÅrÔ°«—Áz�¡ÃÈwºþ‘  tV8é:„)L¢]ÖàAÐÐàõc¤Gpá_¹Z•)YRó}ÿÉCˆ7V5N1ÌZ®` ÍPè˘WP¸wOgæ4tÏœ>Z!tã€ÂFŇ`™ÎZÇ1 (ªy9+ÖÑæ lG¥â¼DÊS˜Í¦éŠ©|<›¸µhNÂ.ÕgæUÛ¶Ï0‚˜w«í,RUÞŠ�&yQLFýà—ãQrU|ß¿XÕ™®\b$©¼À‹.çq®PNkMýÂL`JWÄ 7ñ(Ò½9%öBØ„RÛaœa´ï¨Î¸Mÿw„&2ƒ°ˆiÖŽÒÈJÚs�_˜Ðˠ׎&[EIž«Æ%-Å*Ñn)†‚S|r¸øƒ-q†Âìtg¶båJÂ~em€Œß–vˆBõ”®ž|Aä>@u;8õ�)¡¸LÕV�$2TVçòE¼,*N~áãwr™d=’S˪­+©Ây™Û—Wƒ^#�–Ýôâ*K›ÛÇq”t8.UlÚ£]é73•: )®H°\^͇¨ÿ­|Ü ÁÇþÀˆ0âí> ×uÕ†'§Üúb€ Ö–ÅbçbHÃÚ[¸ô,²GTÈKê6 cÌURÝ»ÏK�kÒ¹#'™Äæ«4T¸Bêb Öz MSýQÙjòðF2D®àü@ "‡G̬ŠlQìBà¯uC°[éef��þæPÐU3Rñ™p£ƒj³ºûËIðÁÖÁ˘b¯­…=ãX;iVÌC€ª"H�øuUÞâyO§ bƒ;ü'XP§Y#]5˜§PE[Ñë¿Mœ¤²>]!kºu—m^…ö•l¨U¬‹ïØmÞŽã0 Ê`éï/+e …ë=á�äüÅŽõÁOû/(Ùñ½D/d+³,¡Yp^9— JSvt”¢ÆG|÷›´­%ž ¬Dus>ÑÀ5ÑÔ.‘†mW|µRµm‰~Äaª,ÚAZÜò�EÍq9ÐoˆäÊQ}ÖŠpÔìº/Ë«3̪Ƽ°¬yŠt/a|JÖ³#˜oÅ›*X ¡Eºyˆ¨[oTìıâ™K/qè’€i\zn^a[S`õ»ŠÀSÝV#?05mG!Õ¾¿ht4ÿØ €¦ä7~�ÔLÔ8ðp"F|²‚Vôsà‚nØçu×3ÒTØ¡õy¤{ºø�çIn�úÁÓñ¨?ìóÄBÛSMj²ú‹„K .é‡kw¹¡äí¿h“X¶Î7s=!-2§O‰IñK0λ‘A‹þb�¡¿yÄD¤Ú<Ì]{X¯JÅ&3 @TÀ0D`ÞJ©“.ŽÒ¤ê dy‚ôjÐôŒJ¶€zK´Ðy›¥%ƒWŽ’´I¼fêX¥.^Û¸K,VïdA£TÆÈ1Q †Ž;Ça�lë-Ûk‚&J|’„¦5–ÒÎkñ*ÈCEî9íÒíf!ˆ”n¤Òneúú#~HÅÈ¥rôëÇHgÑhn<º¹²Š…rðBJѦ§¼#Üz¨%ƒšÍÌÜÉ¢·-DX‡ßW·[�]UÔ}å'qÖÚˆ�) `–¢š\ÁY„UD(ö�iÝîÌC” ‰[UÊ(óU®²Ó¨ìu)mUææbaež±†ar¬x]ÜLÕ¯51údÎ ~›†–a&yßt@™Ñ‘¼Ã€9 •âÌU)ôálZAôe¢ò ªÃF1õ*²7¬oÞ/DÑŸŽlã£.;%Xo,"•Y|}s ,쇬ç÷sqÓ¬«»â‹óU©á˸’�–”=H›E–Bƒ* Â +úqÃ2”­X+c¢'° Òß4ó˜£Þ0ÝåÖ.®"ÑmãåëOèij4E� ïG,X)l7 ªV%S̲(zŽ%?¶ÆÐˆ«+ÀF§ŽÒŒòÅJ’ ·«å‡âbÛbXó©²Ë‰ EoÁÌ`Ñ)‡§ÿ]³ `œ<åæ1 j^©C[*®#â¢9±CR‹Ð¢®7A-iêÃ\ Ë’10O[¼Å &ô®ðl—‘5ÕŽðp»­¶UJ¹*# cY€×·e(<é÷�,½”ѦýWâc,1è¬_¾¡´E‚ŽõÕ…Ù“ÄuO#Cf^;ÇÄÁëÛQV³�Іîqb�ÜCMÌmkèî(yEj»¸Rbh¤ Ã$"Ùe®8`œ*-Ò«Wš¥ì?p«iÆ u³s"˜dø™‚¾eWGÒ$VÙ<ä–]ųO¼`£’ÍžE ‹ÊQ WÃ\Ë#A†•Ef–p«¼#~,(–Áan.‰DU_Œôø‹2—ð!ÿ)ž¥Â5û¶ºŽþaè!*ª¬‰ñESÈ<$b¨Z½1­t"£.±Eùo‹�Õ&¡`ÕéN¸š�˜¯]iéZ…™ð-õ€Ý¨Iã„þë Ü ª·ªJ^1â<ò`.Û‡•ݙ艎»‰ë[Xw©ÌÒ�˜‰”nÃðÁ¦,Ý*û˜“AFiÄ5¡l>ÑÇ Þ«0çƒ)Ô�£±mÖý%øƒ-q1(»]¢ú¥ Pç®zÌC“y” …í�W±ææ,ᘷ ¸?Ù�¥h}`¨i/¡ËÌfÇo„ðKT@A�©Z@"nÝúE¡Þ’Ó˜*BFéÓ´ "1E\ě汅 ѸG‚òô<@£Rë‘*YfQY:ª¥FCF¹eùä;g¤¾¥h°Y\JIe)\%ÛÒêŠ- {Dl§mî�šÍ”áÌoà�b<Õö‹°¡kô: EÙäéO1 £˜&îïÉU˜¹Ä MYó¨l™KÑ4ï`Η¸D¨èõŽfo§h>ÂáÀ é×0ÉÖÖ‚ár´•—0•£§µ3:Ý‹®±bËTžù„&Ø!z¶£q!:ÞÉÚù€-wÅo¯…ËýUFW„PXìq¾Ñʹ4Ñç´<“ä‰,Yö™âÝ�æ®d[|Ü4ìø‡�~¥K�`£n¥&–º‚ߘ^…Ÿ[ÄBÅÙÍ[¨¶Di·Ô ÕÑMoî Í€Ÿ'f£a =+Q”Y˜ìau*¡�îPl›Í·æPâT[ ·ÒY‰­ÑHŸPšÃ­:ˆY%àt\Ñg“t¡1ÎÀüFê\ýM¡É€½zA¡Ò%W }l‘ÀÕk0ˆí‘•n²ÃÅ8üº1»ÝU…8bÑ ~Y®úƒ”…Qx ÄüC7btñ2Ón›Ì]ÎÈ—–$ç_S…Fî ¡lô+UîÅB”©‡â5XÙ1åË´¿ïI…ZÙ§fûÆP·ÙßÅ»#kjÛpfÙaj—É‘™ÔéQh[+<Œ6èÞ˜òyÎB¼Á-H›g_IÚˆÑumuƒSUGé—l�í0E¯V>B¸(¶6£gºƒþ0X본ñ"œœ>9ô™Ð#ŽaÞwŒª¡—¼Eu ª£¼Sjo)ûÿŽ‘}Gˆ©ìá:\Á°ÐÝ¡¿8gÉXpUßE>=#Hò¨>~&ST Çlb>wD&ŽÑ:?1ún®fcþ² *Ž—ˆêò)ÊWH'š4íx‚©Ì5nŒv‡G{¤‡mSJ[Î猬n“PFÌç³(Ü´‹5'5aF&2 # Magick (7.1.1-26 Q16-HDRI) will create corrupt sixel files for very large # images, so resize if necessary. This will also convert to QIF, which is # a very simple image format - differences in loaders should affect the # quality minimally (as compared to e.g. JPEG), and loader overhead should be # a smaller proportion of overall resource usage (as compared to PNG), # resulting in a more direct comparison of the image conversion internals. magick convert -resize '10000000@>' "$ORIGINAL_FILE" "$PREPARED_FILE" # Write a courtesy PNG copy of the prepared file for easier viewing. magick convert "$PREPARED_FILE" "$PREPARED_FILE_PNG" # Chafa pads to the character cell size, so we need to crop that out. DIMENSIONS=$(magick identify -ping -format '%wx%h' "$PREPARED_FILE") # --- Run the converters --- # echo 'INFO: Running converters...' >&2 MAGICK_RES=$($TIME_CMD -f "%U %e %M" -- \ $MAGICK_CMD "$PREPARED_FILE" sixel:- 2>&1 >"$MAGICK_SIX_FILE") magick convert "$MAGICK_SIX_FILE" "$MAGICK_SIXPNG_FILE" IMG2SIXEL_RES=$($TIME_CMD -f "%U %e %M" -- \ $IMG2SIXEL_CMD "$PREPARED_FILE" 2>&1 >"$IMG2SIXEL_SIX_FILE") magick convert "$IMG2SIXEL_SIX_FILE" "$IMG2SIXEL_SIXPNG_FILE" IMG2SIXEL_HIGH_RES=$($TIME_CMD -f "%U %e %M" -- \ $IMG2SIXEL_CMD -I "$PREPARED_FILE" 2>&1 >"$IMG2SIXEL_HIGH_SIX_FILE") magick convert "$IMG2SIXEL_HIGH_SIX_FILE" "$IMG2SIXEL_HIGH_SIXPNG_FILE" CHAFA_W1_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 1 "$PREPARED_FILE" 2>&1 >"$CHAFA_W1_SIX_FILE") magick convert "$CHAFA_W1_SIX_FILE" "$CHAFA_W1_SIXPNG_FILE" CHAFA_W2_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 2 "$PREPARED_FILE" 2>&1 >"$CHAFA_W2_SIX_FILE") magick convert "$CHAFA_W2_SIX_FILE" "$CHAFA_W2_SIXPNG_FILE" CHAFA_W3_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 3 "$PREPARED_FILE" 2>&1 >"$CHAFA_W3_SIX_FILE") magick convert "$CHAFA_W3_SIX_FILE" "$CHAFA_W3_SIXPNG_FILE" CHAFA_W4_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 4 "$PREPARED_FILE" 2>&1 >"$CHAFA_W4_SIX_FILE") magick convert "$CHAFA_W4_SIX_FILE" "$CHAFA_W4_SIXPNG_FILE" CHAFA_W5_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 5 "$PREPARED_FILE" 2>&1 >"$CHAFA_W5_SIX_FILE") magick convert "$CHAFA_W5_SIX_FILE" "$CHAFA_W5_SIXPNG_FILE" CHAFA_W6_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 6 "$PREPARED_FILE" 2>&1 >"$CHAFA_W6_SIX_FILE") magick convert "$CHAFA_W6_SIX_FILE" "$CHAFA_W6_SIXPNG_FILE" CHAFA_W7_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 7 "$PREPARED_FILE" 2>&1 >"$CHAFA_W7_SIX_FILE") magick convert "$CHAFA_W7_SIX_FILE" "$CHAFA_W7_SIXPNG_FILE" CHAFA_W8_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 8 "$PREPARED_FILE" 2>&1 >"$CHAFA_W8_SIX_FILE") magick convert "$CHAFA_W8_SIX_FILE" "$CHAFA_W8_SIXPNG_FILE" CHAFA_W9_RES=$($TIME_CMD -f "%U %e %M" -- \ $CHAFA_CMD -w 9 "$PREPARED_FILE" 2>&1 >"$CHAFA_W9_SIX_FILE") magick convert "$CHAFA_W9_SIX_FILE" "$CHAFA_W9_SIXPNG_FILE" # --- Calculate and print metrics relative to prepared image --- # eval_file_metric () { # Magick will produce an additional normalized output for some metrics. # Remove it with 'cut' to avoid cluttering the table. magick compare -metric "$2" "$PREPARED_FILE" \ \( "$1" -crop "$DIMENSIONS"+0+0 +repage \) null: 2>&1 | \ cut -d ' ' -f 1 } count_file_colors () { # Count the colors in images to ensure the result is apples to apples. magick identify -format '%k' "$1" } echo 'INFO: Assessing output images...' >&2 echo >&2 echo "specimen ncolors MSE SSIM PSNR PAE utime elapsed peakrss" ORIGINAL_COLORS=$(count_file_colors "$ORIGINAL_FILE") ORIGINAL_MSE=$(eval_file_metric "$ORIGINAL_FILE" mse) ORIGINAL_SSIM=$(eval_file_metric "$ORIGINAL_FILE" ssim) ORIGINAL_PSNR=$(eval_file_metric "$ORIGINAL_FILE" psnr) ORIGINAL_PAE=$(eval_file_metric "$ORIGINAL_FILE" pae) echo "original $ORIGINAL_COLORS 0 1 0 0.0 0.0 0" PREPARED_COLORS=$(count_file_colors "$PREPARED_FILE") PREPARED_MSE=$(eval_file_metric "$PREPARED_FILE" mse) PREPARED_SSIM=$(eval_file_metric "$PREPARED_FILE" ssim) PREPARED_PSNR=$(eval_file_metric "$PREPARED_FILE" psnr) PREPARED_PAE=$(eval_file_metric "$PREPARED_FILE" pae) echo "prepared $PREPARED_COLORS 0 1 0 0.0 0.0 0" MAGICK_COLORS=$(count_file_colors "$MAGICK_SIX_FILE") MAGICK_MSE=$(eval_file_metric "$MAGICK_SIX_FILE" mse) MAGICK_SSIM=$(eval_file_metric "$MAGICK_SIX_FILE" ssim) MAGICK_PSNR=$(eval_file_metric "$MAGICK_SIX_FILE" psnr) MAGICK_PAE=$(eval_file_metric "$MAGICK_SIX_FILE" pae) echo "magick $MAGICK_COLORS $MAGICK_MSE $MAGICK_SSIM $MAGICK_PSNR $MAGICK_PAE $MAGICK_RES" IMG2SIXEL_COLORS=$(count_file_colors "$IMG2SIXEL_SIX_FILE") IMG2SIXEL_MSE=$(eval_file_metric "$IMG2SIXEL_SIX_FILE" mse) IMG2SIXEL_SSIM=$(eval_file_metric "$IMG2SIXEL_SIX_FILE" ssim) IMG2SIXEL_PSNR=$(eval_file_metric "$IMG2SIXEL_SIX_FILE" psnr) IMG2SIXEL_PAE=$(eval_file_metric "$IMG2SIXEL_SIX_FILE" pae) echo "img2sixel $IMG2SIXEL_COLORS $IMG2SIXEL_MSE $IMG2SIXEL_SSIM $IMG2SIXEL_PSNR $IMG2SIXEL_PAE $IMG2SIXEL_RES" IMG2SIXEL_HIGH_COLORS=$(count_file_colors "$IMG2SIXEL_HIGH_SIX_FILE") IMG2SIXEL_HIGH_MSE=$(eval_file_metric "$IMG2SIXEL_HIGH_SIX_FILE" mse) IMG2SIXEL_HIGH_SSIM=$(eval_file_metric "$IMG2SIXEL_HIGH_SIX_FILE" ssim) IMG2SIXEL_HIGH_PSNR=$(eval_file_metric "$IMG2SIXEL_HIGH_SIX_FILE" psnr) IMG2SIXEL_HIGH_PAE=$(eval_file_metric "$IMG2SIXEL_HIGH_SIX_FILE" pae) echo "img2sixel-high $IMG2SIXEL_HIGH_COLORS $IMG2SIXEL_HIGH_MSE $IMG2SIXEL_HIGH_SSIM $IMG2SIXEL_HIGH_PSNR $IMG2SIXEL_HIGH_PAE $IMG2SIXEL_HIGH_RES" CHAFA_W1_COLORS=$(count_file_colors "$CHAFA_W1_SIX_FILE") CHAFA_W1_MSE=$(eval_file_metric "$CHAFA_W1_SIX_FILE" mse) CHAFA_W1_SSIM=$(eval_file_metric "$CHAFA_W1_SIX_FILE" ssim) CHAFA_W1_PSNR=$(eval_file_metric "$CHAFA_W1_SIX_FILE" psnr) CHAFA_W1_PAE=$(eval_file_metric "$CHAFA_W1_SIX_FILE" pae) echo "chafa-w1 $CHAFA_W1_COLORS $CHAFA_W1_MSE $CHAFA_W1_SSIM $CHAFA_W1_PSNR $CHAFA_W1_PAE $CHAFA_W1_RES" CHAFA_W2_COLORS=$(count_file_colors "$CHAFA_W2_SIX_FILE") CHAFA_W2_MSE=$(eval_file_metric "$CHAFA_W2_SIX_FILE" mse) CHAFA_W2_SSIM=$(eval_file_metric "$CHAFA_W2_SIX_FILE" ssim) CHAFA_W2_PSNR=$(eval_file_metric "$CHAFA_W2_SIX_FILE" psnr) CHAFA_W2_PAE=$(eval_file_metric "$CHAFA_W2_SIX_FILE" pae) echo "chafa-w2 $CHAFA_W2_COLORS $CHAFA_W2_MSE $CHAFA_W2_SSIM $CHAFA_W2_PSNR $CHAFA_W2_PAE $CHAFA_W2_RES" CHAFA_W3_COLORS=$(count_file_colors "$CHAFA_W3_SIX_FILE") CHAFA_W3_MSE=$(eval_file_metric "$CHAFA_W3_SIX_FILE" mse) CHAFA_W3_SSIM=$(eval_file_metric "$CHAFA_W3_SIX_FILE" ssim) CHAFA_W3_PSNR=$(eval_file_metric "$CHAFA_W3_SIX_FILE" psnr) CHAFA_W3_PAE=$(eval_file_metric "$CHAFA_W3_SIX_FILE" pae) echo "chafa-w3 $CHAFA_W3_COLORS $CHAFA_W3_MSE $CHAFA_W3_SSIM $CHAFA_W3_PSNR $CHAFA_W3_PAE $CHAFA_W3_RES" CHAFA_W4_COLORS=$(count_file_colors "$CHAFA_W4_SIX_FILE") CHAFA_W4_MSE=$(eval_file_metric "$CHAFA_W4_SIX_FILE" mse) CHAFA_W4_SSIM=$(eval_file_metric "$CHAFA_W4_SIX_FILE" ssim) CHAFA_W4_PSNR=$(eval_file_metric "$CHAFA_W4_SIX_FILE" psnr) CHAFA_W4_PAE=$(eval_file_metric "$CHAFA_W4_SIX_FILE" pae) echo "chafa-w4 $CHAFA_W4_COLORS $CHAFA_W4_MSE $CHAFA_W4_SSIM $CHAFA_W4_PSNR $CHAFA_W4_PAE $CHAFA_W4_RES" CHAFA_W5_COLORS=$(count_file_colors "$CHAFA_W5_SIX_FILE") CHAFA_W5_MSE=$(eval_file_metric "$CHAFA_W5_SIX_FILE" mse) CHAFA_W5_SSIM=$(eval_file_metric "$CHAFA_W5_SIX_FILE" ssim) CHAFA_W5_PSNR=$(eval_file_metric "$CHAFA_W5_SIX_FILE" psnr) CHAFA_W5_PAE=$(eval_file_metric "$CHAFA_W5_SIX_FILE" pae) echo "chafa-w5 $CHAFA_W5_COLORS $CHAFA_W5_MSE $CHAFA_W5_SSIM $CHAFA_W5_PSNR $CHAFA_W5_PAE $CHAFA_W5_RES" CHAFA_W6_COLORS=$(count_file_colors "$CHAFA_W6_SIX_FILE") CHAFA_W6_MSE=$(eval_file_metric "$CHAFA_W6_SIX_FILE" mse) CHAFA_W6_SSIM=$(eval_file_metric "$CHAFA_W6_SIX_FILE" ssim) CHAFA_W6_PSNR=$(eval_file_metric "$CHAFA_W6_SIX_FILE" psnr) CHAFA_W6_PAE=$(eval_file_metric "$CHAFA_W6_SIX_FILE" pae) echo "chafa-w6 $CHAFA_W6_COLORS $CHAFA_W6_MSE $CHAFA_W6_SSIM $CHAFA_W6_PSNR $CHAFA_W6_PAE $CHAFA_W6_RES" CHAFA_W7_COLORS=$(count_file_colors "$CHAFA_W7_SIX_FILE") CHAFA_W7_MSE=$(eval_file_metric "$CHAFA_W7_SIX_FILE" mse) CHAFA_W7_SSIM=$(eval_file_metric "$CHAFA_W7_SIX_FILE" ssim) CHAFA_W7_PSNR=$(eval_file_metric "$CHAFA_W7_SIX_FILE" psnr) CHAFA_W7_PAE=$(eval_file_metric "$CHAFA_W7_SIX_FILE" pae) echo "chafa-w7 $CHAFA_W7_COLORS $CHAFA_W7_MSE $CHAFA_W7_SSIM $CHAFA_W7_PSNR $CHAFA_W7_PAE $CHAFA_W7_RES" CHAFA_W8_COLORS=$(count_file_colors "$CHAFA_W8_SIX_FILE") CHAFA_W8_MSE=$(eval_file_metric "$CHAFA_W8_SIX_FILE" mse) CHAFA_W8_SSIM=$(eval_file_metric "$CHAFA_W8_SIX_FILE" ssim) CHAFA_W8_PSNR=$(eval_file_metric "$CHAFA_W8_SIX_FILE" psnr) CHAFA_W8_PAE=$(eval_file_metric "$CHAFA_W8_SIX_FILE" pae) echo "chafa-w8 $CHAFA_W8_COLORS $CHAFA_W8_MSE $CHAFA_W8_SSIM $CHAFA_W8_PSNR $CHAFA_W8_PAE $CHAFA_W8_RES" CHAFA_W9_COLORS=$(count_file_colors "$CHAFA_W9_SIX_FILE") CHAFA_W9_MSE=$(eval_file_metric "$CHAFA_W9_SIX_FILE" mse) CHAFA_W9_SSIM=$(eval_file_metric "$CHAFA_W9_SIX_FILE" ssim) CHAFA_W9_PSNR=$(eval_file_metric "$CHAFA_W9_SIX_FILE" psnr) CHAFA_W9_PAE=$(eval_file_metric "$CHAFA_W9_SIX_FILE" pae) echo "chafa-w9 $CHAFA_W9_COLORS $CHAFA_W9_MSE $CHAFA_W9_SSIM $CHAFA_W9_PSNR $CHAFA_W9_PAE $CHAFA_W9_RES" chafa-1.18.2/tests/term-info-test.c000066400000000000000000000236651517447374300170630ustar00rootroot00000000000000#include "config.h" #include #include #include static void formatting_test (void) { ChafaTermInfo *ti; gchar buf [CHAFA_TERM_SEQ_LENGTH_MAX * 14 + 1]; gchar *out = buf; ti = chafa_term_info_new (); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT, "soft-reset", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_CURSOR_UP, "cursor-up-%1", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_CURSOR_TO_POS, "%1-cursor-to-pos-%2", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT, "%1%2-fg-direct-%3", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_BG_DIRECT, "%1-bg-direct%2%3-", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_FGBG_DIRECT, "%1%2-fgbg-%3,%4%5-%6", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_FG_16, "aix%1,", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_BG_16, "aix%1,", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_FGBG_16, "aix-%1-%2,", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, "def-fg-%1-%2-%3,", NULL); chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_BG, "def-bg-%1-%2-%3,", NULL); out = chafa_term_info_emit_reset_terminal_soft (ti, out); out = chafa_term_info_emit_cursor_up (ti, out, 9876); out = chafa_term_info_emit_cursor_to_pos (ti, out, 1234, 0); out = chafa_term_info_emit_set_color_fg_direct (ti, out, 41, 0, 244); out = chafa_term_info_emit_set_color_bg_direct (ti, out, 0, 100, 99); out = chafa_term_info_emit_set_color_fgbg_direct (ti, out, 1, 199, 99, 0, 0, 9); out = chafa_term_info_emit_set_color_fg_16 (ti, out, 0); out = chafa_term_info_emit_set_color_fg_16 (ti, out, 8); out = chafa_term_info_emit_set_color_bg_16 (ti, out, 0); out = chafa_term_info_emit_set_color_bg_16 (ti, out, 8); out = chafa_term_info_emit_set_color_fgbg_16 (ti, out, 0, 0); out = chafa_term_info_emit_set_color_fgbg_16 (ti, out, 8, 8); out = chafa_term_info_emit_set_default_fg (ti, out, 0xffff, 0x0000, 0x1234); out = chafa_term_info_emit_set_default_bg (ti, out, 0x1234, 0xffff, 0x0000); *out = '\0'; chafa_term_info_unref (ti); g_assert_cmpstr (buf, ==, "soft-reset" "cursor-up-9876" "1235-cursor-to-pos-1" "410-fg-direct-244" "0-bg-direct10099-" "1199-fgbg-99,00-9" "aix30," "aix90," "aix40," "aix100," "aix-30-40," "aix-90-100," "def-fg-ffff-0000-1234," "def-bg-1234-ffff-0000,"); } static void dynamic_test (void) { ChafaTermInfo *ti; gchar buf [CHAFA_TERM_SEQ_LENGTH_MAX + 1]; gchar *out = buf; gchar *dyn; ti = chafa_term_info_new (); /* No args */ chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT, "reset-soft", NULL); out = chafa_term_info_emit_reset_terminal_soft (ti, buf); *out = '\0'; dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_RESET_TERMINAL_SOFT, -1); g_assert_cmpstr (buf, ==, dyn); g_free (dyn); /* 8-bit args */ chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT, "%1%2-fg-direct-%3", NULL); out = chafa_term_info_emit_set_color_fg_direct (ti, buf, 0xff, 0x00, 0x12); *out = '\0'; dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_COLOR_FG_DIRECT, 0xff, 0x00, 0x12, -1); g_assert_cmpstr (buf, ==, dyn); g_free (dyn); /* uint args */ chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_CURSOR_TO_POS, "%1-cursor-to-pos-%2", NULL); out = chafa_term_info_emit_cursor_to_pos (ti, buf, 100000, 200000); *out = '\0'; dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_CURSOR_TO_POS, 100000, 200000, -1); g_assert_cmpstr (buf, ==, dyn); g_free (dyn); /* 16-bit hex args */ chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, "def-fg-%1-%2-%3,", NULL); out = chafa_term_info_emit_set_default_fg (ti, buf, 0xffff, 0x0000, 0x1234); *out = '\0'; dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, 0xffff, 0x0000, 0x1234, -1); g_assert_cmpstr (buf, ==, dyn); g_free (dyn); /* Arg out of range */ dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, 0xffff, 0x10000, 0x1234, 0, -1); g_assert (dyn == NULL); /* Too many args */ dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, 0xffff, 0x0000, 0x1234, 0, -1); g_assert (dyn == NULL); /* Too few args */ dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, 0xffff, 0x0000, -1); g_assert (dyn == NULL); /* Too few (zero) args */ dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, -1); g_assert (dyn == NULL); chafa_term_info_unref (ti); } static void parsing_test (void) { ChafaTermInfo *ti; gchar *dyn; gint dyn_len; gchar *p; guint args [CHAFA_TERM_SEQ_ARGS_MAX]; gint n_args; ChafaParseResult result; gboolean r; guint i; ti = chafa_term_info_new (); /* Define and emit */ r = chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, "def-fg-%1-%2-%3,", NULL); g_assert (r == TRUE); dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, 0xffff, 0x0000, 0x1234, -1); /* Parse success */ p = dyn; dyn_len = strlen (dyn); result = chafa_term_info_parse_seq_varargs (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, &p, &dyn_len, args, &n_args); g_assert (result == CHAFA_PARSE_SUCCESS); g_assert (n_args == 3); g_assert (args [0] == 0xffff); g_assert (args [1] == 0x0000); g_assert (args [2] == 0x1234); /* Not enough data */ for (i = 0; i < strlen (dyn); i++) { p = dyn; dyn_len = i; result = chafa_term_info_parse_seq_varargs (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, &p, &dyn_len, args, &n_args); g_assert (result == CHAFA_PARSE_AGAIN); } /* Parse failure */ p = dyn + 1; dyn_len = strlen (dyn) - 1; result = chafa_term_info_parse_seq_varargs (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, &p, &dyn_len, args, &n_args); g_assert (result == CHAFA_PARSE_FAILURE); g_free (dyn); chafa_term_info_unref (ti); } G_GNUC_BEGIN_IGNORE_DEPRECATIONS static void parsing_legacy_test (void) { ChafaTermInfo *ti; gchar *dyn; gint dyn_len; gchar *p; guint args [CHAFA_TERM_SEQ_ARGS_MAX]; ChafaParseResult result; gboolean r; guint i; ti = chafa_term_info_new (); /* Define and emit */ r = chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, "def-fg-%1-%2-%3,", NULL); g_assert (r == TRUE); dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, 0xffff, 0x0000, 0x1234, -1); /* Parse success */ p = dyn; dyn_len = strlen (dyn); result = chafa_term_info_parse_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, &p, &dyn_len, args); g_assert (result == CHAFA_PARSE_SUCCESS); g_assert (args [0] == 0xffff); g_assert (args [1] == 0x0000); g_assert (args [2] == 0x1234); /* Not enough data */ for (i = 0; i < strlen (dyn); i++) { p = dyn; dyn_len = i; result = chafa_term_info_parse_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, &p, &dyn_len, args); g_assert (result == CHAFA_PARSE_AGAIN); } /* Parse failure */ p = dyn + 1; dyn_len = strlen (dyn) - 1; result = chafa_term_info_parse_seq (ti, CHAFA_TERM_SEQ_SET_DEFAULT_FG, &p, &dyn_len, args); g_assert (result == CHAFA_PARSE_FAILURE); g_free (dyn); chafa_term_info_unref (ti); } G_GNUC_END_IGNORE_DEPRECATIONS static void parsing_varargs_test (void) { ChafaTermInfo *ti; gchar *dyn; gint dyn_len; gchar *p; guint args [CHAFA_TERM_SEQ_ARGS_MAX]; gint n_args; ChafaParseResult result; gboolean r; guint i; ti = chafa_term_info_new (); /* Define and emit */ r = chafa_term_info_set_seq (ti, CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES, "attr-%v,", NULL); g_assert (r == TRUE); dyn = chafa_term_info_emit_seq (ti, CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES, 0xff, 0x0000, 0x1234, -1); g_assert (strcmp (dyn, "attr-255;0;4660,") == 0); /* Parse success */ p = dyn; dyn_len = strlen (dyn); result = chafa_term_info_parse_seq_varargs (ti, CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES, &p, &dyn_len, args, &n_args); g_assert (result == CHAFA_PARSE_SUCCESS); g_assert (n_args == 3); g_assert (args [0] == 0xff); g_assert (args [1] == 0x0000); g_assert (args [2] == 0x1234); /* Not enough data */ for (i = 0; i < strlen (dyn); i++) { p = dyn; dyn_len = i; result = chafa_term_info_parse_seq_varargs (ti, CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES, &p, &dyn_len, args, &n_args); g_assert (result == CHAFA_PARSE_AGAIN); } /* Parse failure */ p = dyn + 1; dyn_len = strlen (dyn) - 1; result = chafa_term_info_parse_seq_varargs (ti, CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES, &p, &dyn_len, args, &n_args); g_assert (result == CHAFA_PARSE_FAILURE); g_free (dyn); chafa_term_info_unref (ti); } int main (int argc, char *argv []) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/term-info/formatting", formatting_test); g_test_add_func ("/term-info/dynamic", dynamic_test); g_test_add_func ("/term-info/parsing", parsing_test); g_test_add_func ("/term-info/parsing-legacy", parsing_legacy_test); g_test_add_func ("/term-info/parsing-varargs", parsing_varargs_test); return g_test_run (); } chafa-1.18.2/tests/test-driver.sh000077500000000000000000000116451517447374300166440ustar00rootroot00000000000000#! /bin/sh # test-driver - basic testsuite driver script. scriptversion=2018-03-07.03; # UTC # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # Make unconditional expansion of undefined variables an error. This # helps a lot in preventing typo-related bugs. set -u usage_error () { echo "$0: $*" >&2 print_usage >&2 exit 2 } print_usage () { cat <"$log_file" "$@" >>"$log_file" 2>&1 estatus=$? if test $enable_hard_errors = no && test $estatus -eq 99; then tweaked_estatus=1 else tweaked_estatus=$estatus fi case $tweaked_estatus:$expect_failure in 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; 0:*) col=$grn res=PASS recheck=no gcopy=no;; 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; *:*) col=$red res=FAIL recheck=yes gcopy=yes;; esac # Report the test outcome and exit status in the logs, so that one can # know whether the test passed or failed simply by looking at the '.log' # file, without the need of also peaking into the corresponding '.trs' # file (automake bug#11814). echo "$res $test_name (exit status: $estatus)" >>"$log_file" # Report outcome to console. echo "${col}${res}${std}: $test_name" # Chafa-specific: On error, print log file to console. if test $estatus != 0; then cat "$log_file" fi # Register the test result, and other relevant metadata. echo ":test-result: $res" > $trs_file echo ":global-test-result: $res" >> $trs_file echo ":recheck: $recheck" >> $trs_file echo ":copy-in-global-log: $gcopy" >> $trs_file # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: chafa-1.18.2/tools/000077500000000000000000000000001517447374300140245ustar00rootroot00000000000000chafa-1.18.2/tools/Makefile.am000066400000000000000000000000441517447374300160560ustar00rootroot00000000000000SUBDIRS = chafa fontgen completions chafa-1.18.2/tools/chafa/000077500000000000000000000000001517447374300150665ustar00rootroot00000000000000chafa-1.18.2/tools/chafa/.gitignore000066400000000000000000000000071517447374300170530ustar00rootroot00000000000000/chafa chafa-1.18.2/tools/chafa/LICENSE.qoi000066400000000000000000000020631517447374300166630ustar00rootroot00000000000000MIT License Copyright (c) 2022 Dominic Szablewski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. chafa-1.18.2/tools/chafa/Makefile.am000066400000000000000000000057071517447374300171330ustar00rootroot00000000000000if WANT_TOOLS bin_PROGRAMS = \ chafa chafa_SOURCES = \ chafa.c \ chafa-byte-fifo.c \ chafa-byte-fifo.h \ chafa-parser.c \ chafa-parser.h \ chafa-stream-reader.c \ chafa-stream-reader.h \ chafa-stream-writer.c \ chafa-stream-writer.h \ chafa-term.c \ chafa-term.h \ chafa-wakeup.c \ chafa-wakeup.h \ chicle-file-mapping.c \ chicle-file-mapping.h \ chicle-font-loader.c \ chicle-font-loader.h \ chicle-gif-loader.c \ chicle-gif-loader.h \ chicle-grid-layout.c \ chicle-grid-layout.h \ chicle-media-loader.c \ chicle-media-loader.h \ chicle-media-pipeline.c \ chicle-media-pipeline.h \ chicle-options.c \ chicle-options.h \ chicle-path-queue.c \ chicle-path-queue.h \ chicle-placement-counter.c \ chicle-placement-counter.h \ chicle-png-loader.c \ chicle-png-loader.h \ chicle-named-colors.c \ chicle-named-colors.h \ qoi.h \ chicle-qoi-loader.c \ chicle-qoi-loader.h \ chicle-util.c \ chicle-util.h \ chicle-xwd-loader.c \ chicle-xwd-loader.h if HAVE_AVIF chafa_SOURCES += \ chicle-avif-loader.c \ chicle-avif-loader.h endif if HAVE_HEIF chafa_SOURCES += \ chicle-heif-loader.c \ chicle-heif-loader.h endif if HAVE_JPEG chafa_SOURCES += \ chicle-jpeg-loader.c \ chicle-jpeg-loader.h endif if HAVE_TIFF chafa_SOURCES += \ chicle-tiff-loader.c \ chicle-tiff-loader.h endif if HAVE_SVG chafa_SOURCES += \ chicle-svg-loader.c \ chicle-svg-loader.h endif if HAVE_WEBP chafa_SOURCES += \ chicle-webp-loader.c \ chicle-webp-loader.h endif if HAVE_JXL chafa_SOURCES += \ chicle-jxl-loader.c \ chicle-jxl-loader.h endif if HAVE_COREGRAPHICS chafa_SOURCES += \ chicle-coregraphics-loader.c \ chicle-coregraphics-loader.h endif # We can pass -rpath so the binary knows where to find libchafa.so when # installed outside /usr (e.g. the default /usr/local). This affects Ubuntu. # Resolved by running ldconfig. See Github issue #32. # # This is disabled by default. chafa_CFLAGS = $(CHAFA_CFLAGS) $(GLIB_CFLAGS) $(JPEG_CFLAGS) $(SVG_CFLAGS) $(TIFF_CFLAGS) $(WEBP_CFLAGS) $(JXL_CFLAGS) $(AVIF_CFLAGS) $(HEIF_CFLAGS) $(FREETYPE_CFLAGS) $(COREGRAPHICS_CFLAGS) if ENABLE_RPATH chafa_LDFLAGS = $(CHAFA_LDFLAGS) -rpath $(libdir) endif chafa_LDADD = $(GLIB_LIBS) $(JPEG_LIBS) $(SVG_LIBS) $(TIFF_LIBS) $(WEBP_LIBS) $(JXL_LIBS) $(AVIF_LIBS) $(HEIF_LIBS) $(COREGRAPHICS_LIBS) $(FREETYPE_LIBS) $(top_builddir)/chafa/libchafa.la $(top_builddir)/libnsgif/libnsgif.la $(top_builddir)/lodepng/liblodepng.la -lm $(WIN32_LDADD) # On Microsoft Windows, we compile a resource file with windres and link it in. # This enables UTF-8 support in filenames, environment variables, etc. if IS_WIN32_BUILD WIN32_LDADD = manifest.o manifest.o: $(srcdir)/manifest.rc $(WINDRES) -o $@ $(srcdir)/manifest.rc else WIN32_LDADD = endif endif ## --- General --- ## Include $(top_builddir)/chafa to get generated chafaconfig.h. AM_CPPFLAGS = \ -I$(top_srcdir)/chafa \ -I$(top_builddir)/chafa \ -I$(top_srcdir)/libnsgif \ -I$(top_srcdir)/lodepng EXTRA_DIST = manifest.rc ms-utf8.xml chafa-1.18.2/tools/chafa/c64-platform.c000066400000000000000000000165331517447374300174600ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #define UNICODE_UNDEF 0 typedef struct { gint c; gunichar u; } CodeMap; /* It's better to keep a single entry per line, since it leaves room for annotation. * Also, maintaining tabular layouts is a pita even when we don't have out-there * Unicode characters messing up the formatting (which, in this case, we do). */ static const CodeMap c64_unshifted_pseudo_codes [] = { /* 0-127 */ { 0, '@' }, { 1, 'A' }, { 2, 'B' }, { 3, 'C' }, { 4, 'D' }, { 5, 'E' }, { 6, 'F' }, { 7, 'G' }, { 8, 'H' }, { 9, 'I' }, { 10, 'J' }, { 11, 'K' }, { 12, 'L' }, { 13, 'M' }, { 14, 'N' }, { 15, 'O' }, { 16, 'P' }, { 17, 'Q' }, { 18, 'R' }, { 19, 'S' }, { 20, 'T' }, { 21, 'U' }, { 22, 'V' }, { 23, 'W' }, { 24, 'X' }, { 25, 'Y' }, { 26, 'Z' }, { 27, '[' }, { 28, 0xa3 }, /* £ pound symbol*/ { 29, ']' }, { 30, 0x2191 }, /* ↑ up arrow */ { 31, 0x2190 }, /* â†� left arrow */ { 32, ' ' }, { 33, '!' }, { 34, '"' }, { 35, '#' }, { 36, '$' }, { 37, '%' }, { 38, '&' }, { 39, '\'' }, { 40, '(' }, { 41, ')' }, { 42, '*' }, { 43, '+' }, { 44, ',' }, { 45, '-' }, { 46, '.' }, { 47, '/' }, { 48, '0' }, { 49, '1' }, { 50, '2' }, { 51, '3' }, { 52, '4' }, { 53, '5' }, { 54, '6' }, { 55, '7' }, { 56, '8' }, { 57, '9' }, { 58, ':' }, { 59, ';' }, { 60, '<' }, { 61, '=' }, { 62, '>' }, { 63, '?' }, { 64, 0x2500 }, /* ─ horizontal box drawing line */ { 65, 0x2660 }, /* â™  black spade suit */ { 66, 0x2502 }, /* │ vertical 1/8 block 4 */ { 67, 0x1fb79 }, /* 🭹 horizontal 1/8 block 5 */ { 68, 0x1fb78 }, /* 🭸 horizontal 1/8 block 4 */ { 69, 0x1fb77 }, /* 🭷 horizontal 1/8 block 3 */ { 70, 0x1fb7a }, /* 🭶 horizontal 1/8 block 6 */ { 71, 0x1fb71 }, /* 🭱 vertical 1/8 block 3 */ { 72, 0x1fb73 }, /* 🭳 vertical 1/8 block 5 */ { 73, 0x256e }, /* â•® left-bottom arc connector */ { 74, 0x2570 }, /* â•° right-top arc connector */ { 75, 0x256f }, /* ╯ left-top arc connector */ { 76, 0x1fb7c }, /* 🭼 left and lower one-eight corner */ { 77, 0x2572 }, /* ╲ box drawing light diagonal UL to LR */ { 78, 0x2571 }, /* ╱ box drawing light diagonal UR to LL */ { 79, 0x1fb7d }, /* 🭽 left and upper one-eight corner */ { 80, 0x1fb7e }, /* 🭾 right and upper one-eight corner */ { 81, 0x25cf }, /* â—� black circle */ { 82, 0x1fb7b }, /* 🭻 horizontal 1/8 block 7 */ { 83, 0x2665 }, /* ♥ black heart suit */ { 84, 0x1fb70 }, /* 🭰 vertical 1/8 block 2 */ { 85, 0x256d }, /* â•­ right-bottom arc connector */ { 86, 0x2573 }, /* ╳ box drawing light cross */ { 87, 0x25cb }, /* â—‹ white circle */ { 88, 0x2663 }, /* ♣ black club suit */ { 89, 0x1fb75 }, /* 🭵 vertical 1/8 block 7 */ { 90, 0x2666 }, /* ♦ black diamond suit */ { 91, 0x253c }, /* ┼ box drawing light vertical and horizontal */ { 92, 0x1fb8c }, /* 🮌 left half medium shade (kinda) */ { 93, 0x2502 }, /* │ vertical box drawing line */ { 94, 0x03c0 }, /* Ï€ greek small letter Pi */ { 95, 0x25e5 }, /* â—¥ black upper right triangle */ { 96, ' ' }, /* looks like a space (identical to #32) */ { 97, 0x258c }, /* â–Œ left half block */ { 98, 0x2584 }, /* â–„ lower half block */ { 99, 0x23ba }, /* ⎺ horizontal scan line 1 (upper) */ { 100, 0x23bd }, /* ⎽ horizontal scan line 9 (lower) */ { 101, 0x258f }, /* â–� left 1/8 block */ { 102, 0x1fb95 }, /* 🮕 checker board fill */ { 103, 0x2595 }, /* â–• right 1/8 block */ { 104, 0x1fb8f }, /* ðŸ®� lower half medium shade (kinda) */ { 105, 0x25e4 }, /* â—¤ black upper left triangle */ { 106, 0x2595 }, /* â–• right 1/8 block (identical to #103) */ { 107, 0x251c }, /* ├ box drawing light vertical and right */ { 108, 0x2597 }, /* â–— quadrant lower right */ { 109, 0x2514 }, /* â”” box drawing light up and right */ { 110, 0x2510 }, /* â”� box drawing light down and left */ { 111, 0x2581 }, /* â–� lower 1/8 block */ { 112, 0x250c }, /* ┌ box drawing light down and right */ { 113, 0x2534 }, /* â”´ box drawing light up and horizontal */ { 114, 0x252c }, /* ┬ box drawing light down and horizontal */ { 115, 0x2524 }, /* ┤ box drawing light vertical and left */ { 116, 0x258f }, /* â–� left 1/8 block (identical to #101) */ { 117, 0x258e }, /* â–Ž left 1/4 block */ { 118, 0x1fb87 }, /* 🮇 right 1/4 block */ { 119, 0x2594 }, /* â–” upper 1/8 block */ { 120, 0x1fb82 }, /* 🮂 upper 1/4 block */ { 121, 0x2582 }, /* â–‚ lower 1/4 block */ { 122, 0x1fb7f }, /* 🭿 right and lower 1/8 corner */ { 123, 0x2596 }, /* â–– quadrant lower left */ { 124, 0x259d }, /* â–� quadrant upper right */ { 125, 0x2518 }, /* ┘ box drawing light up and left */ { 126, 0x2598 }, /* â–˜ quadrant upper left */ { 127, 0x259a }, /* â–š quadrant upper left and lower right */ /* Chars 128-255 are inverted versions of 0-127. Some of them make sense * as plain characters too. We list those here. */ { 160, 0x2588 }, /* â–ˆ full block */ { 214, 0x1fbbd }, /* 🮽 negative diagonal cross */ { 220, 0x1fb94 }, /* 🮔 left medium half inverse medium shade and right half block (kinda) */ { 223, 0x25e3 }, /* â—£ black lower left triangle */ { 225, 0x2590 }, /* â–� right half block */ { 226, 0x2580 }, /* â–€ upper half block */ { 229, 0x1fb8b }, /* 🮋 right 7/8 block */ { 230, 0x1fb96 }, /* 🮖 inverse checker board fill */ { 231, 0x2589 }, /* â–‰ left 7/8 block */ { 232, 0x1fb91 }, /* 🮑 upper half block and lower half inverse medium shade (kinda) */ { 233, 0x25e2 }, /* â—¢ black lower right triangle */ { 234, 0x2589 }, /* â–‰ left 7/8 block, (identical to #231) */ { 236, 0x259b }, /* â–› quadrant UL and UR and LL */ { 239, 0x1fb86 }, /* 🮆 upper 7/8 block */ { 244, 0x1fb8b }, /* 🮋 right 7/8 block (identical to #229) */ { 245, 0x1fb8a }, /* 🮊 right 3/4 block */ { 246, 0x258a }, /* â–Š left 3/4 block */ { 247, 0x2587 }, /* â–‡ lower 7/8 block */ { 248, 0x2586 }, /* â–† lower 3/4 block */ { 249, 0x1fb85 }, /* 🮅 upper 3/4 block */ { 251, 0x259c }, /* â–œ quadrant UL and UR and LR */ { 252, 0x2599 }, /* â–™ quadrant UL and LL and LR */ { 254, 0x259f }, /* â–Ÿ quadrant UR and LL and LR */ { 255, 0x259e }, /* â–ž quadrant upper right and lower left */ { -1, 0 } }; chafa-1.18.2/tools/chafa/chafa-byte-fifo.c000066400000000000000000000231301517447374300201550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include "chafa-byte-fifo.h" #define BUFFER_SIZE_MAX 16384 typedef struct Buffer Buffer; struct Buffer { Buffer *next, *prev; gint ofs, len; guchar data [BUFFER_SIZE_MAX]; }; struct ChafaByteFifo { Buffer *buf_head, *buf_tail; /* Stream position of first byte. Starts at 0. Increased by _pop(). */ gint64 pos; /* Number of bytes in FIFO. */ gint len; }; static void enqueue (ChafaByteFifo *fifo, gconstpointer src, gint src_len) { const guchar *src_bytes = src; gint n; fifo->len += src_len; if (fifo->buf_tail) { n = MIN (src_len, BUFFER_SIZE_MAX - (fifo->buf_tail->ofs + fifo->buf_tail->len)); memcpy (&fifo->buf_tail->data [fifo->buf_tail->ofs + fifo->buf_tail->len], src_bytes, n); fifo->buf_tail->len += n; src_bytes += n; src_len -= n; } while (src_len > 0) { Buffer *new_buf = g_new0 (Buffer, 1); if (!fifo->buf_head) { fifo->buf_head = fifo->buf_tail = new_buf; } else { fifo->buf_tail->next = new_buf; new_buf->prev = fifo->buf_tail; fifo->buf_tail = new_buf; } n = MIN (src_len, BUFFER_SIZE_MAX); memcpy (fifo->buf_tail->data, src_bytes, n); src_bytes += n; src_len -= n; fifo->buf_tail->len = n; } } /* dest can be NULL */ static gint dequeue (ChafaByteFifo *fifo, gpointer dest, gint dest_len) { guchar *dest_bytes = dest; Buffer *b; gint result_len; gint n; result_len = dest_len = MIN (dest_len, fifo->len); for (b = fifo->buf_head; dest_len > 0; ) { n = MIN (dest_len, b->len); dest_len -= n; if (dest_bytes) { memcpy (dest_bytes, b->data + b->ofs, n); dest_bytes += n; } b->ofs += n; b->len -= n; if (b->len == 0) { g_assert (b->prev == NULL); fifo->buf_head = b->next; g_free (b); b = fifo->buf_head; if (b) b->prev = NULL; } } fifo->len -= result_len; if (fifo->len == 0) fifo->buf_tail = NULL; fifo->pos += result_len; return result_len; } static gint fifo_search (ChafaByteFifo *fifo, gconstpointer data, gint data_len, gint64 *pos) { Buffer *b, *match_b; const guint8 *data_u8 = data; gint data_ofs = 0; gint64 ofs = 0; gint64 buf_ofs; gint64 match_ofs, match_buf_ofs; gint result = -1; for (b = fifo->buf_head; b; b = b->next) { if (*pos < fifo->pos + ofs + b->len) break; ofs += b->len; } if (!b) goto out; buf_ofs = match_buf_ofs = *pos - (fifo->pos + ofs); match_b = b; match_ofs = ofs; for ( ; b; b = b->next) { for ( ; buf_ofs < b->len; buf_ofs++) { if (fifo->len - (ofs + buf_ofs) < data_len - data_ofs) { *pos = fifo->pos + ofs + buf_ofs; goto out; } if (data_u8 [data_ofs] == b->data [b->ofs + buf_ofs]) { if (data_ofs == 0) { match_b = b; match_ofs = ofs; match_buf_ofs = buf_ofs; } data_ofs++; if (data_ofs == data_len) { *pos = fifo->pos + match_ofs + match_buf_ofs; result = match_ofs + match_buf_ofs; goto out; } } else if (data_ofs > 0) { data_ofs = 0; b = match_b; ofs = match_ofs; buf_ofs = match_buf_ofs; } } ofs += b->len; buf_ofs = 0; } out: return result; } ChafaByteFifo * chafa_byte_fifo_new (void) { ChafaByteFifo *fifo; fifo = g_new0 (ChafaByteFifo, 1); return fifo; } void chafa_byte_fifo_destroy (ChafaByteFifo *byte_fifo) { g_return_if_fail (byte_fifo != NULL); g_free (byte_fifo); } gint64 chafa_byte_fifo_get_pos (ChafaByteFifo *byte_fifo) { g_return_val_if_fail (byte_fifo != NULL, 0); return byte_fifo->pos; } gint chafa_byte_fifo_get_len (ChafaByteFifo *byte_fifo) { g_return_val_if_fail (byte_fifo != NULL, 0); return byte_fifo->len; } void chafa_byte_fifo_push (ChafaByteFifo *byte_fifo, gconstpointer src, gint src_len) { g_return_if_fail (byte_fifo != NULL); enqueue (byte_fifo, src, src_len); } gint chafa_byte_fifo_pop (ChafaByteFifo *byte_fifo, gpointer dest, gint dest_len) { g_return_val_if_fail (byte_fifo != NULL, 0); return dequeue (byte_fifo, dest, dest_len); } gconstpointer chafa_byte_fifo_peek (ChafaByteFifo *byte_fifo, gint *len) { Buffer *b; g_return_val_if_fail (byte_fifo != NULL, NULL); g_return_val_if_fail (len != NULL, NULL); *len = 0; if (byte_fifo->len == 0) return NULL; g_assert (byte_fifo->buf_head != NULL); for (b = byte_fifo->buf_head; ; b = b->next) { if (b->len > 0) { *len = b->len; return b->data + b->ofs; } } g_assert_not_reached (); return NULL; } gint chafa_byte_fifo_drop (ChafaByteFifo *byte_fifo, gint len) { g_return_val_if_fail (byte_fifo != NULL, 0); return dequeue (byte_fifo, NULL, len); } gint chafa_byte_fifo_search (ChafaByteFifo *byte_fifo, gconstpointer data, gint data_len, gint64 *restart_pos) { gint64 dummy_pos; g_return_val_if_fail (byte_fifo != NULL, -1); g_return_val_if_fail (data != NULL, -1); g_return_val_if_fail (data_len >= 0, -1); if (data_len == 0) return 0; if (!restart_pos) { dummy_pos = byte_fifo->pos; restart_pos = &dummy_pos; } else if (*restart_pos < byte_fifo->pos) { *restart_pos = byte_fifo->pos; } return fifo_search (byte_fifo, data, data_len, restart_pos); } gpointer chafa_byte_fifo_split_next (ChafaByteFifo *byte_fifo, gconstpointer separator, gint separator_len, gint64 *restart_pos, gint *len_out) { guint8 *data = NULL; gint len; g_return_val_if_fail (byte_fifo != NULL, NULL); g_return_val_if_fail (separator != NULL, NULL); g_return_val_if_fail (separator_len >= 0, NULL); len = chafa_byte_fifo_search (byte_fifo, separator, separator_len, restart_pos); if (len >= 0) { data = g_malloc (len + 1); chafa_byte_fifo_pop (byte_fifo, data, len); data [len] = '\0'; chafa_byte_fifo_drop (byte_fifo, separator_len); } if (len_out) *len_out = len; return data; } #if 0 /* FIXME: Move this to tests/ once the API is made public */ static void test_byte_fifo (void) { ChafaByteFifo *byte_fifo; gchar buf [32768]; gint result; memset (buf, 'x', 32768); byte_fifo = chafa_byte_fifo_new (); chafa_byte_fifo_push (byte_fifo, "abc", 3); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == 0); chafa_byte_fifo_drop (byte_fifo, 3); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == -1); chafa_byte_fifo_push (byte_fifo, "ababababcababab", 15); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == 6); chafa_byte_fifo_pop (byte_fifo, NULL, 1); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == 5); chafa_byte_fifo_push (byte_fifo, buf, 30000); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == 5); chafa_byte_fifo_drop (byte_fifo, 10); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == -1); chafa_byte_fifo_push (byte_fifo, "abc", 3); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == 30004); chafa_byte_fifo_drop (byte_fifo, 100000); result = chafa_byte_fifo_search (byte_fifo, "abc", 3, NULL); g_assert (result == -1); chafa_byte_fifo_push (byte_fifo, buf, 16380); chafa_byte_fifo_push (byte_fifo, "abracadabra", 11); result = chafa_byte_fifo_search (byte_fifo, "abracadabra", 11, NULL); g_assert (result == 16380); chafa_byte_fifo_drop (byte_fifo, 100000); chafa_byte_fifo_push (byte_fifo, buf, 16380); chafa_byte_fifo_push (byte_fifo, "abracadfrumpy", 13); result = chafa_byte_fifo_search (byte_fifo, "abracadabra", 11, NULL); g_assert (result == -1); chafa_byte_fifo_push (byte_fifo, "abracadabra", 11); result = chafa_byte_fifo_search (byte_fifo, "abracadabra", 11, NULL); g_assert (result == 16393); } #endif chafa-1.18.2/tools/chafa/chafa-byte-fifo.h000066400000000000000000000036361517447374300201730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_BYTE_FIFO_H__ #define __CHAFA_BYTE_FIFO_H__ #include G_BEGIN_DECLS typedef struct ChafaByteFifo ChafaByteFifo; ChafaByteFifo *chafa_byte_fifo_new (void); void chafa_byte_fifo_destroy (ChafaByteFifo *byte_fifo); gint64 chafa_byte_fifo_get_pos (ChafaByteFifo *byte_fifo); gint chafa_byte_fifo_get_len (ChafaByteFifo *byte_fifo); void chafa_byte_fifo_push (ChafaByteFifo *byte_fifo, gconstpointer src, gint src_len); gint chafa_byte_fifo_pop (ChafaByteFifo *byte_fifo, gpointer dest, gint dest_len); gconstpointer chafa_byte_fifo_peek (ChafaByteFifo *byte_fifo, gint *len); gint chafa_byte_fifo_drop (ChafaByteFifo *byte_fifo, gint len); gint chafa_byte_fifo_search (ChafaByteFifo *byte_fifo, gconstpointer data, gint data_len, gint64 *pos); gpointer chafa_byte_fifo_split_next (ChafaByteFifo *byte_fifo, gconstpointer separator, gint separator_len, gint64 *restart_pos, gint *len_out); G_END_DECLS #endif /* __CHAFA_BYTE_FIFO_H__ */ chafa-1.18.2/tools/chafa/chafa-parser.c000066400000000000000000000133311517447374300175670ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* memcpy, memset */ #include "chafa.h" #include "chafa-parser.h" struct ChafaEvent { ChafaEventType type; gunichar c; ChafaTermSeq seq; guint seq_args [CHAFA_TERM_SEQ_ARGS_MAX]; gint n_seq_args; }; struct ChafaParser { ChafaTermInfo *term_info; GString *buf; gint buf_ofs; guint eof_pushed : 1; guint eof_dispatched : 1; }; ChafaEventType chafa_event_get_type (ChafaEvent *event) { g_return_val_if_fail (event != NULL, CHAFA_EOF_EVENT); return event->type; } gunichar chafa_event_get_unichar (ChafaEvent *event) { g_return_val_if_fail (event != NULL, 0); g_return_val_if_fail (event->type == CHAFA_UNICHAR_EVENT, 0); return event->c; } ChafaTermSeq chafa_event_get_seq (ChafaEvent *event) { g_return_val_if_fail (event != NULL, CHAFA_TERM_SEQ_MAX); if (event->type != CHAFA_SEQ_EVENT) return CHAFA_TERM_SEQ_MAX; return event->seq; } gint chafa_event_get_seq_arg (ChafaEvent *event, gint n) { g_return_val_if_fail (event != NULL, -1); if (event->type != CHAFA_SEQ_EVENT || n >= event->n_seq_args) return -1; return (gint) event->seq_args [n]; } gint chafa_event_get_n_seq_args (ChafaEvent *event) { g_return_val_if_fail (event != NULL, 0); return event->n_seq_args; } void chafa_parser_init (ChafaParser *parser_out, ChafaTermInfo *term_info) { g_return_if_fail (parser_out != NULL); parser_out->term_info = term_info; chafa_term_info_ref (term_info); parser_out->buf = g_string_new (""); } void chafa_parser_deinit (ChafaParser *parser) { g_return_if_fail (parser != NULL); chafa_term_info_unref (parser->term_info); g_string_free (parser->buf, TRUE); } ChafaParser * chafa_parser_new (ChafaTermInfo *term_info) { ChafaParser *parser; parser = g_new0 (ChafaParser, 1); chafa_parser_init (parser, term_info); return parser; } void chafa_parser_destroy (ChafaParser *parser) { g_return_if_fail (parser != NULL); chafa_parser_deinit (parser); g_free (parser); } void chafa_parser_push_data (ChafaParser *parser, gconstpointer data, gint data_len) { g_return_if_fail (parser != NULL); g_return_if_fail (data != NULL); g_return_if_fail (data_len >= 0); g_return_if_fail (parser->eof_pushed == FALSE); g_string_append_len (parser->buf, data, data_len); } void chafa_parser_push_eof (ChafaParser *parser) { g_return_if_fail (parser != NULL); g_return_if_fail (parser->eof_pushed == FALSE); parser->eof_pushed = TRUE; } ChafaEvent * chafa_parser_pop_event (ChafaParser *parser) { ChafaEvent *event = NULL; gboolean have_again = FALSE; gchar *p0; gint len; gint i; g_return_val_if_fail (parser != NULL, FALSE); p0 = parser->buf->str; len = parser->buf->len; for (i = 0; i < CHAFA_TERM_SEQ_MAX; i++) { ChafaParseResult result; ChafaEvent temp_event; result = chafa_term_info_parse_seq_varargs (parser->term_info, i, &p0, &len, temp_event.seq_args, &temp_event.n_seq_args); if (result == CHAFA_PARSE_SUCCESS) { event = g_memdup (&temp_event, sizeof (ChafaEvent)); event->type = CHAFA_SEQ_EVENT; event->seq = i; event->c = 0; goto out; } else if (result == CHAFA_PARSE_AGAIN) { have_again = TRUE; } } while (!have_again && len > 0) { gunichar c; /* Character */ c = g_utf8_get_char_validated (p0, len); if (c == (gunichar) -1) { /* Invalid sequence; skip one byte */ p0++; len--; } else if (c == (gunichar) -2) { gchar *p1 = memchr (p0, '\0', len); if (p1) { /* Embedded NUL */ len -= (ptrdiff_t) p1 - (ptrdiff_t) p0 + 1; p0 = p1 + 1; } else { /* Incomplete */ have_again = TRUE; } } else { /* Good char */ event = g_new0 (ChafaEvent, 1); event->type = CHAFA_UNICHAR_EVENT; event->seq = -1; event->c = c; p0 = g_utf8_next_char (p0); goto out; } } out: if (!event && parser->eof_pushed && !parser->eof_dispatched) { event = g_new0 (ChafaEvent, 1); event->type = CHAFA_EOF_EVENT; event->seq = -1; parser->eof_dispatched = TRUE; } if (p0 != parser->buf->str) { /* FIXME: This will be slow. Switch to a better data structure */ g_string_erase (parser->buf, 0, (ptrdiff_t) p0 - (ptrdiff_t) parser->buf->str); } return event; } chafa-1.18.2/tools/chafa/chafa-parser.h000066400000000000000000000035211517447374300175740ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_PARSER_H__ #define __CHAFA_PARSER_H__ #include G_BEGIN_DECLS typedef enum { CHAFA_EOF_EVENT, CHAFA_UNICHAR_EVENT, CHAFA_SEQ_EVENT, } ChafaEventType; typedef struct ChafaEvent ChafaEvent; typedef struct ChafaParser ChafaParser; ChafaEventType chafa_event_get_type (ChafaEvent *event); gunichar chafa_event_get_unichar (ChafaEvent *event); ChafaTermSeq chafa_event_get_seq (ChafaEvent *event); gint chafa_event_get_seq_arg (ChafaEvent *event, gint n); gint chafa_event_get_n_seq_args (ChafaEvent *event); ChafaParser *chafa_parser_new (ChafaTermInfo *term_info); void chafa_parser_destroy (ChafaParser *parser); void chafa_parser_init (ChafaParser *parser_out, ChafaTermInfo *term_info); void chafa_parser_deinit (ChafaParser *parser); void chafa_parser_push_data (ChafaParser *parser, gconstpointer data, gint data_len); void chafa_parser_push_eof (ChafaParser *parser); ChafaEvent *chafa_parser_pop_event (ChafaParser *parser); G_END_DECLS #endif /* __CHAFA_PARSER_H__ */ chafa-1.18.2/tools/chafa/chafa-stream-reader.c000066400000000000000000000360041517447374300210300ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* open */ #include /* stat */ #include /* open */ #include /* STDOUT_FILENO */ /* Our copy of glib's internal GWakeup */ #include "chafa-wakeup.h" #include "chafa.h" #include "chafa-byte-fifo.h" #include "chafa-stream-reader.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #else # include #endif /* ------------------- * * Defines and structs * * ------------------- */ /* Stack buffer size */ #define READ_BUF_MAX 4096 /* Max fifo size before forced sync */ #define FIFO_DEFAULT_MAX 32768 struct ChafaStreamReader { gint refs; GThread *thread; ChafaByteFifo *fifo; GMutex mutex; GCond cond; ChafaWakeup *wakeup; GQueue *event_queue; #ifdef G_OS_WIN32 HANDLE fd_win32; DWORD saved_console_mode; #endif gint64 token_restart_pos; gpointer token_separator; gint token_separator_len; gint fd; guint idle_id; gint buf_max; guint is_console : 1; /* TRUE if EOF event was seen on input FD */ guint eof_seen : 1; guint shutdown_reqd : 1; guint shutdown_done : 1; }; /* ------------------ * * MS Windows helpers * * ------------------ */ #ifdef G_OS_WIN32 static void win32_stream_reader_init (ChafaStreamReader *stream_reader) { GetConsoleMode (stream_reader->fd_win32, &stream_reader->saved_console_mode); setmode (stream_reader->fd, O_BINARY); if (SetConsoleMode (stream_reader->fd_win32, ENABLE_PROCESSED_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT)) { stream_reader->is_console = TRUE; } else { if (GetLastError () != ERROR_INVALID_HANDLE) { /* Legacy MS Windows */ stream_reader->is_console = TRUE; } } } static void win32_stream_reader_deinit (ChafaStreamReader *stream_reader) { SetConsoleMode (stream_reader->fd_win32, stream_reader->saved_console_mode); } #endif /* -------------------------------- * * Low-level I/O and tty whispering * * -------------------------------- */ static gint read_from_stream (ChafaStreamReader *stream_reader, guchar *out, gint max) { GPollFD poll_fds [2]; gint result = -1; if (stream_reader->fd < 0) goto out; #ifdef G_OS_WIN32 poll_fds [0].fd = (gintptr) stream_reader->fd_win32; #else poll_fds [0].fd = stream_reader->fd; #endif poll_fds [0].events = G_IO_IN | G_IO_HUP | G_IO_ERR; poll_fds [0].revents = 0; poll_fds [1].revents = 0; chafa_wakeup_get_pollfd (stream_reader->wakeup, &poll_fds [1]); g_poll (poll_fds, 2, -1); /* Check for wakeup call; this means we should exit immediately */ if (poll_fds [1].revents) goto out; if (poll_fds [0].revents & G_IO_IN) { #ifdef G_OS_WIN32 DWORD n_read = 0; gboolean op_success = FALSE; if (stream_reader->is_console) op_success = ReadConsoleA (stream_reader->fd_win32, out, max, &n_read, NULL); else op_success = ReadFile (stream_reader->fd_win32, out, max, &n_read, NULL); if (op_success) result = n_read; else if (GetLastError () != ERROR_IO_PENDING) result = -1; #else /* !G_OS_WIN32 */ gint saved_errno; /* Do a non-blocking read. We're forced to turn it on and off again: * * - If we're reading from stdin, we can't leave it in non-blocking * mode, as it'll confuse subsequent shell commands (github#293). * * - We can't do blocking reads because there'd be no way to * interrupt the read(); GThread doesn't support signals akin to * pthread_sigqueue(), and we can't use the pthreads API directly * since GLib may be using a different implementation behind the * scenes. * * So we have this awkward workaround. There's a chance we get * killed while fd is still non-blocking, but in practice it's * very small. */ g_unix_set_fd_nonblocking (stream_reader->fd, TRUE, NULL); result = read (stream_reader->fd, out, max); saved_errno = errno; g_unix_set_fd_nonblocking (stream_reader->fd, FALSE, NULL); if (result < 1) { result = (saved_errno == EAGAIN || saved_errno == EINTR) ? 0 : -1; } #endif } else if (poll_fds [0].revents & (G_IO_HUP | G_IO_ERR)) { result = -1; } out: return result; } /* ----------------------- * * Mid-level I/O machinery * * ----------------------- */ static gboolean in_idle_func (gpointer data) { ChafaStreamReader *stream_reader = data; /* Dispatch read events in main thread */ g_mutex_lock (&stream_reader->mutex); stream_reader->idle_id = 0; for (;;) { guchar buf [READ_BUF_MAX]; gint len; /* FIXME: Can use peek here and save copying */ len = chafa_byte_fifo_pop (stream_reader->fifo, buf, READ_BUF_MAX); if (len < 1) break; /* TODO: Do something! */ } g_mutex_unlock (&stream_reader->mutex); /* TODO: Actually dispatch the events from parser */ return G_SOURCE_REMOVE; } static gpointer thread_main (gpointer data) { ChafaStreamReader *stream_reader = data; for (;;) { guchar buf [READ_BUF_MAX]; gint len; len = read_from_stream (stream_reader, buf, READ_BUF_MAX); g_mutex_lock (&stream_reader->mutex); if (len < 0) stream_reader->eof_seen = TRUE; if (stream_reader->eof_seen || stream_reader->shutdown_reqd) { break; } else if (len > 0) { chafa_byte_fifo_push (stream_reader->fifo, buf, len); g_cond_broadcast (&stream_reader->cond); if (!stream_reader->idle_id) stream_reader->idle_id = g_idle_add (in_idle_func, stream_reader); } while (chafa_byte_fifo_get_len (stream_reader->fifo) > FIFO_DEFAULT_MAX && !stream_reader->shutdown_reqd) g_cond_wait (&stream_reader->cond, &stream_reader->mutex); if (stream_reader->shutdown_reqd) break; g_mutex_unlock (&stream_reader->mutex); } stream_reader->shutdown_done = TRUE; g_cond_broadcast (&stream_reader->cond); g_mutex_unlock (&stream_reader->mutex); return NULL; } static void maybe_start_thread (ChafaStreamReader *stream_reader) { if (stream_reader->thread) return; stream_reader->thread = g_thread_new ("stream-reader", thread_main, stream_reader); } static gboolean is_eof_unlocked (ChafaStreamReader *stream_reader) { return chafa_byte_fifo_get_len (stream_reader->fifo) == 0 && (stream_reader->eof_seen || stream_reader->shutdown_done); } /* --------------------- * * Construct and destroy * * --------------------- */ static void chafa_stream_reader_init (ChafaStreamReader *stream_reader, gint fd, gconstpointer token_separator, gint token_separator_len) { stream_reader->refs = 1; stream_reader->fd = fd; stream_reader->buf_max = FIFO_DEFAULT_MAX; stream_reader->fifo = chafa_byte_fifo_new (); stream_reader->wakeup = chafa_wakeup_new (); g_mutex_init (&stream_reader->mutex); g_cond_init (&stream_reader->cond); if (token_separator && token_separator_len > 0) { stream_reader->token_separator = g_memdup (token_separator, token_separator_len); stream_reader->token_separator_len = token_separator_len; } else { stream_reader->token_separator = g_memdup ("", 1); stream_reader->token_separator_len = 1; } #ifdef G_OS_WIN32 stream_reader->fd_win32 = (HANDLE) _get_osfhandle (stream_reader->fd); win32_stream_reader_init (stream_reader); #else if (isatty (stream_reader->fd)) stream_reader->is_console = TRUE; #endif } static void chafa_stream_reader_destroy (ChafaStreamReader *stream_reader) { g_return_if_fail (stream_reader != NULL); g_mutex_lock (&stream_reader->mutex); if (stream_reader->idle_id) { g_source_remove (stream_reader->idle_id); stream_reader->idle_id = 0; } stream_reader->shutdown_reqd = TRUE; chafa_wakeup_signal (stream_reader->wakeup); g_cond_broadcast (&stream_reader->cond); while (stream_reader->thread && !stream_reader->shutdown_done) g_cond_wait (&stream_reader->cond, &stream_reader->mutex); g_mutex_unlock (&stream_reader->mutex); if (stream_reader->thread) g_thread_join (stream_reader->thread); #ifdef G_OS_WIN32 win32_stream_reader_deinit (stream_reader); #endif g_mutex_clear (&stream_reader->mutex); g_cond_clear (&stream_reader->cond); chafa_wakeup_free (stream_reader->wakeup); chafa_byte_fifo_destroy (stream_reader->fifo); g_free (stream_reader->token_separator); g_free (stream_reader); } /* ---------- * * Public API * * ---------- */ ChafaStreamReader * chafa_stream_reader_new_from_fd (gint fd) { ChafaStreamReader *stream_reader; g_return_val_if_fail (fd >= 0, NULL); stream_reader = g_new0 (ChafaStreamReader, 1); chafa_stream_reader_init (stream_reader, fd, NULL, -1); return stream_reader; } ChafaStreamReader * chafa_stream_reader_new_from_fd_full (gint fd, gconstpointer token_separator, gint token_separator_len) { ChafaStreamReader *stream_reader; g_return_val_if_fail (fd >= 0, NULL); stream_reader = g_new0 (ChafaStreamReader, 1); chafa_stream_reader_init (stream_reader, fd, token_separator, token_separator_len); return stream_reader; } void chafa_stream_reader_ref (ChafaStreamReader *stream_reader) { gint refs; g_return_if_fail (stream_reader != NULL); refs = g_atomic_int_get (&stream_reader->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&stream_reader->refs); } void chafa_stream_reader_unref (ChafaStreamReader *stream_reader) { gint refs; g_return_if_fail (stream_reader != NULL); refs = g_atomic_int_get (&stream_reader->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&stream_reader->refs)) { chafa_stream_reader_destroy (stream_reader); } } gint chafa_stream_reader_get_fd (ChafaStreamReader *stream_reader) { g_return_val_if_fail (stream_reader != NULL, -1); return stream_reader->fd; } gboolean chafa_stream_reader_is_console (ChafaStreamReader *stream_reader) { g_return_val_if_fail (stream_reader != NULL, FALSE); return stream_reader->is_console; } static void popped_fifo (ChafaStreamReader *stream_reader) { /* If there's space in the buffer, tell thread to resume reading */ if (chafa_byte_fifo_get_len (stream_reader->fifo) <= FIFO_DEFAULT_MAX) g_cond_broadcast (&stream_reader->cond); } gint chafa_stream_reader_read (ChafaStreamReader *stream_reader, gpointer out, gint max_len) { gint result = -1; g_return_val_if_fail (stream_reader != NULL, -1); maybe_start_thread (stream_reader); g_mutex_lock (&stream_reader->mutex); result = chafa_byte_fifo_pop (stream_reader->fifo, out, max_len); popped_fifo (stream_reader); g_mutex_unlock (&stream_reader->mutex); return result; } /* FIXME: Honor max_len, both for a regular split and remainder. Return an * error code on oversized tokens, and skip over them. */ gint chafa_stream_reader_read_token (ChafaStreamReader *stream_reader, gpointer *out, gint max_len) { gchar *token = NULL; gint result = -1; g_return_val_if_fail (stream_reader != NULL, -1); maybe_start_thread (stream_reader); g_mutex_lock (&stream_reader->mutex); token = chafa_byte_fifo_split_next (stream_reader->fifo, stream_reader->token_separator, stream_reader->token_separator_len, &stream_reader->token_restart_pos, &result); if (!token && (stream_reader->eof_seen || stream_reader->shutdown_done)) { gint len = chafa_byte_fifo_get_len (stream_reader->fifo); /* Return remaining data after final separator */ if (len > 0) { token = g_malloc (len + 1); chafa_byte_fifo_pop (stream_reader->fifo, token, len); token [len] = '\0'; result = len; } } popped_fifo (stream_reader); g_mutex_unlock (&stream_reader->mutex); if (result >= 0) *out = token; return result; } static gboolean chafa_stream_reader_wait_until_locked (ChafaStreamReader *stream_reader, gint64 end_time_us) { return g_cond_wait_until (&stream_reader->cond, &stream_reader->mutex, end_time_us); } gboolean chafa_stream_reader_wait_until (ChafaStreamReader *stream_reader, gint64 end_time_us) { gboolean result = FALSE; g_return_val_if_fail (stream_reader != NULL, FALSE); if (end_time_us < 1 || end_time_us <= g_get_monotonic_time ()) return FALSE; maybe_start_thread (stream_reader); g_mutex_lock (&stream_reader->mutex); result = chafa_stream_reader_wait_until_locked (stream_reader, end_time_us); g_mutex_unlock (&stream_reader->mutex); return result; } void chafa_stream_reader_wait (ChafaStreamReader *stream_reader, gint timeout_ms) { g_return_if_fail (stream_reader != NULL); maybe_start_thread (stream_reader); g_mutex_lock (&stream_reader->mutex); if (stream_reader->shutdown_done) { g_mutex_unlock (&stream_reader->mutex); return; } if (timeout_ms > 0) { gint64 end_time_us = g_get_monotonic_time () + timeout_ms * 1000; chafa_stream_reader_wait_until_locked (stream_reader, end_time_us); } else { g_cond_wait (&stream_reader->cond, &stream_reader->mutex); } g_mutex_unlock (&stream_reader->mutex); } gboolean chafa_stream_reader_is_eof (ChafaStreamReader *stream_reader) { gboolean is_eof = FALSE; g_return_val_if_fail (stream_reader != NULL, TRUE); g_mutex_lock (&stream_reader->mutex); is_eof = is_eof_unlocked (stream_reader); g_mutex_unlock (&stream_reader->mutex); return is_eof; } chafa-1.18.2/tools/chafa/chafa-stream-reader.h000066400000000000000000000040521517447374300210330ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_STREAM_READER_H__ #define __CHAFA_STREAM_READER_H__ #include G_BEGIN_DECLS typedef struct ChafaStreamReader ChafaStreamReader; ChafaStreamReader *chafa_stream_reader_new_from_fd (gint fd); ChafaStreamReader *chafa_stream_reader_new_from_fd_full (gint fd, gconstpointer token_separator, gint token_separator_len); void chafa_stream_reader_ref (ChafaStreamReader *stream_reader); void chafa_stream_reader_unref (ChafaStreamReader *stream_reader); gint chafa_stream_reader_get_fd (ChafaStreamReader *stream_reader); gboolean chafa_stream_reader_is_console (ChafaStreamReader *stream_reader); gint chafa_stream_reader_read (ChafaStreamReader *stream_reader, gpointer out, gint max_len); gint chafa_stream_reader_read_token (ChafaStreamReader *stream_reader, gpointer *out, gint max_len); gboolean chafa_stream_reader_wait_until (ChafaStreamReader *stream_reader, gint64 end_time_us); void chafa_stream_reader_wait (ChafaStreamReader *stream_reader, gint timeout_ms); gboolean chafa_stream_reader_is_eof (ChafaStreamReader *stream_reader); G_END_DECLS #endif /* __CHAFA_STREAM_READER_H__ */ chafa-1.18.2/tools/chafa/chafa-stream-writer.c000066400000000000000000000326201517447374300211020ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* open */ #include /* stat */ #include /* open */ #include /* STDOUT_FILENO */ #include /* g_vasprintf */ /* Our copy of glib's internal GWakeup */ #include "chafa-wakeup.h" #include "chafa.h" #include "chafa-byte-fifo.h" #include "chafa-stream-writer.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #else # include #endif /* ------------------- * * Defines and structs * * ------------------- */ /* Stack buffer size */ #define WRITE_BUF_MAX 4096 /* Max fifo size before forced sync */ #define FIFO_DEFAULT_MAX (1 << 20) struct ChafaStreamWriter { gint refs; GThread *thread; ChafaByteFifo *fifo; GMutex mutex; GCond cond; ChafaWakeup *wakeup; GQueue *event_queue; #ifdef G_OS_WIN32 HANDLE fd_win32; DWORD saved_console_mode; #endif gint fd; gint buf_max; guint is_console : 1; guint drained : 1; guint shutdown_reqd : 1; guint shutdown_done : 1; }; /* ------------------ * * MS Windows helpers * * ------------------ */ #ifdef G_OS_WIN32 static void win32_stream_writer_init (ChafaStreamWriter *stream_writer) { GetConsoleMode (stream_writer->fd_win32, &stream_writer->saved_console_mode); setmode (stream_writer->fd, O_BINARY); if (SetConsoleMode (stream_writer->fd_win32, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_WRAP_AT_EOL_OUTPUT)) { stream_writer->is_console = TRUE; } else { if (GetLastError () != ERROR_INVALID_HANDLE) { /* Legacy MS Windows */ stream_writer->is_console = TRUE; SetConsoleMode (stream_writer->fd_win32, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); } } } static void win32_stream_writer_deinit (ChafaStreamWriter *stream_writer) { SetConsoleMode (stream_writer->fd_win32, stream_writer->saved_console_mode); } static gboolean safe_WriteConsoleA (ChafaStreamWriter *stream_writer, const gchar *data, gsize len) { gsize total_written = 0; g_assert (stream_writer->fd_win32 != INVALID_HANDLE_VALUE); while (total_written < len) { DWORD n_written = 0; if (stream_writer->is_console) { if (!WriteConsoleA (stream_writer->fd_win32, data, len - total_written, &n_written, NULL)) return FALSE; } else { /* WriteFile() and fwrite() seem to work equally well despite various * claims that the former does poorly in a UTF-8 environment. The * resulting files look good in my tests, but note that catting them * out with 'type' introduces lots of artefacts. */ if (!WriteFile (stream_writer->fd_win32, data, len - total_written, &n_written, NULL)) return FALSE; } data += n_written; total_written += n_written; } return TRUE; } #else /* !G_OS_WIN32 */ static gboolean wait_for_pipe (gint fd) { GPollFD poll_fds [1]; poll_fds [0].fd = fd; poll_fds [0].events = G_IO_OUT | G_IO_HUP | G_IO_ERR; poll_fds [0].revents = 0; g_poll (poll_fds, 1, -1); return (poll_fds [0].revents & (G_IO_HUP | G_IO_ERR)) ? FALSE : TRUE; } static gboolean safe_write (gint fd, gconstpointer buf, gsize len) { const guint8 *buffer = buf; gboolean success = FALSE; while (len > 0) { guint to_write; gint n_written; gint saved_errno; if (len > INT_MAX) to_write = INT_MAX; else to_write = (unsigned int) len; n_written = write (fd, buffer, to_write); saved_errno = errno; if (n_written == -1) { if (saved_errno == EAGAIN) { # if defined(__gnu_hurd__) || defined(__OpenBSD__) /* On GNU/Hurd and OpenBSD we get EAGAIN if the remote end * closed the pipe, and if the pipe is made blocking it * simply stalls. This makes our >&- redirection test fail. * Therefore we bail out here as the least bad option. */ goto out; # else /* It's a nonblocking pipe; wait for it to become ready, * then try again. */ if (!wait_for_pipe (fd)) goto out; # endif } else if (saved_errno != EINTR) { goto out; } } else if (n_written < 0) { /* Not a valid 'write' result */ goto out; } else if (n_written > 0) { /* Continue writing until permanent failure or entire buffer written */ buffer += n_written; len -= (unsigned int) n_written; } } success = TRUE; out: return success; } #endif /* -------------------------------- * * Low-level I/O and tty whispering * * -------------------------------- */ static gboolean write_to_stream (ChafaStreamWriter *stream_writer, gconstpointer buf, gsize len) { gboolean result = TRUE; if (len == 0) return TRUE; #ifdef G_OS_WIN32 { gsize total_written = 0; const void * const newline = "\r\n"; const gchar *p0, *p1, *end; /* On MS Windows, we convert line feeds to DOS-style CRLF as we go. */ for (p0 = buf, end = p0 + len; stream_writer->fd_win32 != INVALID_HANDLE_VALUE && total_written < len; p0 = p1) { p1 = memchr (p0, '\n', end - p0); if (!p1) p1 = end; if (!safe_WriteConsoleA (stream_writer, p0, p1 - p0)) break; total_written += p1 - p0; if (p1 != end) { if (!safe_WriteConsoleA (stream_writer, newline, 2)) break; p1 += 1; total_written += 1; } } result = total_written == len ? TRUE : FALSE; } #else { result = safe_write (stream_writer->fd, buf, len); } #endif return result; } /* ----------------------- * * Mid-level I/O machinery * * ----------------------- */ static gpointer thread_main (gpointer data) { ChafaStreamWriter *stream_writer = data; gboolean io_error = FALSE; for (;;) { guchar buf [WRITE_BUF_MAX]; gint len; g_mutex_lock (&stream_writer->mutex); if (io_error || stream_writer->shutdown_reqd) break; if (!chafa_byte_fifo_get_len (stream_writer->fifo)) { /* Pending output has now left the process. Signal main thread; it * may be waiting to finish a flush */ stream_writer->drained = TRUE; g_cond_broadcast (&stream_writer->cond); } len = 0; while (!stream_writer->shutdown_reqd) { len = chafa_byte_fifo_pop (stream_writer->fifo, buf, WRITE_BUF_MAX); if (len) break; g_cond_wait (&stream_writer->cond, &stream_writer->mutex); } g_mutex_unlock (&stream_writer->mutex); if (!write_to_stream (stream_writer, buf, len)) io_error = TRUE; } stream_writer->shutdown_done = TRUE; g_cond_broadcast (&stream_writer->cond); g_mutex_unlock (&stream_writer->mutex); return NULL; } static void maybe_start_thread (ChafaStreamWriter *stream_writer) { if (stream_writer->thread) return; stream_writer->thread = g_thread_new ("stream-writer", thread_main, stream_writer); } /* --------------------- * * Construct and destroy * * --------------------- */ static void chafa_stream_writer_init (ChafaStreamWriter *stream_writer, gint fd) { stream_writer->refs = 1; stream_writer->fd = fd; stream_writer->buf_max = FIFO_DEFAULT_MAX; stream_writer->fifo = chafa_byte_fifo_new (); stream_writer->wakeup = chafa_wakeup_new (); g_mutex_init (&stream_writer->mutex); g_cond_init (&stream_writer->cond); #ifdef G_OS_WIN32 stream_writer->fd_win32 = (HANDLE) _get_osfhandle (stream_writer->fd); win32_stream_writer_init (stream_writer); #else if (isatty (stream_writer->fd)) stream_writer->is_console = TRUE; #endif } static void chafa_stream_writer_destroy (ChafaStreamWriter *stream_writer) { g_return_if_fail (stream_writer != NULL); g_mutex_lock (&stream_writer->mutex); stream_writer->shutdown_reqd = TRUE; chafa_wakeup_signal (stream_writer->wakeup); g_cond_broadcast (&stream_writer->cond); while (stream_writer->thread && !stream_writer->shutdown_done) g_cond_wait (&stream_writer->cond, &stream_writer->mutex); g_mutex_unlock (&stream_writer->mutex); if (stream_writer->thread) g_thread_join (stream_writer->thread); #ifdef G_OS_WIN32 win32_stream_writer_deinit (stream_writer); #endif g_mutex_clear (&stream_writer->mutex); g_cond_clear (&stream_writer->cond); chafa_wakeup_free (stream_writer->wakeup); chafa_byte_fifo_destroy (stream_writer->fifo); g_free (stream_writer); } /* ---------- * * Public API * * ---------- */ ChafaStreamWriter * chafa_stream_writer_new_from_fd (gint fd) { ChafaStreamWriter *stream_writer; g_return_val_if_fail (fd >= 0, NULL); stream_writer = g_new0 (ChafaStreamWriter, 1); chafa_stream_writer_init (stream_writer, fd); return stream_writer; } void chafa_stream_writer_ref (ChafaStreamWriter *stream_writer) { gint refs; g_return_if_fail (stream_writer != NULL); refs = g_atomic_int_get (&stream_writer->refs); g_return_if_fail (refs > 0); g_atomic_int_inc (&stream_writer->refs); } void chafa_stream_writer_unref (ChafaStreamWriter *stream_writer) { gint refs; g_return_if_fail (stream_writer != NULL); refs = g_atomic_int_get (&stream_writer->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&stream_writer->refs)) { chafa_stream_writer_destroy (stream_writer); } } gint chafa_stream_writer_get_fd (ChafaStreamWriter *stream_writer) { g_return_val_if_fail (stream_writer != NULL, -1); return stream_writer->fd; } gboolean chafa_stream_writer_is_console (ChafaStreamWriter *stream_writer) { g_return_val_if_fail (stream_writer != NULL, FALSE); return stream_writer->is_console; } gint chafa_stream_writer_get_buffer_max (ChafaStreamWriter *stream_writer) { g_return_val_if_fail (stream_writer != NULL, -1); return stream_writer->buf_max; } void chafa_stream_writer_set_buffer_max (ChafaStreamWriter *stream_writer, gint buf_max) { g_return_if_fail (stream_writer != NULL); g_return_if_fail (buf_max > 0); stream_writer->buf_max = buf_max; } void chafa_stream_writer_write (ChafaStreamWriter *stream_writer, gconstpointer data, gint len) { maybe_start_thread (stream_writer); while (len > 0) { gint n_written; g_mutex_lock (&stream_writer->mutex); /* Wait for partial drain if necessary */ for (;;) { gint queued = chafa_byte_fifo_get_len (stream_writer->fifo); if (queued == 0 || queued + len <= stream_writer->buf_max) break; if (stream_writer->shutdown_done) { g_mutex_unlock (&stream_writer->mutex); goto out; } g_cond_wait (&stream_writer->cond, &stream_writer->mutex); } /* Push and signal */ stream_writer->drained = FALSE; n_written = MIN (len, stream_writer->buf_max); chafa_byte_fifo_push (stream_writer->fifo, data, n_written); len -= n_written; data = ((const gchar *) data) + n_written; g_cond_broadcast (&stream_writer->cond); g_mutex_unlock (&stream_writer->mutex); } out: return; } gint chafa_stream_writer_print (ChafaStreamWriter *stream_writer, const gchar *format, ...) { gchar *str = NULL; va_list args; gint result; va_start (args, format); result = g_vasprintf (&str, format, args); va_end (args); if (result > 0) chafa_stream_writer_write (stream_writer, str, result); g_free (str); return result; } gboolean chafa_stream_writer_flush (ChafaStreamWriter *stream_writer) { maybe_start_thread (stream_writer); g_mutex_lock (&stream_writer->mutex); while (!stream_writer->shutdown_done && !stream_writer->drained) g_cond_wait (&stream_writer->cond, &stream_writer->mutex); g_mutex_unlock (&stream_writer->mutex); return TRUE; } chafa-1.18.2/tools/chafa/chafa-stream-writer.h000066400000000000000000000034501517447374300211060ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_STREAM_WRITER_H__ #define __CHAFA_STREAM_WRITER_H__ #include G_BEGIN_DECLS typedef struct ChafaStreamWriter ChafaStreamWriter; ChafaStreamWriter *chafa_stream_writer_new_from_fd (gint fd); void chafa_stream_writer_ref (ChafaStreamWriter *stream_writer); void chafa_stream_writer_unref (ChafaStreamWriter *stream_writer); gint chafa_stream_writer_get_fd (ChafaStreamWriter *stream_writer); gboolean chafa_stream_writer_is_console (ChafaStreamWriter *stream_writer); gint chafa_stream_writer_get_buffer_max (ChafaStreamWriter *stream_writer); void chafa_stream_writer_set_buffer_max (ChafaStreamWriter *stream_writer, gint buf_max); void chafa_stream_writer_write (ChafaStreamWriter *stream_writer, gconstpointer data, gint len); gint chafa_stream_writer_print (ChafaStreamWriter *stream_writer, const gchar *format, ...); gboolean chafa_stream_writer_flush (ChafaStreamWriter *stream_writer); G_END_DECLS #endif /* __CHAFA_STREAM_WRITER_H__ */ chafa-1.18.2/tools/chafa/chafa-term.c000066400000000000000000000567221517447374300172550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* ctermid */ #include /* open */ #include /* open */ #include /* STDOUT_FILENO */ #ifdef HAVE_SYS_IOCTL_H # include /* ioctl */ #endif #ifdef HAVE_TERMIOS_H # include /* tcgetattr, tcsetattr */ #endif #include /* g_vasprintf */ #include /* g_open, g_close */ #include "chafa.h" #include "chafa-byte-fifo.h" #include "chafa-stream-reader.h" #include "chafa-stream-writer.h" #include "chafa-term.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #else # include #endif /* ------------------- * * Defines and structs * * ------------------- */ /* Maximum width or height of the terminal, in pixels. If it claims to be * bigger than this, assume it's broken. */ #define PIXEL_EXTENT_MAX (8192 * 3) #define CELL_EXTENT_PX_MAX 8192 /* Stack buffer size */ #define READ_BUF_MAX 4096 struct ChafaTerm { ChafaTermInfo *term_info; ChafaTermInfo *default_term_info; ChafaParser *parser; ChafaStreamReader *reader; ChafaStreamWriter *writer; ChafaStreamWriter *err_writer; gint width_cells, height_cells; gint width_px, height_px; gint cell_width_px, cell_height_px; /* Default FG/BG colors. Byte order is XRGB native. -1 if unknown */ gint32 default_fg_rgb; gint32 default_bg_rgb; /* TRUE if we probed the tty size at least once */ guint have_tty_size : 1; /* TRUE if both input and output fds are connected to a terminal */ guint interactive_supported : 1; /* TRUE if EOF event was seen on input FD */ guint in_eof_seen : 1; /* TRUE if probe query was sent */ guint probe_attempt : 1; /* TRUE if probe response was received */ guint probe_success : 1; /* TRUE if sixel capability was detected by the last probe */ guint probe_found_sixel : 1; /* I/O bookkeeping */ GQueue *event_queue; guint in_idle_id; }; /* ------------------ * * MS Windows helpers * * ------------------ */ #ifdef G_OS_WIN32 static UINT win32_saved_console_output_cp; static UINT win32_saved_console_input_cp; static gint win32_global_init_depth; static void win32_global_init (void) { if (g_atomic_int_add (&win32_global_init_depth, 1) > 0) return; win32_saved_console_output_cp = GetConsoleOutputCP (); win32_saved_console_input_cp = GetConsoleCP (); /* Set UTF-8 code page output */ SetConsoleOutputCP (65001); /* Set UTF-8 code page input, for good measure */ SetConsoleCP (65001); } static void win32_global_deinit (void) { if (!g_atomic_int_dec_and_test (&win32_global_init_depth)) return; SetConsoleOutputCP (win32_saved_console_output_cp); SetConsoleCP (win32_saved_console_input_cp); } static void win32_term_init (ChafaTerm *term) { win32_global_init (); } static void win32_term_deinit (ChafaTerm *term) { win32_global_deinit (); } static HANDLE win32_get_reader_handle (ChafaTerm *term) { if (term->reader) { gint fd = chafa_stream_reader_get_fd (term->reader); if (fd >= 0) return (HANDLE) _get_osfhandle (fd); } return INVALID_HANDLE_VALUE; } static HANDLE win32_get_writer_handle (ChafaTerm *term) { if (term->reader) { gint fd = chafa_stream_reader_get_fd (term->reader); if (fd >= 0) return (HANDLE) _get_osfhandle (fd); } return INVALID_HANDLE_VALUE; } #endif /* -------------------------------- * * Low-level I/O and tty whispering * * -------------------------------- */ #ifdef HAVE_TERMIOS_H static void ensure_raw_mode_enabled (ChafaTerm *term, struct termios *saved_termios, gboolean *termios_changed) { struct termios t; if (!term->reader) return; tcgetattr (chafa_stream_reader_get_fd (term->reader), saved_termios); t = *saved_termios; t.c_lflag &= ~(ECHO | ICANON); if (t.c_lflag != saved_termios->c_lflag) { *termios_changed = TRUE; /* Note tcsetattr() can block on tty fds when we're in the background. */ tcsetattr (chafa_stream_reader_get_fd (term->reader), TCSANOW, &t); /* FIXME: Should probably call tcgetattr() here to ensure things went * according to plan. */ } else { *termios_changed = FALSE; } } static void restore_termios (ChafaTerm *term, const struct termios *saved_termios, gboolean *termios_changed) { if (!term->reader || !*termios_changed) return; tcsetattr (chafa_stream_reader_get_fd (term->reader), TCSANOW, saved_termios); } #endif static void get_tty_size (ChafaTerm *term) { term->width_cells = term->height_cells = term->width_px = term->height_px = -1; #ifdef G_OS_WIN32 { HANDLE chd = win32_get_writer_handle (term); CONSOLE_SCREEN_BUFFER_INFO csb_info; if (chd != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo (chd, &csb_info)) { term->width_cells = csb_info.srWindow.Right - csb_info.srWindow.Left + 1; term->height_cells = csb_info.srWindow.Bottom - csb_info.srWindow.Top + 1; } } #elif defined(HAVE_SYS_IOCTL_H) { struct winsize w; gboolean have_winsz = FALSE; gint in_fd = -1, out_fd = -1, err_fd = -1; if (term->reader) in_fd = chafa_stream_reader_get_fd (term->reader); if (term->writer) out_fd = chafa_stream_writer_get_fd (term->writer); if (term->err_writer) err_fd = chafa_stream_writer_get_fd (term->err_writer); /* FIXME: Use tcgetwinsize() when it becomes more widely available. * See: https://www.austingroupbugs.net/view.php?id=1151#c3856 */ if ((out_fd >= 0 && ioctl (out_fd, TIOCGWINSZ, &w) >= 0) || (err_fd >= 0 && ioctl (err_fd, TIOCGWINSZ, &w) >= 0) || (in_fd >= 0 && ioctl (in_fd, TIOCGWINSZ, &w) >= 0)) have_winsz = TRUE; # ifdef HAVE_CTERMID if (!have_winsz) { const gchar *term_path; gint fd = -1; term_path = ctermid (NULL); if (term_path) fd = g_open (term_path, O_RDONLY); if (fd >= 0) { if (ioctl (fd, TIOCGWINSZ, &w) >= 0) have_winsz = TRUE; g_close (fd, NULL); } } # endif /* HAVE_CTERMID */ if (have_winsz) { term->width_cells = w.ws_col; term->height_cells = w.ws_row; term->width_px = w.ws_xpixel; term->height_px = w.ws_ypixel; } } #endif /* HAVE_SYS_IOCTL_H */ if (term->width_cells <= 0) term->width_cells = -1; if (term->height_cells <= 2) term->height_cells = -1; /* If .ws_xpixel and .ws_ypixel are filled out, we can calculate * aspect information for the font used. Sixel-capable terminals * like mlterm set these fields, but most others do not. */ if (term->width_px > PIXEL_EXTENT_MAX || term->height_px > PIXEL_EXTENT_MAX) { /* https://github.com/hpjansson/chafa/issues/62 */ term->width_px = -1; term->height_px = -1; } else if (term->width_px <= 0 || term->height_px <= 0) { term->width_px = -1; term->height_px = -1; } term->have_tty_size = TRUE; } /* ----------- * * Seq helpers * * ----------- */ static const ChafaTermSeq sixel_seqs [] = { CHAFA_TERM_SEQ_BEGIN_SIXELS, CHAFA_TERM_SEQ_END_SIXELS, CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING, CHAFA_TERM_SEQ_DISABLE_SIXEL_SCROLLING, CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN, CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_RIGHT }; static void supplement_seq (ChafaTermInfo *dest, ChafaTermInfo *src, ChafaTermSeq seq) { if (!chafa_term_info_have_seq (dest, seq)) chafa_term_info_set_seq (dest, seq, chafa_term_info_get_seq (src, seq), NULL); } static void supplement_seqs (ChafaTermInfo *dest, ChafaTermInfo *src, const ChafaTermSeq *seqs, gint n_seqs) { gint i; for (i = 0; i < n_seqs; i++) supplement_seq (dest, src, seqs [i]); } static gint print_multiple (ChafaTerm *term, const gint *print_seqs) { gint n_printed = 0; gint i; for (i = 0; print_seqs [i] > -1; i++) { if (chafa_term_print_seq (term, print_seqs [i], -1) > 0) n_printed++; } return n_printed; } /* ----------------------- * * Internal event handling * * ----------------------- */ /* We peek at all incoming events and update state based on some of them * before they're passed on to the user. * * Events are handled before they're put on the event queue. */ static void apply_probe_results (ChafaTerm *term) { if (!term->probe_success) return; if (!term->default_term_info) term->default_term_info = chafa_term_db_get_fallback_info (chafa_term_db_get_default ()); if (term->probe_found_sixel && !chafa_term_info_have_seq (term->term_info, CHAFA_TERM_SEQ_BEGIN_SIXELS)) { supplement_seqs (term->term_info, term->default_term_info, sixel_seqs, G_N_ELEMENTS (sixel_seqs)); } if (term->width_cells > 0 && term->height_cells > 0 && term->width_px > 0 && term->height_px > 0) { term->cell_width_px = term->width_px / term->width_cells; term->cell_height_px = term->height_px / term->height_cells; } } static gint probe_color_to_packed_rgb (const gint *c) { return ((c [0] / 256) << 16) | ((c [1] / 256) << 8) | (c [2] / 256); } static gboolean handle_default_fg_event (ChafaTerm *term, ChafaEvent *event) { gint c [3]; gint i; if (chafa_event_get_seq (event) != CHAFA_TERM_SEQ_SET_DEFAULT_FG) return FALSE; for (i = 0; i < 3; i++) c [i] = chafa_event_get_seq_arg (event, i); term->default_fg_rgb = probe_color_to_packed_rgb (c); return TRUE; } static gboolean handle_default_bg_event (ChafaTerm *term, ChafaEvent *event) { gint c [3]; gint i; if (chafa_event_get_seq (event) != CHAFA_TERM_SEQ_SET_DEFAULT_BG) return FALSE; for (i = 0; i < 3; i++) c [i] = chafa_event_get_seq_arg (event, i); term->default_bg_rgb = probe_color_to_packed_rgb (c); return TRUE; } static gboolean handle_text_area_size_cells_event (ChafaTerm *term, ChafaEvent *event) { gint c [2]; gint i; if (chafa_event_get_seq (event) != CHAFA_TERM_SEQ_TEXT_AREA_SIZE_CELLS) return FALSE; for (i = 0; i < 2; i++) c [i] = chafa_event_get_seq_arg (event, i); if (c [0] > 0 && c [1] > 0) { term->width_cells = c [1]; term->height_cells = c [0]; } return TRUE; } static gboolean handle_text_area_size_px_event (ChafaTerm *term, ChafaEvent *event) { gint c [2]; gint i; if (chafa_event_get_seq (event) != CHAFA_TERM_SEQ_TEXT_AREA_SIZE_PX) return FALSE; for (i = 0; i < 2; i++) c [i] = chafa_event_get_seq_arg (event, i); if (c [0] > 0 && c [0] < PIXEL_EXTENT_MAX && c [1] > 0 && c [1] < PIXEL_EXTENT_MAX) { term->width_px = c [1]; term->height_px = c [0]; } return TRUE; } static gboolean handle_cell_size_px_event (ChafaTerm *term, ChafaEvent *event) { gint c [2]; gint i; if (chafa_event_get_seq (event) != CHAFA_TERM_SEQ_CELL_SIZE_PX) return FALSE; for (i = 0; i < 2; i++) c [i] = chafa_event_get_seq_arg (event, i); if (c [0] > 0 && c [0] < CELL_EXTENT_PX_MAX && c [1] > 0 && c [1] < CELL_EXTENT_PX_MAX) { term->cell_width_px = c [1]; term->cell_height_px = c [0]; } return TRUE; } static gboolean handle_primary_da_event (ChafaTerm *term, ChafaEvent *event) { gint arg; gint i; if (chafa_event_get_seq (event) != CHAFA_TERM_SEQ_PRIMARY_DEVICE_ATTRIBUTES) return FALSE; for (i = 0; (arg = chafa_event_get_seq_arg (event, i)) >= 0; i++) { switch (arg) { case 4: term->probe_found_sixel = TRUE; break; default: break; } } term->probe_success = TRUE; apply_probe_results (term); return TRUE; } static gboolean handle_eof_event (ChafaTerm *term, ChafaEvent *event) { if (chafa_event_get_type (event) != CHAFA_EOF_EVENT) return FALSE; term->in_eof_seen = TRUE; return TRUE; } typedef gboolean (*EventHandler) (ChafaTerm *, ChafaEvent *); static const EventHandler event_handlers [] = { handle_default_fg_event, handle_default_bg_event, handle_text_area_size_cells_event, handle_text_area_size_px_event, handle_cell_size_px_event, handle_primary_da_event, handle_eof_event, NULL }; static void handle_event (ChafaTerm *term, ChafaEvent *event) { gint i; if (!event) return; for (i = 0; event_handlers [i]; i++) { if (event_handlers [i] (term, event)) break; } } /* ----------------------- * * Mid-level I/O machinery * * ----------------------- */ static ChafaEvent * in_sync_pull (ChafaTerm *term, gint timeout_ms) { ChafaEvent *event = NULL; gint64 end_time_us = -1; if ((event = chafa_parser_pop_event (term->parser))) return event; if (timeout_ms > 0) end_time_us = g_get_monotonic_time () + timeout_ms * 1000; for (;;) { guchar buf [READ_BUF_MAX]; gint len; /* TODO: Break on EOF */ len = chafa_stream_reader_read (term->reader, buf, READ_BUF_MAX); chafa_parser_push_data (term->parser, buf, len); if ((event = chafa_parser_pop_event (term->parser))) break; if (timeout_ms <= 0) { /* Wait indefinitely */ chafa_stream_reader_wait (term->reader, -1); } else { /* Bail out if end time passed */ if (!chafa_stream_reader_wait_until (term->reader, end_time_us)) break; } } return event; } /* --------------------- * * Construct and destroy * * --------------------- */ static gboolean fd_is_valid (gint fd) { gboolean result; if (fd < 0) return FALSE; #ifdef G_OS_WIN32 result = ((HANDLE) _get_osfhandle (fd) != INVALID_HANDLE_VALUE) ? TRUE : FALSE; #else result = (fcntl (fd, F_GETFL) >= 0) ? TRUE : FALSE; #endif return result; } static ChafaTerm * term_new_full (ChafaTermInfo *term_info, gint in_fd, gint out_fd, gint err_fd) { ChafaTerm *term; term = g_new0 (ChafaTerm, 1); if (term_info) { chafa_term_info_ref (term_info); term->term_info = term_info; } else { gchar **envp; envp = g_get_environ (); term->term_info = chafa_term_db_detect (chafa_term_db_get_default (), envp); g_strfreev (envp); } term->parser = chafa_parser_new (term->term_info); term->width_cells = -1; term->height_cells = -1; term->width_px = -1; term->height_px = -1; term->cell_width_px = -1; term->cell_height_px = -1; term->default_fg_rgb = -1; term->default_bg_rgb = -1; term->event_queue = g_queue_new (); /* Verify that the fds are open before we do anything else with them. The * default terminal uses stdio (0, 1, 2), but these may have been closed by * the calling process. The fds may be reused later, e.g. when the * application opens a file. */ if (fd_is_valid (in_fd)) term->reader = chafa_stream_reader_new_from_fd (in_fd); if (fd_is_valid (out_fd)) term->writer = chafa_stream_writer_new_from_fd (out_fd); if (fd_is_valid (err_fd)) term->err_writer = chafa_stream_writer_new_from_fd (err_fd); #ifdef G_OS_WIN32 win32_term_init (term); #endif if (term->reader && chafa_stream_reader_is_console (term->reader) && term->writer && chafa_stream_writer_is_console (term->writer)) term->interactive_supported = TRUE; get_tty_size (term); return term; } static ChafaTerm * term_new_default (void) { return term_new_full (NULL, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO); } static ChafaTerm * instantiate_singleton (G_GNUC_UNUSED gpointer data) { return term_new_default (); } /* ---------- * * Public API * * ---------- */ ChafaTerm * chafa_term_new (ChafaTermInfo *term_info, gint in_fd, gint out_fd, gint err_fd) { return term_new_full (term_info, in_fd, out_fd, err_fd); } void chafa_term_destroy (ChafaTerm *term) { g_return_if_fail (term != NULL); chafa_term_flush (term); if (term->reader) chafa_stream_reader_unref (term->reader); if (term->writer) chafa_stream_writer_unref (term->writer); if (term->err_writer) chafa_stream_writer_unref (term->err_writer); g_queue_free_full (term->event_queue, g_free); chafa_term_info_unref (term->term_info); if (term->default_term_info) chafa_term_info_unref (term->default_term_info); #ifdef G_OS_WIN32 win32_term_deinit (term); #endif chafa_parser_destroy (term->parser); g_free (term); } ChafaTerm * chafa_term_get_default (void) { static GOnce my_once = G_ONCE_INIT; g_once (&my_once, (GThreadFunc) instantiate_singleton, NULL); return my_once.retval; } gint chafa_term_get_buffer_max (ChafaTerm *term) { if (term->writer) return chafa_stream_writer_get_buffer_max (term->writer); return -1; } void chafa_term_set_buffer_max (ChafaTerm *term, gint buf_max) { if (term->writer) chafa_stream_writer_set_buffer_max (term->writer, buf_max); } ChafaTermInfo * chafa_term_get_term_info (ChafaTerm *term) { return term->term_info; } void chafa_term_set_term_info (ChafaTerm *term, ChafaTermInfo *term_info) { if (term_info) chafa_term_info_ref (term_info); if (term->term_info) chafa_term_info_unref (term->term_info); term->term_info = term_info; } ChafaEvent * chafa_term_read_event (ChafaTerm *term, guint timeout_ms) { ChafaEvent *event = NULL; if (!term->reader) goto out; event = g_queue_pop_tail (term->event_queue); if (event) goto out; if (term->in_eof_seen) goto out; event = in_sync_pull (term, timeout_ms); handle_event (term, event); out: return event; } void chafa_term_write (ChafaTerm *term, gconstpointer data, gint len) { if (!term->writer) return; chafa_stream_writer_write (term->writer, data, len); } gint chafa_term_print (ChafaTerm *term, const gchar *format, ...) { gchar *str = NULL; va_list args; gint len = -1; if (!term->writer) return -1; va_start (args, format); len = g_vasprintf (&str, format, args); va_end (args); if (len > 0) chafa_stream_writer_write (term->writer, str, len); g_free (str); return len; } gint chafa_term_print_seq (ChafaTerm *term, ChafaTermSeq seq, ...) { va_list args; gchar *str; gint len = -1; if (!term->writer) return -1; va_start (args, seq); str = chafa_term_info_emit_seq_valist (term->term_info, seq, &args); va_end (args); if (str) { len = strlen (str); chafa_stream_writer_write (term->writer, str, len); } g_free (str); return len; } gboolean chafa_term_flush (ChafaTerm *term) { if (!term->writer) return FALSE; return chafa_stream_writer_flush (term->writer); } void chafa_term_write_err (ChafaTerm *term, gconstpointer data, gint len) { if (!term->err_writer) return; chafa_stream_writer_write (term->err_writer, data, len); } gint chafa_term_print_err (ChafaTerm *term, const gchar *format, ...) { gchar *str = NULL; va_list args; gint result; va_start (args, format); result = g_vasprintf (&str, format, args); va_end (args); if (result > 0) chafa_term_write_err (term, str, result); g_free (str); return result; } void chafa_term_get_size_px (ChafaTerm *term, gint *width_px_out, gint *height_px_out) { if (!term->have_tty_size) get_tty_size (term); if (width_px_out) *width_px_out = term->width_px; if (height_px_out) *height_px_out = term->height_px; } void chafa_term_get_size_cells (ChafaTerm *term, gint *width_cells_out, gint *height_cells_out) { if (!term->have_tty_size) get_tty_size (term); if (width_cells_out) *width_cells_out = term->width_cells; if (height_cells_out) *height_cells_out = term->height_cells; } gboolean chafa_term_sync_probe (ChafaTerm *term, gint timeout_ms) { ChafaEvent *event; gint64 start_time; gint remain_ms = timeout_ms; #ifdef HAVE_TERMIOS_H struct termios saved_termios; gboolean termios_changed = FALSE; #endif const gint probe_seqs [] = { CHAFA_TERM_SEQ_QUERY_DEFAULT_FG, CHAFA_TERM_SEQ_QUERY_DEFAULT_BG, CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_CELLS, CHAFA_TERM_SEQ_QUERY_TEXT_AREA_SIZE_PX, CHAFA_TERM_SEQ_QUERY_CELL_SIZE_PX, CHAFA_TERM_SEQ_QUERY_PRIMARY_DEVICE_ATTRIBUTES, -1 }; gint n_probes = 0; if (term->probe_success) return TRUE; if (!term->interactive_supported) return FALSE; if (timeout_ms > 0) start_time = g_get_monotonic_time (); /* Terminal must be in raw mode for response to get picked up without * user interaction. */ #ifdef HAVE_TERMIOS_H ensure_raw_mode_enabled (term, &saved_termios, &termios_changed); #endif n_probes = print_multiple (term, probe_seqs); term->probe_attempt = TRUE; if (n_probes == 0) { /* Terminal doesn't support any of the probe sequences */ term->probe_success = FALSE; goto out; } while ((event = in_sync_pull (term, timeout_ms > 0 ? remain_ms : -1))) { g_queue_push_head (term->event_queue, event); handle_event (term, event); if (term->probe_success || term->in_eof_seen) break; if (timeout_ms > 0) { remain_ms -= (g_get_monotonic_time () - start_time) / 1000; if (remain_ms <= 0) break; } } out: #ifdef HAVE_TERMIOS_H restore_termios (term, &saved_termios, &termios_changed); #endif return term->probe_success; } void chafa_term_notify_size_changed (ChafaTerm *term) { get_tty_size (term); } gint32 chafa_term_get_default_fg_color (ChafaTerm *term) { return term->default_fg_rgb; } gint32 chafa_term_get_default_bg_color (ChafaTerm *term) { return term->default_bg_rgb; } chafa-1.18.2/tools/chafa/chafa-term.h000066400000000000000000000045531517447374300172550ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHAFA_TERM_H__ #define __CHAFA_TERM_H__ #include #include "chafa-parser.h" G_BEGIN_DECLS typedef struct ChafaTerm ChafaTerm; ChafaTerm *chafa_term_new (ChafaTermInfo *term_info, gint in_fd, gint out_fd, gint err_fd); void chafa_term_destroy (ChafaTerm *term); ChafaTerm *chafa_term_get_default (void); gint chafa_term_get_buffer_max (ChafaTerm *term); void chafa_term_set_buffer_max (ChafaTerm *term, gint max); ChafaTermInfo *chafa_term_get_term_info (ChafaTerm *term); void chafa_term_set_term_info (ChafaTerm *term, ChafaTermInfo *term_info); ChafaEvent *chafa_term_read_event (ChafaTerm *term, guint timeout_ms); void chafa_term_write (ChafaTerm *term, gconstpointer data, gint len); gint chafa_term_print (ChafaTerm *term, const gchar *format, ...) G_GNUC_PRINTF (2, 3); gint chafa_term_print_seq (ChafaTerm *term, ChafaTermSeq seq, ...); gboolean chafa_term_flush (ChafaTerm *term); void chafa_term_write_err (ChafaTerm *term, gconstpointer data, gint len); gint chafa_term_print_err (ChafaTerm *term, const gchar *format, ...) G_GNUC_PRINTF (2, 3); void chafa_term_get_size_px (ChafaTerm *term, gint *width_px_out, gint *height_px_out); void chafa_term_get_size_cells (ChafaTerm *term, gint *width_cells_out, gint *height_cells_out); gboolean chafa_term_sync_probe (ChafaTerm *term, gint timeout_ms); void chafa_term_notify_size_changed (ChafaTerm *term); gint32 chafa_term_get_default_fg_color (ChafaTerm *term); gint32 chafa_term_get_default_bg_color (ChafaTerm *term); G_END_DECLS #endif /* __CHAFA_TERM_H__ */ chafa-1.18.2/tools/chafa/chafa-wakeup.c000066400000000000000000000146661517447374300176030ustar00rootroot00000000000000/* * Copyright © 2011 Canonical Limited * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . * * Author: Ryan Lortie */ #include "config.h" /* Chafa note: I've changed the namespace to avoid potential future * conflicts. This fine piece of engineering is otherwise unmodified * from the GLib original. --hpj */ /* gwakeup.c is special -- GIO and some test cases include it. As such, * it cannot include other glib headers without triggering the single * includes warnings. We have to manually include its dependencies here * (and at all other use sites). */ #include #include "chafa-wakeup.h" /*< private > * SECTION:gwakeup * @title: ChafaWakeup * @short_description: portable cross-thread event signal mechanism * * #ChafaWakeup is a simple and portable way of signaling events between * different threads in a way that integrates nicely with g_poll(). * GLib uses it internally for cross-thread signalling in the * implementation of #GMainContext and #GCancellable. * * You first create a #ChafaWakeup with chafa_wakeup_new() and initialise a * #GPollFD from it using chafa_wakeup_get_pollfd(). Polling on the created * #GPollFD will block until chafa_wakeup_signal() is called, at which point * it will immediately return. Future attempts to poll will continue to * return until chafa_wakeup_acknowledge() is called. chafa_wakeup_free() is * used to free a #ChafaWakeup. * * On sufficiently modern Linux, this is implemented using eventfd. On * Windows it is implemented using an event handle. On other systems it * is implemented with a pair of pipes. * * Since: 2.30 **/ #ifdef _WIN32 #include #ifdef GLIB_COMPILATION #include "gmessages.h" #include "giochannel.h" #include "gwin32.h" #endif ChafaWakeup * chafa_wakeup_new (void) { HANDLE wakeup; wakeup = CreateEvent (NULL, TRUE, FALSE, NULL); if (wakeup == NULL) g_error ("Cannot create event for ChafaWakeup: %s", g_win32_error_message (GetLastError ())); return (ChafaWakeup *) wakeup; } void chafa_wakeup_get_pollfd (ChafaWakeup *wakeup, GPollFD *poll_fd) { poll_fd->fd = (gintptr) wakeup; poll_fd->events = G_IO_IN; } void chafa_wakeup_acknowledge (ChafaWakeup *wakeup) { ResetEvent ((HANDLE) wakeup); } void chafa_wakeup_signal (ChafaWakeup *wakeup) { SetEvent ((HANDLE) wakeup); } void chafa_wakeup_free (ChafaWakeup *wakeup) { CloseHandle ((HANDLE) wakeup); } #else #include "glib-unix.h" #include #if defined (HAVE_EVENTFD) #include #endif struct _ChafaWakeup { gint fds[2]; }; /** * chafa_wakeup_new: * * Creates a new #ChafaWakeup. * * You should use chafa_wakeup_free() to free it when you are done. * * Returns: a new #ChafaWakeup * * Since: 2.30 **/ ChafaWakeup * chafa_wakeup_new (void) { GError *error = NULL; ChafaWakeup *wakeup; wakeup = g_slice_new (ChafaWakeup); /* try eventfd first, if we think we can */ #if defined (HAVE_EVENTFD) #ifndef TEST_EVENTFD_FALLBACK wakeup->fds[0] = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK); #else wakeup->fds[0] = -1; #endif if (wakeup->fds[0] != -1) { wakeup->fds[1] = -1; return wakeup; } /* for any failure, try a pipe instead */ #endif if (!g_unix_open_pipe (wakeup->fds, FD_CLOEXEC, &error)) g_error ("Creating pipes for ChafaWakeup: %s", error->message); if (!g_unix_set_fd_nonblocking (wakeup->fds[0], TRUE, &error) || !g_unix_set_fd_nonblocking (wakeup->fds[1], TRUE, &error)) g_error ("Set pipes non-blocking for ChafaWakeup: %s", error->message); return wakeup; } /** * chafa_wakeup_get_pollfd: * @wakeup: a #ChafaWakeup * @poll_fd: a #GPollFD * * Prepares a @poll_fd such that polling on it will succeed when * chafa_wakeup_signal() has been called on @wakeup. * * @poll_fd is valid until @wakeup is freed. * * Since: 2.30 **/ void chafa_wakeup_get_pollfd (ChafaWakeup *wakeup, GPollFD *poll_fd) { poll_fd->fd = wakeup->fds[0]; poll_fd->events = G_IO_IN; } /** * chafa_wakeup_acknowledge: * @wakeup: a #ChafaWakeup * * Acknowledges receipt of a wakeup signal on @wakeup. * * You must call this after @wakeup polls as ready. If not, it will * continue to poll as ready until you do so. * * If you call this function and @wakeup is not signaled, nothing * happens. * * Since: 2.30 **/ void chafa_wakeup_acknowledge (ChafaWakeup *wakeup) { char buffer[16]; /* read until it is empty */ while (read (wakeup->fds[0], buffer, sizeof buffer) == sizeof buffer); } /** * chafa_wakeup_signal: * @wakeup: a #ChafaWakeup * * Signals @wakeup. * * Any future (or present) polling on the #GPollFD returned by * chafa_wakeup_get_pollfd() will immediately succeed until such a time as * chafa_wakeup_acknowledge() is called. * * This function is safe to call from a UNIX signal handler. * * Since: 2.30 **/ void chafa_wakeup_signal (ChafaWakeup *wakeup) { int res; if (wakeup->fds[1] == -1) { guint64 one = 1; /* eventfd() case. It requires a 64-bit counter increment value to be * written. */ do res = write (wakeup->fds[0], &one, sizeof one); while (G_UNLIKELY (res == -1 && errno == EINTR)); } else { guint8 one = 1; /* Non-eventfd() case. Only a single byte needs to be written, and it can * have an arbitrary value. */ do res = write (wakeup->fds[1], &one, sizeof one); while (G_UNLIKELY (res == -1 && errno == EINTR)); } } /** * chafa_wakeup_free: * @wakeup: a #ChafaWakeup * * Frees @wakeup. * * You must not currently be polling on the #GPollFD returned by * chafa_wakeup_get_pollfd(), or the result is undefined. **/ void chafa_wakeup_free (ChafaWakeup *wakeup) { close (wakeup->fds[0]); if (wakeup->fds[1] != -1) close (wakeup->fds[1]); g_slice_free (ChafaWakeup, wakeup); } #endif /* !_WIN32 */ chafa-1.18.2/tools/chafa/chafa-wakeup.h000066400000000000000000000023561517447374300176010ustar00rootroot00000000000000/* * Copyright © 2011 Canonical Limited * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . * * Author: Ryan Lortie */ #ifndef __CHAFA_WAKEUP_H__ #define __CHAFA_WAKEUP_H__ #include G_BEGIN_DECLS typedef struct _ChafaWakeup ChafaWakeup; ChafaWakeup * chafa_wakeup_new (void); void chafa_wakeup_free (ChafaWakeup *wakeup); void chafa_wakeup_get_pollfd (ChafaWakeup *wakeup, GPollFD *poll_fd); void chafa_wakeup_signal (ChafaWakeup *wakeup); void chafa_wakeup_acknowledge (ChafaWakeup *wakeup); G_END_DECLS #endif chafa-1.18.2/tools/chafa/chafa.c000066400000000000000000001030661517447374300163020ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* strspn, strlen, strcmp, strncmp, memset */ #include /* setlocale */ #include /* open */ #include /* stat */ #include /* open */ #include /* STDOUT_FILENO */ #include /* exit */ #ifdef HAVE_SYS_IOCTL_H # include /* ioctl */ #endif #ifdef HAVE_SIGACTION # include /* sigaction */ #endif #ifdef HAVE_TERMIOS_H # include /* tcgetattr, tcsetattr */ #endif #if defined(HAVE_SYS_TIME_H) && defined(HAVE_SETITIMER) # include /* setitimer */ #endif #include #include "chafa-term.h" #include "chicle-font-loader.h" #include "chicle-grid-layout.h" #include "chicle-media-pipeline.h" #include "chicle-options.h" #include "chicle-path-queue.h" #include "chicle-placement-counter.h" #include "chicle-util.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #endif /* Maximum size of stack-allocated read/write buffer */ #define BUFFER_MAX 4096 /* If the user issues a SIGINT and we can't exit immediately, wait * this long for processing to finish before forcing an exit. */ #define EXIT_GRACE_USEC (500 * 1000) #ifdef G_OS_WIN32 /* Enable command line globbing on Windows. * * This is MinGW-specific. If you'd like it to work in MSVC, please get in * touch. There are a couple of glob-alikes floating around - for instance, * the one in MPV is portable and appropriately licensed. */ extern int _CRT_glob = 1; #endif static volatile sig_atomic_t interrupted_by_user = FALSE; static ChiclePlacementCounter *placement_counter; #ifdef HAVE_TERMIOS_H static struct termios saved_termios; #endif static gchar fast_exit_seq [CHAFA_TERM_SEQ_LENGTH_MAX + 4]; static void prepare_fast_exit (ChafaTermInfo *term_info) { gchar *p0; /* CAN, ST */ strcpy (fast_exit_seq, "\x18\x1b\x5c"); p0 = chafa_term_info_emit_enable_cursor (term_info, fast_exit_seq + strlen (fast_exit_seq)); *p0 = '\0'; } #ifdef HAVE_SIGACTION static void fast_exit (void) { /* Fast exit */ if (!options.polite) { G_GNUC_UNUSED volatile int result; #ifdef HAVE_TERMIOS_H if (options.is_interactive) { tcsetattr (STDIN_FILENO, TCSANOW, &saved_termios); } #endif /* There's nothing we can do if this fails. Work around * -Werror=unused-result. */ result = write (STDOUT_FILENO, fast_exit_seq, strlen (fast_exit_seq)); } exit (0); } static void sigalarm_handler (G_GNUC_UNUSED int sig) { fast_exit (); } static void install_fast_exit_alarm (void) { #ifdef HAVE_SETITIMER struct sigaction sa; struct itimerval itv; memset (&sa, 0, sizeof (sa)); memset (&itv, 0, sizeof (itv)); sa.sa_handler = sigalarm_handler; sa.sa_flags = SA_RESETHAND; sigaction (SIGALRM, &sa, NULL); itv.it_value.tv_usec = EXIT_GRACE_USEC; setitimer (ITIMER_REAL, &itv, NULL); #endif } static void install_interrupt_handler (void); static void sigint_handler (G_GNUC_UNUSED int sig) { if (interrupted_by_user) { fast_exit (); } else { install_interrupt_handler (); install_fast_exit_alarm (); } interrupted_by_user = TRUE; } static void install_interrupt_handler (void) { struct sigaction sa; memset (&sa, 0, sizeof (sa)); sa.sa_handler = sigint_handler; sa.sa_flags = 0; sigaction (SIGINT, &sa, NULL); } #endif static void interruptible_usleep (gdouble us) { while (us > 0.0 && !interrupted_by_user) { gdouble sleep_us = MIN (us, 50000.0); g_usleep (sleep_us); us -= sleep_us; } } static void tty_options_init (void) { if (!options.polite) { #ifdef HAVE_TERMIOS_H if (options.is_interactive) { struct termios t; tcgetattr (STDIN_FILENO, &saved_termios); t = saved_termios; t.c_lflag &= ~(ECHO | ICANON); tcsetattr (STDIN_FILENO, TCSANOW, &t); } #endif if (options.mode != CHAFA_CANVAS_MODE_FGBG) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_DISABLE_CURSOR, -1); } if (options.pixel_mode == CHAFA_PIXEL_MODE_SIXELS) { /* Most terminals should have sixel scrolling and advance-down enabled * by default, so we're not going to undo these later. */ chafa_term_print_seq (term, CHAFA_TERM_SEQ_ENABLE_SIXEL_SCROLLING, -1); chafa_term_print_seq (term, CHAFA_TERM_SEQ_SET_SIXEL_ADVANCE_DOWN, -1); } } } static void tty_options_deinit (void) { if (!options.polite) { if (options.mode != CHAFA_CANVAS_MODE_FGBG) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_ENABLE_CURSOR, -1); } #ifdef HAVE_TERMIOS_H if (options.is_interactive) { tcsetattr (STDIN_FILENO, TCSANOW, &saved_termios); } #endif } } static void pixel_to_cell_dimensions (gdouble scale, gint cell_width, gint cell_height, gint width, gint height, gint *width_out, gint *height_out) { /* Scale can't be zero or negative */ scale = MAX (scale, 0.00001); /* Zero or negative cell dimensions -> presumably unknown, use 10x20 */ if (cell_width < 1) cell_width = 10; if (cell_height < 1) cell_height = 20; if (width_out) { *width_out = ((int) (width * scale) + cell_width - 1) / cell_width; *width_out = MAX (*width_out, 1); } if (height_out) { *height_out = ((int) (height * scale) + cell_height - 1) / cell_height; *height_out = MAX (*height_out, 1); } } static void write_gstring_to_stdout (GString *gs) { chafa_term_write (term, gs->str, gs->len); } static void write_gstrings_to_stdout (GString **gsa) { gint i; for (i = 0; gsa [i]; i++) write_gstring_to_stdout (gsa [i]); } static void write_pad_spaces (gint n) { gchar buf [BUFFER_MAX]; gint i; g_assert (n >= 0); n = MIN (n, BUFFER_MAX); for (i = 0; i < n; i++) buf [i] = ' '; chafa_term_write (term, buf, n); } static void write_cursor_down_scroll_n (gint n) { gchar buf [BUFFER_MAX]; gchar *p0 = buf; if (n < 1) return; for ( ; n; n--) { p0 = chafa_term_info_emit_cursor_down_scroll (options.term_info, p0); if (p0 - buf + CHAFA_TERM_SEQ_LENGTH_MAX > BUFFER_MAX) { chafa_term_write (term, buf, p0 - buf); p0 = buf; } } chafa_term_write (term, buf, p0 - buf); } static void write_vertical_spaces (gint n) { gchar buf [BUFFER_MAX]; if (n < 1) return; if (options.relative) { write_cursor_down_scroll_n (n); return; } memset (buf, '\n', MIN (n, BUFFER_MAX)); for ( ; n > 0; n -= BUFFER_MAX) chafa_term_write (term, buf, MIN (n, BUFFER_MAX)); } static void write_image_prologue (const gchar *path, gboolean is_first_file, gboolean is_first_frame, gboolean is_animation, gint dest_height) { /* Insert a blank line between files in continuous (!clear) mode */ if (is_first_frame && !options.clear && !is_first_file) write_vertical_spaces (1 + (options.have_parking_row ? 0 : 1)); if (options.clear) { if (is_first_frame) { /* Clear */ chafa_term_print_seq (term, CHAFA_TERM_SEQ_CLEAR, -1); } /* Home cursor between frames */ chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_TO_TOP_LEFT, -1); } /* Insert space for vertical alignment */ if (options.clear || is_first_frame) write_vertical_spaces (options.vert_align == CHAFA_ALIGN_START ? 0 : options.vert_align == CHAFA_ALIGN_CENTER ? ((options.view_height - dest_height - options.margin_bottom) / 2) : (options.view_height - dest_height - options.margin_bottom)); if (!options.clear && is_animation && is_first_frame) { /* Start animation: reserve space and save image origin */ write_cursor_down_scroll_n (dest_height); chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_UP, dest_height, -1); chafa_term_print_seq (term, CHAFA_TERM_SEQ_SAVE_CURSOR_POS, -1); /* Print label before animation starts */ if (options.label) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_DOWN, dest_height, -1); chicle_path_print_label (term, path, options.horiz_align, options.view_width, options.use_unicode, options.link_labels != CHICLE_TRISTATE_FALSE ? TRUE : FALSE); chafa_term_print_seq (term, CHAFA_TERM_SEQ_RESTORE_CURSOR_POS, -1); } } else if (!options.clear && !is_first_frame) { /* Subsequent animation frames: cursor to image origin */ chafa_term_print_seq (term, CHAFA_TERM_SEQ_RESTORE_CURSOR_POS, -1); } } static void write_image_epilogue (const gchar *path, gboolean is_animation, gint dest_width) { gint left_space; left_space = options.horiz_align == CHAFA_ALIGN_START ? 0 : options.horiz_align == CHAFA_ALIGN_CENTER ? ((options.view_width - dest_width - options.margin_right) / 2) : (options.view_width - dest_width - options.margin_right); /* These modes leave cursor to the right of the bottom row */ if (options.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS || options.pixel_mode == CHAFA_PIXEL_MODE_KITTY || options.pixel_mode == CHAFA_PIXEL_MODE_ITERM2) { if (options.have_parking_row) { write_vertical_spaces (1); } else if (!options.relative) { /* Windows needs an explicit CR in absolute mode */ chafa_term_write (term, "\r", 1); } if (options.relative) chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_LEFT, left_space + dest_width, -1); if (options.label) { if (!is_animation) { chicle_path_print_label (term, path, options.horiz_align, options.view_width, options.use_unicode, options.link_labels != CHICLE_TRISTATE_FALSE ? TRUE : FALSE); if (options.relative) chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_LEFT, options.view_width, -1); } write_vertical_spaces (1); } } else /* CHAFA_PIXEL_MODE_SIXELS */ { /* Sixel mode leaves the cursor in the leftmost column of the final band, * but some terminals have a quirk where they'll leave it on the row * below. */ if (!(chafa_term_info_get_quirks (chafa_term_get_term_info (term)) & CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT) && options.have_parking_row) write_vertical_spaces (1); if (options.relative && left_space > 0) chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_LEFT, left_space, -1); if (options.label) { if (!is_animation) { if (!options.relative) chafa_term_write (term, "\r", 1); chicle_path_print_label (term, path, options.horiz_align, options.view_width, options.use_unicode, options.link_labels != CHICLE_TRISTATE_FALSE ? TRUE : FALSE); if (options.relative) chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_LEFT, options.view_width, -1); } write_vertical_spaces (1); } } } /* Write out the image data, possibly centering it */ static void write_image (GString **gsa, gint dest_width) { gint left_space; left_space = options.horiz_align == CHAFA_ALIGN_START ? 0 : options.horiz_align == CHAFA_ALIGN_CENTER ? ((options.view_width - dest_width - options.margin_right) / 2) : (options.view_width - dest_width - options.margin_right); left_space = MAX (left_space, 0); /* Indent top left corner: Common for all modes */ if (options.relative && left_space > 0) chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_RIGHT, left_space, -1); else write_pad_spaces (left_space); if (options.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) { gint i; /* Indent subsequent rows: Symbols mode only */ for (i = 0; gsa [i]; i++) { write_gstring_to_stdout (gsa [i]); if (gsa [i + 1]) { if (options.relative) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_LEFT, left_space + dest_width, -1); chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL, -1); if (left_space > 0) chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_RIGHT, left_space, -1); } else { chafa_term_write (term, "\n", 1); write_pad_spaces (left_space); } } } } else { write_gstrings_to_stdout (gsa); } } static ChafaCanvasConfig * build_config (gint dest_width, gint dest_height, gboolean is_animation) { ChafaCanvasConfig *config; config = chafa_canvas_config_new (); chafa_canvas_config_set_geometry (config, dest_width, dest_height); chafa_canvas_config_set_canvas_mode (config, options.mode); chafa_canvas_config_set_pixel_mode (config, options.pixel_mode); chafa_canvas_config_set_dither_mode (config, options.dither_mode); chafa_canvas_config_set_dither_grain_size (config, options.dither_grain_width, options.dither_grain_height); chafa_canvas_config_set_dither_intensity (config, options.dither_intensity); chafa_canvas_config_set_color_extractor (config, options.color_extractor); chafa_canvas_config_set_color_space (config, options.color_space); chafa_canvas_config_set_fg_color (config, options.fg_color); chafa_canvas_config_set_bg_color (config, options.bg_color); chafa_canvas_config_set_preprocessing_enabled (config, options.preprocess); chafa_canvas_config_set_fg_only_enabled (config, options.fg_only); chafa_canvas_config_set_passthrough (config, options.passthrough); /* With Kitty and sixels, animation frames should have an opaque background. * Otherwise, previous frames will show through transparent areas. */ if (is_animation && (options.pixel_mode == CHAFA_PIXEL_MODE_KITTY || options.pixel_mode == CHAFA_PIXEL_MODE_SIXELS) && !options.transparency_threshold_set) chafa_canvas_config_set_transparency_threshold (config, 1.0f); else if (options.transparency_threshold >= 0.0) chafa_canvas_config_set_transparency_threshold (config, options.transparency_threshold); if (options.cell_width > 0 && options.cell_height > 0) chafa_canvas_config_set_cell_geometry (config, options.cell_width, options.cell_height); chafa_canvas_config_set_symbol_map (config, options.symbol_map); chafa_canvas_config_set_fill_symbol_map (config, options.fill_symbol_map); /* Work switch takes values [1..9], we normalize to [0.0..1.0] to * get the work factor. */ chafa_canvas_config_set_work_factor (config, (options.work_factor - 1) / 8.0f); chafa_canvas_config_set_optimizations (config, options.optimizations); return config; } static ChafaCanvas * build_canvas (ChafaPixelType pixel_type, const guint8 *pixels, gint src_width, gint src_height, gint src_rowstride, const ChafaCanvasConfig *config, gint placement_id, ChafaTuck tuck) { ChafaFrame *frame; ChafaImage *image; ChafaPlacement *placement; ChafaCanvas *canvas; canvas = chafa_canvas_new (config); frame = chafa_frame_new_borrow (pixels, pixel_type, src_width, src_height, src_rowstride); image = chafa_image_new (); chafa_image_set_frame (image, frame); placement = chafa_placement_new (image, placement_id); chafa_placement_set_tuck (placement, tuck); chafa_placement_set_halign (placement, options.horiz_align); chafa_placement_set_valign (placement, options.vert_align); chafa_canvas_set_placement (canvas, placement); chafa_placement_unref (placement); chafa_image_unref (image); chafa_frame_unref (frame); return canvas; } typedef enum { FILE_FAILED, FILE_WAS_STILL, FILE_WAS_ANIMATION } RunResult; /* Prescaling is for structured formats like SVG where the intrinsic size may be * too small or too large and we'd rather rasterize to something closer to our * final output size. */ static void calc_prescale_size_px (gint *prescale_width_out, gint *prescale_height_out) { gint cell_width_px, cell_height_px; if (options.cell_width <= 0 || options.cell_height <= 0) { cell_width_px = 10; cell_height_px = 20; } else { cell_width_px = options.cell_width; cell_height_px = options.cell_height; } *prescale_width_out = cell_width_px * (options.width > 0 ? options.width : options.view_width); *prescale_height_out = cell_height_px * (options.height > 0 ? options.height : options.view_height); *prescale_width_out = MAX (*prescale_width_out, 160); *prescale_height_out = MAX (*prescale_height_out, 160); } static RunResult run_generic (const gchar *filename, ChicleMediaLoader *media_loader, gboolean is_first_file, gboolean is_first_frame) { gboolean is_animation = FALSE; gdouble anim_duration_s = options.file_duration_s >= 0.0 ? options.file_duration_s : G_MAXDOUBLE; gdouble anim_elapsed_s = 0.0; GTimer *timer; gint loop_n = 0; GString **gsa; gint placement_id = -1; gint frame_count = 0; RunResult result = FILE_FAILED; gint dest_width = 0, dest_height = 0; GError *error = NULL; timer = g_timer_new (); if (interrupted_by_user) goto out; if (options.pixel_mode == CHAFA_PIXEL_MODE_KITTY && options.passthrough != CHAFA_PASSTHROUGH_NONE) { if (!placement_counter) placement_counter = chicle_placement_counter_new (); placement_id = chicle_placement_counter_get_next_id (placement_counter); } is_animation = options.animate ? chicle_media_loader_get_is_animation (media_loader) : FALSE; result = is_animation ? FILE_WAS_ANIMATION : FILE_WAS_STILL; do { gboolean have_frame; /* Outer loop repeats animation if desired */ chicle_media_loader_goto_first_frame (media_loader); for (have_frame = TRUE; have_frame && !interrupted_by_user && (loop_n == 0 || anim_elapsed_s < anim_duration_s); have_frame = chicle_media_loader_goto_next_frame (media_loader)) { gdouble elapsed_ms, remain_ms; gint delay_ms; ChafaPixelType pixel_type; gint src_width, src_height, src_rowstride; gint uncorrected_src_width, uncorrected_src_height; gint virt_src_width, virt_src_height; const guint8 *pixels; ChafaCanvasConfig *config; ChafaCanvas *canvas; ChafaTuck tuck; g_timer_start (timer); if (options.use_exact_size == CHICLE_TRISTATE_TRUE) { /* True */ tuck = CHAFA_TUCK_SHRINK_TO_FIT; } else { /* False/auto */ if (options.stretch) { tuck = CHAFA_TUCK_STRETCH; } else { tuck = CHAFA_TUCK_FIT; } } pixels = chicle_media_loader_get_frame_data (media_loader, &pixel_type, &src_width, &src_height, &src_rowstride); /* FIXME: This shouldn't happen -- but if it does, our * options for handling it gracefully here aren't great. * Needs refactoring. */ if (!pixels) break; delay_ms = chicle_media_loader_get_frame_delay (media_loader); /* Hack to work around the fact that chafa_calc_canvas_geometry() doesn't * support arbitrary scaling. Instead, we manipulate the source size to * achieve the desired effect. */ if (using_detected_size && options.scale < CHICLE_SCALE_MAX - 0.1) { pixel_to_cell_dimensions (options.scale, options.cell_width, options.cell_height, src_width, src_height, &uncorrected_src_width, &uncorrected_src_height); virt_src_width = uncorrected_src_width; if (options.cell_width > 0 && options.cell_height > 0) virt_src_height = uncorrected_src_height / options.font_ratio; else virt_src_height = uncorrected_src_height; virt_src_height = MAX (virt_src_height, 1); } else { virt_src_width = uncorrected_src_width = src_width; virt_src_height = uncorrected_src_height = src_height; } if (options.use_exact_size == CHICLE_TRISTATE_TRUE) { dest_width = virt_src_width; dest_height = virt_src_height; } else { dest_width = options.width; dest_height = options.height; } chafa_calc_canvas_geometry (virt_src_width, virt_src_height, &dest_width, &dest_height, options.font_ratio, options.scale >= CHICLE_SCALE_MAX - 0.1 ? TRUE : FALSE, options.stretch); if (options.use_exact_size == CHICLE_TRISTATE_AUTO && dest_width == uncorrected_src_width && dest_height == uncorrected_src_height) { tuck = (options.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS ? CHAFA_TUCK_FIT : CHAFA_TUCK_SHRINK_TO_FIT); } #if 0 /* The size calculations are too convoluted, so we may need this to * debug --exact-size. */ g_printerr ("src=(%dx%d) unc=(%dx%d) virt=(%dx%d) dest=(%dx%d)\n", src_width, src_height, uncorrected_src_width, uncorrected_src_height, virt_src_width, virt_src_height, dest_width, dest_height); #endif config = build_config (dest_width, dest_height, is_animation); canvas = build_canvas (pixel_type, pixels, src_width, src_height, src_rowstride, config, placement_id >= 0 ? placement_id + ((frame_count++) % 2) : -1, tuck); chafa_canvas_print_rows (canvas, options.term_info, &gsa, NULL); write_image_prologue (filename, is_first_file, is_first_frame, is_animation, dest_height); write_image (gsa, dest_width); /* No inter-frame epilogue in animations; this prevents unwanted * scrolling when we get the sixel overshoot quirk wrong (#255). */ if (!is_animation) write_image_epilogue (filename, is_animation, dest_width); chafa_term_flush (term); chafa_free_gstring_array (gsa); chafa_canvas_unref (canvas); chafa_canvas_config_unref (config); if (is_animation) { /* Account for time spent converting and printing frame */ elapsed_ms = g_timer_elapsed (timer, NULL) * 1000.0; if (options.anim_fps > 0.0) remain_ms = 1000.0 / options.anim_fps; else remain_ms = delay_ms; remain_ms /= options.anim_speed_multiplier; remain_ms = MAX (remain_ms - elapsed_ms, 0); if (remain_ms > 0.0001 && 1000.0 / (gdouble) remain_ms < CHICLE_ANIM_FPS_MAX) interruptible_usleep (remain_ms * 1000.0); anim_elapsed_s += MAX (elapsed_ms, delay_ms) / 1000.0; } is_first_frame = FALSE; if (!is_animation) break; } loop_n++; } while (is_animation && !interrupted_by_user && !options.watch && anim_elapsed_s < anim_duration_s); if (is_animation) write_image_epilogue (filename, is_animation, dest_width); out: /* We need two IDs per animation in order to do flicker-free flips. If the * final frame got the higher ID, increment the global counter so the next * image doesn't clobber it. */ if (placement_id >= 0 && !(frame_count % 2)) placement_id = chicle_placement_counter_get_next_id (placement_counter); g_timer_destroy (timer); g_clear_error (&error); return result; } static int run_watch (const gchar *filename) { GTimer *timer; gboolean is_first_frame = TRUE; gdouble duration_s = options.file_duration_s >= 0.0 ? options.file_duration_s : G_MAXDOUBLE; gint prescale_width, prescale_height; calc_prescale_size_px (&prescale_width, &prescale_height); timer = g_timer_new (); for ( ; !interrupted_by_user; ) { struct stat sbuf; if (!stat (filename, &sbuf)) { ChicleMediaLoader *media_loader; /* Sadly we can't rely on timestamps to tell us when to reload * the file, since they can take way too long to update. */ media_loader = chicle_media_loader_new (filename, prescale_width, prescale_height, NULL); if (media_loader) { run_generic (filename, media_loader, TRUE, is_first_frame); chicle_media_loader_destroy (media_loader); } is_first_frame = FALSE; g_usleep (10000); } else { /* Don't hammer the path if the file is temporarily gone */ g_usleep (250000); } if (g_timer_elapsed (timer, NULL) > duration_s) break; } g_timer_destroy (timer); return 0; } static int run_vertical (ChiclePathQueue *path_queue) { ChicleMediaPipeline *pipeline; gdouble still_duration_s = options.file_duration_s > 0.0 ? options.file_duration_s : 0.0; gint n_processed = 0; gint n_failed = 0; gint prescale_width, prescale_height; calc_prescale_size_px (&prescale_width, &prescale_height); pipeline = chicle_media_pipeline_new (path_queue, prescale_width, prescale_height); chicle_media_pipeline_set_want_loader (pipeline, TRUE); chicle_media_pipeline_set_want_output (pipeline, FALSE); while (!interrupted_by_user) { gchar *path = NULL; ChicleMediaLoader *media_loader = NULL; GError *error = NULL; RunResult result; if (!chicle_media_pipeline_pop (pipeline, &path, &media_loader, NULL, &error)) break; n_processed++; if (!media_loader) { if (error) { gchar *safe_path = path ? g_strdup (path) : NULL; if (safe_path) chicle_flatten_cntrl_inplace (safe_path); g_printerr ("%s: Failed to open '%s': %s\n", options.executable_name, safe_path ? safe_path : "?", error->message); g_free (safe_path); g_error_free (error); } g_free (path); n_failed++; continue; } result = run_generic (path, media_loader, n_processed > 1 ? FALSE : TRUE, TRUE); if (result == FILE_FAILED) n_failed++; if (result == FILE_WAS_STILL && still_duration_s > 0.0) { interruptible_usleep (still_duration_s * 1000000.0); } chicle_media_loader_destroy (media_loader); g_free (path); } /* Emit linefeed after last image when cursor was not in parking row */ if (!options.have_parking_row) chafa_term_write (term, "\n", 1); /* Zero files processed is not a failure, since we may be processing an * empty file list. */ return (n_failed > 0 && n_failed == n_processed) ? 2 : (n_failed > 0) ? 1 : 0; } static gint run_grid (ChiclePathQueue *path_queue) { ChafaCanvasConfig *canvas_config; ChicleGridLayout *grid_layout; /* The prototype canvas' size isn't used for anything; set it to a legal value */ canvas_config = build_config (1, 1, FALSE); grid_layout = chicle_grid_layout_new (); chicle_grid_layout_set_view_size (grid_layout, options.width, options.height); chicle_grid_layout_set_grid_size (grid_layout, options.grid_width, options.grid_height); chicle_grid_layout_set_canvas_config (grid_layout, canvas_config); chicle_grid_layout_set_term_info (grid_layout, options.term_info); chicle_grid_layout_set_align (grid_layout, options.horiz_align, options.vert_align); chicle_grid_layout_set_tuck (grid_layout, options.use_exact_size == CHICLE_TRISTATE_TRUE ? CHAFA_TUCK_SHRINK_TO_FIT : (options.stretch ? CHAFA_TUCK_STRETCH : CHAFA_TUCK_FIT)); chicle_grid_layout_set_print_labels (grid_layout, options.label); chicle_grid_layout_set_link_labels (grid_layout, options.link_labels != CHICLE_TRISTATE_FALSE ? TRUE : FALSE); chicle_grid_layout_set_use_unicode (grid_layout, options.use_unicode); chicle_grid_layout_set_path_queue (grid_layout, path_queue); while (!interrupted_by_user && chicle_grid_layout_print_chunk (grid_layout, term)) ; chafa_canvas_config_unref (canvas_config); chicle_grid_layout_destroy (grid_layout); return 0; } static void proc_init (void) { #ifdef HAVE_SIGACTION install_interrupt_handler (); #endif #ifdef G_OS_WIN32 setmode (fileno (stdin), O_BINARY); setmode (fileno (stdout), O_BINARY); #endif /* Must do this early. Buffer size probably doesn't matter */ setvbuf (stdout, NULL, _IOFBF, 32768); setlocale (LC_ALL, ""); /* Chafa may create and destroy GThreadPools multiple times while rendering * an image. This reduces thread churn and saves a decent amount of CPU. */ g_thread_pool_set_max_unused_threads (-1); global_path_queue = chicle_path_queue_new (); } int main (int argc, char *argv []) { int ret = 0; proc_init (); if (!chicle_parse_options (&argc, &argv)) { ret = 2; goto out; } if (options.args) { chicle_path_queue_push_path_list_steal (global_path_queue, options.args); options.args = NULL; } /* --version and --help can skip all the init/deinit stuff */ if (options.skip_processing || chicle_path_queue_get_length (global_path_queue) == 0) goto out; prepare_fast_exit (options.term_info); tty_options_init (); if (options.grid_width > 0 || options.grid_height > 0) { ret = run_grid (global_path_queue); } else if (options.watch) { gchar *path = chicle_path_queue_try_pop (global_path_queue); if (path) { ret = run_watch (path); g_free (path); } } else { ret = run_vertical (global_path_queue); } tty_options_deinit (); out: if (term) chafa_term_destroy (term); chicle_retire_passthrough_workarounds_tmux (); if (placement_counter) chicle_placement_counter_destroy (placement_counter); if (options.symbol_map) chafa_symbol_map_unref (options.symbol_map); if (options.fill_symbol_map) chafa_symbol_map_unref (options.fill_symbol_map); if (options.term_info) chafa_term_info_unref (options.term_info); chicle_path_queue_unref (global_path_queue); return ret; } chafa-1.18.2/tools/chafa/chicle-avif-loader.c000066400000000000000000000202701517447374300206510ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "chicle-avif-loader.h" #include "chicle-util.h" #define N_CHANNELS 4 #define BYTES_PER_PIXEL N_CHANNELS #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) struct ChicleAvifLoader { ChicleFileMapping *mapping; gconstpointer file_data; size_t file_data_len; gpointer frame_data; guint width, height; guint rowstride; avifDecoder *decoder; gint current_frame_index; guint frame_is_decoded : 1; guint frame_is_success : 1; }; static ChicleRotationType rotation [4] [3] = { { CHICLE_ROTATION_180_MIRROR, CHICLE_ROTATION_0_MIRROR, CHICLE_ROTATION_NONE }, { CHICLE_ROTATION_270_MIRROR, CHICLE_ROTATION_90_MIRROR, CHICLE_ROTATION_270 }, { CHICLE_ROTATION_0_MIRROR, CHICLE_ROTATION_180_MIRROR, CHICLE_ROTATION_180 }, { CHICLE_ROTATION_90_MIRROR, CHICLE_ROTATION_270_MIRROR, CHICLE_ROTATION_90 } }; static ChicleRotationType calc_rotation (avifTransformFlags tflags, guint angle, guint axis) { guint8 rot, mir; if (angle > 3 || axis > 1) return CHICLE_ROTATION_NONE; rot = (tflags & AVIF_TRANSFORM_IROT) ? angle : 0; mir = (tflags & AVIF_TRANSFORM_IMIR) ? axis : 2; return rotation [rot] [mir]; } static gboolean maybe_decode_frame (ChicleAvifLoader *loader) { avifResult avif_result; avifImage *image; avifRGBImage rgb; guint axis; if (loader->frame_is_decoded) return loader->frame_is_success; loader->frame_is_success = FALSE; rgb.pixels = NULL; avif_result = avifDecoderNextImage (loader->decoder); if (avif_result != AVIF_RESULT_OK) goto out; image = loader->decoder->image; avifRGBImageSetDefaults (&rgb, image); rgb.depth = 8; rgb.format = AVIF_RGB_FORMAT_RGBA; rgb.rowBytes = image->width * BYTES_PER_PIXEL; rgb.pixels = g_malloc (image->height * rgb.rowBytes); avif_result = avifImageYUVToRGB(image, &rgb); if (avif_result != AVIF_RESULT_OK) goto out; loader->width = image->width; loader->height = image->height; loader->rowstride = rgb.rowBytes; g_free (loader->frame_data); loader->frame_data = rgb.pixels; #if AVIF_VERSION_MAJOR >= 1 axis = image->imir.axis; #else axis = image->imir.mode; #endif chicle_rotate_image (&loader->frame_data, &loader->width, &loader->height, &loader->rowstride, N_CHANNELS, calc_rotation (image->transformFlags, image->irot.angle, axis)); loader->frame_is_decoded = TRUE; loader->frame_is_success = TRUE; out: if (!loader->frame_is_success) { g_free (rgb.pixels); } return loader->frame_is_success; } static ChicleAvifLoader * chicle_avif_loader_new (void) { return g_new0 (ChicleAvifLoader, 1); } ChicleAvifLoader * chicle_avif_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleAvifLoader *loader = NULL; gboolean success = FALSE; avifResult avif_result; avifImage *image; g_return_val_if_fail (mapping != NULL, NULL); /* Quick check for the ISOBMFF ftyp box to filter out files that are * something else entirely */ if (!chicle_file_mapping_has_magic (mapping, 4, "ftyp", 4)) goto out; loader = chicle_avif_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; loader->decoder = avifDecoderCreate (); /* Allow for missing PixelInformationProperty, invalid clap box and * missing ImageSpatialExtentsProperty in alpha auxiliary image items */ loader->decoder->strictFlags = AVIF_STRICT_DISABLED; avif_result = avifDecoderSetIOMemory (loader->decoder, loader->file_data, loader->file_data_len); if (avif_result != AVIF_RESULT_OK) goto out; avif_result = avifDecoderParse (loader->decoder); if (avif_result != AVIF_RESULT_OK) goto out; image = loader->decoder->image; if (image->width < 1 || image->width >= (1 << 28) || image->height < 1 || image->height >= (1 << 28)) goto out; loader->width = image->width; loader->height = image->height; loader->rowstride = loader->width * BYTES_PER_PIXEL; if (loader->height * loader->rowstride > IMAGE_BUFFER_SIZE_MAX) goto out; /* Ensure we can decode a frame. If not, we'll try other loaders */ if (!maybe_decode_frame (loader)) goto out; success = TRUE; out: if (!success) { if (loader) { if (loader->decoder) { avifDecoderDestroy (loader->decoder); loader->decoder = NULL; } g_free (loader); loader = NULL; } } return loader; } void chicle_avif_loader_destroy (ChicleAvifLoader *loader) { if (loader->decoder) avifDecoderDestroy (loader->decoder); if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->frame_data) g_free (loader->frame_data); g_free (loader); } gboolean chicle_avif_loader_get_is_animation (ChicleAvifLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return loader->decoder->imageCount > 1 ? TRUE : FALSE; } gconstpointer chicle_avif_loader_get_frame_data (ChicleAvifLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (!maybe_decode_frame (loader)) return NULL; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (pixel_type_out) *pixel_type_out = CHAFA_PIXEL_RGBA8_UNASSOCIATED; if (rowstride_out) *rowstride_out = loader->rowstride; return loader->frame_data; } gint chicle_avif_loader_get_frame_delay (ChicleAvifLoader *loader) { gdouble duration_s; g_return_val_if_fail (loader != NULL, 0); duration_s = loader->decoder->imageTiming.duration; /* NaN or very small? */ if (duration_s != duration_s || duration_s < 0.000001) duration_s = 0.05; /* Infinite or very big? Set frame duration to a bit more than a day's time. */ if (duration_s > 99999.0) duration_s = 99999.0; return duration_s * 1000.0; } void chicle_avif_loader_goto_first_frame (ChicleAvifLoader *loader) { g_return_if_fail (loader != NULL); if (loader->current_frame_index == 0) return; loader->current_frame_index = 0; loader->frame_is_decoded = FALSE; loader->frame_is_success = FALSE; avifDecoderReset (loader->decoder); } gboolean chicle_avif_loader_goto_next_frame (ChicleAvifLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); if (loader->current_frame_index + 1 >= (gint) loader->decoder->imageCount) return FALSE; loader->current_frame_index++; loader->frame_is_decoded = FALSE; loader->frame_is_success = FALSE; return TRUE; } chafa-1.18.2/tools/chafa/chicle-avif-loader.h000066400000000000000000000035311517447374300206570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_AVIF_LOADER_H__ #define __CHICLE_AVIF_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleAvifLoader ChicleAvifLoader; ChicleAvifLoader *chicle_avif_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_avif_loader_destroy (ChicleAvifLoader *loader); gboolean chicle_avif_loader_get_is_animation (ChicleAvifLoader *loader); gconstpointer chicle_avif_loader_get_frame_data (ChicleAvifLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_avif_loader_get_frame_delay (ChicleAvifLoader *loader); void chicle_avif_loader_goto_first_frame (ChicleAvifLoader *loader); gboolean chicle_avif_loader_goto_next_frame (ChicleAvifLoader *loader); G_END_DECLS #endif /* __CHICLE_AVIF_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-coregraphics-loader.c000066400000000000000000000302041517447374300223730ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * Author: Hayaki Saio * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include "chicle-coregraphics-loader.h" #include "chicle-util.h" #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) #define ROWSTRIDE_ALIGN 16 #define PAD_TO_N(p, n) (((p) + ((n) - 1)) & ~((unsigned) (n) - 1)) #define ROWSTRIDE_PAD(rowstride) (PAD_TO_N ((rowstride), (ROWSTRIDE_ALIGN))) #define DEFAULT_FRAME_DELAY_MS 100 #if G_BYTE_ORDER == G_BIG_ENDIAN # define BITMAP_INFO (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big) # define PIXEL_TYPE CHAFA_PIXEL_ARGB8_PREMULTIPLIED #else # define BITMAP_INFO (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little) # define PIXEL_TYPE CHAFA_PIXEL_BGRA8_PREMULTIPLIED #endif struct _ChicleCoreGraphicsLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; CFDataRef cf_data; CGImageSourceRef image_source; guint frame_index; guint frame_count; guint is_animation : 1; guint frame_ready : 1; guchar *frame_data; gint width; gint height; gint rowstride; gint frame_delay_ms; }; static ChicleCoreGraphicsLoader *chicle_coregraphics_loader_new (void); static gboolean ensure_frame_ready (ChicleCoreGraphicsLoader *loader); static gboolean decode_frame (ChicleCoreGraphicsLoader *loader); static ChicleRotationType extract_orientation (CFDictionaryRef properties); static gdouble extract_frame_delay (CFDictionaryRef properties); static gdouble get_delay_from_dictionary (CFDictionaryRef dict, CFStringRef unclamped_key, CFStringRef clamped_key); static ChicleCoreGraphicsLoader * chicle_coregraphics_loader_new (void) { return g_new0 (ChicleCoreGraphicsLoader, 1); } ChicleCoreGraphicsLoader * chicle_coregraphics_loader_new_from_mapping (ChicleFileMapping *mapping, G_GNUC_UNUSED gint target_width, G_GNUC_UNUSED gint target_height) { ChicleCoreGraphicsLoader *loader = NULL; gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); loader = chicle_coregraphics_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; loader->cf_data = CFDataCreateWithBytesNoCopy (kCFAllocatorDefault, loader->file_data, (CFIndex) loader->file_data_len, kCFAllocatorNull); if (!loader->cf_data) goto out; loader->image_source = CGImageSourceCreateWithData (loader->cf_data, NULL); if (!loader->image_source) goto out; loader->frame_count = (guint) CGImageSourceGetCount (loader->image_source); if (loader->frame_count < 1) goto out; if (loader->frame_count > 1) loader->is_animation = TRUE; success = TRUE; out: if (!success) { if (loader) { if (loader->image_source) CFRelease (loader->image_source); loader->image_source = NULL; if (loader->cf_data) CFRelease (loader->cf_data); loader->cf_data = NULL; loader->mapping = NULL; /* Ownership stays with caller */ g_free (loader); loader = NULL; } } return loader; } void chicle_coregraphics_loader_destroy (ChicleCoreGraphicsLoader *loader) { if (!loader) return; if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->image_source) CFRelease (loader->image_source); if (loader->cf_data) CFRelease (loader->cf_data); g_free (loader->frame_data); g_free (loader); } static gboolean ensure_frame_ready (ChicleCoreGraphicsLoader *loader) { if (!loader->frame_ready) { if (!decode_frame (loader)) return FALSE; } return TRUE; } static gboolean decode_frame (ChicleCoreGraphicsLoader *loader) { CGColorSpaceRef color_space = NULL; CGContextRef context = NULL; CGImageRef image = NULL; CFDictionaryRef properties = NULL; gpointer pixel_ptr; guchar *pixels = NULL; size_t width, height, rowstride; guint width_u, height_u, rowstride_u; gdouble delay_seconds; gboolean success = FALSE; image = CGImageSourceCreateImageAtIndex (loader->image_source, loader->frame_index, NULL); if (!image) goto out; width = CGImageGetWidth (image); height = CGImageGetHeight (image); if (width < 1 || width >= (1u << 28) || height < 1 || height >= (1u << 28)) goto out; rowstride = ROWSTRIDE_PAD (width * BYTES_PER_PIXEL); if (height > 0 && ((guint64) rowstride * (guint64) height) > IMAGE_BUFFER_SIZE_MAX) goto out; pixels = g_malloc ((gsize) rowstride * (gsize) height); color_space = CGColorSpaceCreateDeviceRGB (); if (!color_space) goto out; context = CGBitmapContextCreate (pixels, width, height, 8, rowstride, color_space, BITMAP_INFO); if (!context) goto out; CGContextDrawImage (context, CGRectMake (0, 0, width, height), image); properties = CGImageSourceCopyPropertiesAtIndex (loader->image_source, loader->frame_index, NULL); pixel_ptr = pixels; width_u = (guint) width; height_u = (guint) height; rowstride_u = (guint) rowstride; chicle_rotate_image (&pixel_ptr, &width_u, &height_u, &rowstride_u, BYTES_PER_PIXEL, chicle_invert_rotation (extract_orientation (properties))); pixels = pixel_ptr; delay_seconds = extract_frame_delay (properties); g_free (loader->frame_data); loader->frame_data = pixels; loader->width = (gint) width_u; loader->height = (gint) height_u; loader->rowstride = (gint) rowstride_u; loader->frame_delay_ms = 0; if (delay_seconds > 0.0) { gdouble delay_ms = delay_seconds * 1000.0; if (delay_ms > (gdouble) G_MAXINT) loader->frame_delay_ms = G_MAXINT; else loader->frame_delay_ms = (gint) (delay_ms + 0.5); } else if (loader->is_animation) { loader->frame_delay_ms = DEFAULT_FRAME_DELAY_MS; } loader->frame_ready = TRUE; pixels = NULL; /* Ownership moved to loader */ success = TRUE; out: if (!success && pixels) g_free (pixels); if (properties) CFRelease (properties); if (context) CGContextRelease (context); if (color_space) CGColorSpaceRelease (color_space); if (image) CGImageRelease (image); if (!success) { loader->frame_ready = FALSE; loader->frame_delay_ms = 0; } return success; } gboolean chicle_coregraphics_loader_get_is_animation (ChicleCoreGraphicsLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return loader->is_animation ? TRUE : FALSE; } gconstpointer chicle_coregraphics_loader_get_frame_data (ChicleCoreGraphicsLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (!ensure_frame_ready (loader)) return NULL; if (pixel_type_out) *pixel_type_out = PIXEL_TYPE; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->rowstride; return loader->frame_data; } gint chicle_coregraphics_loader_get_frame_delay (ChicleCoreGraphicsLoader *loader) { g_return_val_if_fail (loader != NULL, 0); if (!ensure_frame_ready (loader)) return 0; return loader->frame_delay_ms; } void chicle_coregraphics_loader_goto_first_frame (ChicleCoreGraphicsLoader *loader) { g_return_if_fail (loader != NULL); loader->frame_index = 0; loader->frame_ready = FALSE; loader->frame_delay_ms = 0; if (loader->frame_data) { g_free (loader->frame_data); loader->frame_data = NULL; } } gboolean chicle_coregraphics_loader_goto_next_frame (ChicleCoreGraphicsLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); if (loader->frame_index + 1 >= loader->frame_count) return FALSE; loader->frame_index++; loader->frame_ready = FALSE; loader->frame_delay_ms = 0; if (loader->frame_data) { g_free (loader->frame_data); loader->frame_data = NULL; } return TRUE; } static ChicleRotationType extract_orientation (CFDictionaryRef properties) { ChicleRotationType rotation = CHICLE_ROTATION_NONE; if (properties) { const void *value = CFDictionaryGetValue (properties, kCGImagePropertyOrientation); if (value && CFGetTypeID (value) == CFNumberGetTypeID ()) { gint orientation = 0; if (CFNumberGetValue ((CFNumberRef) value, kCFNumberIntType, &orientation) && orientation > CHICLE_ROTATION_NONE && orientation < CHICLE_ROTATION_UNDEFINED) { rotation = (ChicleRotationType) orientation; } } } return rotation; } static gdouble get_delay_from_dictionary (CFDictionaryRef dict, CFStringRef unclamped_key, CFStringRef clamped_key) { gdouble delay = 0.0; const void *value; if (!dict) return 0.0; value = CFDictionaryGetValue (dict, unclamped_key); if (value && CFGetTypeID (value) == CFNumberGetTypeID ()) { if (CFNumberGetValue ((CFNumberRef) value, kCFNumberDoubleType, &delay) && delay > 0.0) return delay; } value = CFDictionaryGetValue (dict, clamped_key); if (value && CFGetTypeID (value) == CFNumberGetTypeID ()) { if (CFNumberGetValue ((CFNumberRef) value, kCFNumberDoubleType, &delay) && delay > 0.0) return delay; } return 0.0; } static gdouble extract_frame_delay (CFDictionaryRef properties) { gdouble delay = 0.0; if (!properties) return 0.0; const void *dict_value = CFDictionaryGetValue (properties, kCGImagePropertyGIFDictionary); if (dict_value && CFGetTypeID (dict_value) == CFDictionaryGetTypeID ()) { delay = get_delay_from_dictionary ((CFDictionaryRef) dict_value, kCGImagePropertyGIFUnclampedDelayTime, kCGImagePropertyGIFDelayTime); if (delay > 0.0) return delay; } return 0.0; } chafa-1.18.2/tools/chafa/chicle-coregraphics-loader.h000066400000000000000000000043531517447374300224060ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * Author: Hayaki Saio * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_COREGRAPHICS_LOADER_H__ #define __CHICLE_COREGRAPHICS_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct _ChicleCoreGraphicsLoader ChicleCoreGraphicsLoader; ChicleCoreGraphicsLoader *chicle_coregraphics_loader_new_from_mapping (ChicleFileMapping *mapping, gint target_width, gint target_height); void chicle_coregraphics_loader_destroy (ChicleCoreGraphicsLoader *loader); gboolean chicle_coregraphics_loader_get_is_animation (ChicleCoreGraphicsLoader *loader); gconstpointer chicle_coregraphics_loader_get_frame_data (ChicleCoreGraphicsLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_coregraphics_loader_get_frame_delay (ChicleCoreGraphicsLoader *loader); void chicle_coregraphics_loader_goto_first_frame (ChicleCoreGraphicsLoader *loader); gboolean chicle_coregraphics_loader_goto_next_frame (ChicleCoreGraphicsLoader *loader); G_END_DECLS #endif /* __CHICLE_COREGRAPHICS_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-file-mapping.c000066400000000000000000000355401517447374300210360ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #ifdef G_OS_WIN32 # include # include #endif #ifdef HAVE_MMAP # include #endif #ifdef HAVE_GETRANDOM # include #endif #include #include "chicle-file-mapping.h" #ifdef HAVE_MMAP /* Workaround for non-Linux platforms */ # ifndef MAP_NORESERVE # define MAP_NORESERVE 0 # endif #endif #ifndef MAP_FAILED # define MAP_FAILED ((void *) -1) #endif /* MS Windows needs files to be explicitly opened as O_BINARY. However, this * flag is not always defined in our cross builds. */ #ifndef O_BINARY # ifdef _O_BINARY # define O_BINARY _O_BINARY # else # define O_BINARY 0 # endif #endif /* The absolute maximum size file we'll try to open */ #define FILE_SIZE_MAX ((gint64) 2 * 1024 * 1024 * 1024 - 2) /* Streams bigger than this must be cached in a file */ #define FILE_MEMORY_CACHE_MAX (4 * 1024 * 1024) /* Size of buffer used for copying stdin to file */ #define COPY_BUFFER_SIZE 8192 /* A contiguous magic string can't be longer than this */ #define MAGIC_LENGTH_MAX 1024 struct ChicleFileMapping { gchar *path; gpointer data; gsize length; gint fd; guint failed : 1; guint is_mmapped : 1; }; static gboolean file_is_stdin (ChicleFileMapping *file_mapping) { return file_mapping->path && file_mapping->path [0] == '-' && file_mapping->path [1] == '\0' ? TRUE : FALSE; } static gsize safe_read (gint fd, void *buf, gsize len) { gsize ntotal = 0; guint8 *buffer = buf; while (len > 0) { unsigned int nread; int iread; int saved_errno; /* Passing nread > INT_MAX to read is implementation defined in POSIX * 1003.1, therefore despite the unsigned argument portable code must * limit the value to INT_MAX! */ if (len > INT_MAX) nread = INT_MAX; else nread = (unsigned int)/*SAFE*/len; iread = read (fd, buffer, nread); saved_errno = errno; if (iread == -1) { /* This is the devil in the details, a read can terminate early with 0 * bytes read because of EINTR, yet it still returns -1 otherwise end * of file cannot be distinguished. */ if (saved_errno != EINTR) { /* I.e. a permanent failure */ return 0; } } else if (iread < 0) { /* Not a valid 'read' result: */ return 0; } else if (iread > 0) { /* Continue reading until a permanent failure, or EOF */ buffer += iread; len -= (unsigned int)/*SAFE*/iread; ntotal += (unsigned int)/*SAFE*/iread; } else { return ntotal; } } return ntotal; /* len == 0 */ } static gboolean safe_write (gint fd, gconstpointer buf, gsize len) { const guint8 *buffer = buf; gboolean success = FALSE; while (len > 0) { guint to_write; gint n_written; gint saved_errno; if (len > INT_MAX) to_write = INT_MAX; else to_write = (unsigned int) len; n_written = write (fd, buffer, to_write); saved_errno = errno; if (n_written == -1) { if (saved_errno != EINTR) goto out; } else if (n_written < 0) { /* Not a valid 'write' result */ goto out; } else if (n_written > 0) { /* Continue writing until permanent failure or entire buffer written */ buffer += n_written; len -= (unsigned int) n_written; } } success = TRUE; out: return success; } static gboolean safe_copy (gint src_fd, gint dest_fd) { guint8 buf [COPY_BUFFER_SIZE]; gsize n_read; while ((n_read = safe_read (src_fd, buf, COPY_BUFFER_SIZE)) > 0) { if (!safe_write (dest_fd, buf, n_read)) return FALSE; } return TRUE; } static void free_file_data (ChicleFileMapping *file_mapping) { if (file_mapping->data) { #ifdef HAVE_MMAP if (file_mapping->is_mmapped) munmap (file_mapping->data, file_mapping->length); else #endif g_free (file_mapping->data); } if (file_mapping->fd >= 0) g_close (file_mapping->fd, NULL); file_mapping->fd = -1; file_mapping->data = NULL; file_mapping->is_mmapped = FALSE; } static guint64 get_random_u64 (void) { guint64 u64 = 0; gint len = 0; GTimeVal tv; #ifdef HAVE_GETRANDOM len = getrandom ((void *) &u64, sizeof (guint64), GRND_NONBLOCK); #endif if (!u64 || len < (gint) sizeof (guint64)) { gpointer p; /* FIXME: Not paranoid enough */ /* FIXME: g_get_current_time() was deprecated in GLib 2.62. Switch to * g_get_real_time () sometime, and require GLib >= 2.28. */ g_get_current_time (&tv); g_random_set_seed (tv.tv_sec ^ tv.tv_usec); u64 ^= (guint64) g_random_int (); g_get_current_time (&tv); g_random_set_seed (tv.tv_sec ^ tv.tv_usec); u64 ^= ((guint64) g_random_int ()) << 32; p = g_thread_self (); u64 ^= (guint64) p; } return u64; } static gint open_temp_file_in_path (const gchar *base_path) { gchar *cache_path; gint fd; if (!base_path) return -1; cache_path = g_strdup_printf ("%s%schafa-%016" G_GINT64_MODIFIER "x", base_path, G_DIR_SEPARATOR_S, get_random_u64 ()); /* Create the file and unlink it, so it goes away when we exit */ fd = g_open (cache_path, O_CREAT | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR); if (fd >= 0) { /* You can't unlink an open file on MS Windows, so this will fail there */ g_unlink (cache_path); } g_free (cache_path); return fd; } static gint open_temp_file (void) { gint fd; fd = open_temp_file_in_path (g_get_user_cache_dir ()); if (fd < 0) fd = open_temp_file_in_path (g_get_tmp_dir ()); return fd; } static gint cache_stdin (ChicleFileMapping *file_mapping, GError **error) { gpointer buf = NULL; gint stdin_fd = fileno (stdin); /* Can't use STDIN_FILENO on Windows */ size_t n_read; gint cache_fd = -1; gint success = FALSE; if (stdin_fd < 0) goto out; #ifdef G_OS_WIN32 setmode (stdin_fd, O_BINARY); #endif /* Read from stdin */ buf = g_malloc (FILE_MEMORY_CACHE_MAX); n_read = safe_read (stdin_fd, buf, FILE_MEMORY_CACHE_MAX); if (n_read < 1) goto out; /* If the stream didn't fit in memory, save it all to a file instead. * We can mmap it later. Or read it back in, ha ha. */ if (n_read == FILE_MEMORY_CACHE_MAX) { cache_fd = open_temp_file (); if (cache_fd >= 0) { if (!safe_write (cache_fd, buf, n_read)) goto out; g_free (buf); buf = NULL; if (!safe_copy (stdin_fd, cache_fd)) goto out; } } else { file_mapping->data = g_realloc (buf, n_read); file_mapping->length = n_read; buf = NULL; } success = TRUE; out: if (!success) { if (cache_fd >= 0) g_close (cache_fd, NULL); cache_fd = -1; g_free (buf); if (error && !*error) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Could not cache input stream"); } } return cache_fd; } static gint open_file (ChicleFileMapping *file_mapping, GError **error) { gint fd; if (file_is_stdin (file_mapping)) { fd = cache_stdin (file_mapping, error); } else { fd = g_open (file_mapping->path, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR); if (fd < 0) { g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno), "%s", strerror (errno)); } } return fd; } static gboolean ensure_open_file (ChicleFileMapping *file_mapping) { if (file_mapping->data || file_mapping->fd >= 0) return TRUE; file_mapping->fd = open_file (file_mapping, NULL); if (file_mapping->data || file_mapping->fd >= 0) return TRUE; return FALSE; } static guint8 * read_file (gint fd, size_t *data_size) { struct stat sb; guint8 *buffer; size_t size; size_t n; if (fstat (fd, &sb)) { return NULL; } size = sb.st_size; buffer = g_try_malloc (size); if (!buffer) { g_printerr ("Unable to allocate %lld bytes\n", (long long) size); return NULL; } if (lseek (fd, 0, SEEK_SET) != 0) { g_free (buffer); return NULL; } n = safe_read (fd, buffer, size); if (n != size) { g_free (buffer); return NULL; } *data_size = size; return buffer; } static gboolean map_or_read_file (ChicleFileMapping *file_mapping) { gboolean result = FALSE; struct stat sbuf; gint t; if (file_mapping->failed) return FALSE; if (file_mapping->data) return TRUE; if (file_mapping->fd < 0) file_mapping->fd = open_file (file_mapping, NULL); /* If the data arrived over a pipe and was reasonably small, open_file () will * populate the data fields instead of the fd. */ if (!file_mapping->data) { if (file_mapping->fd < 0) goto out; t = fstat (file_mapping->fd, &sbuf); if (sbuf.st_size > FILE_SIZE_MAX) goto out; if (!t) { file_mapping->length = sbuf.st_size; #ifdef HAVE_MMAP /* Try memory mapping first */ file_mapping->data = mmap (NULL, file_mapping->length, PROT_READ, MAP_SHARED | MAP_NORESERVE, file_mapping->fd, 0); #endif } if (file_mapping->data != NULL && file_mapping->data != MAP_FAILED) { file_mapping->is_mmapped = TRUE; } else { file_mapping->data = read_file (file_mapping->fd, &file_mapping->length); file_mapping->is_mmapped = FALSE; } } if (!file_mapping->data) goto out; result = TRUE; out: if (!result) { file_mapping->failed = TRUE; } return result; } ChicleFileMapping * chicle_file_mapping_new (const gchar *path) { ChicleFileMapping *file_mapping; file_mapping = g_new0 (ChicleFileMapping, 1); file_mapping->path = g_strdup (path); file_mapping->fd = -1; return file_mapping; } void chicle_file_mapping_destroy (ChicleFileMapping *file_mapping) { free_file_data (file_mapping); g_free (file_mapping->path); g_free (file_mapping); } gboolean chicle_file_mapping_open_now (ChicleFileMapping *file_mapping, GError **error) { if (file_mapping->data || file_mapping->fd >= 0) return TRUE; file_mapping->fd = open_file (file_mapping, error); if (file_mapping->data || file_mapping->fd >= 0) return TRUE; if (error && !*error) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Open/map failed"); } return FALSE; } const gchar * chicle_file_mapping_get_path (ChicleFileMapping *file_mapping) { return file_mapping->path; } gconstpointer chicle_file_mapping_get_data (ChicleFileMapping *file_mapping, gsize *length_out) { if (!file_mapping->data) map_or_read_file (file_mapping); if (length_out) *length_out = file_mapping->length; return file_mapping->data; } gboolean chicle_file_mapping_taste (ChicleFileMapping *file_mapping, gpointer out, goffset ofs, gsize length) { if (!ensure_open_file (file_mapping)) return FALSE; if (file_mapping->data) { if (ofs + length <= file_mapping->length) { memcpy (out, ((const gchar *) file_mapping->data) + ofs, length); return TRUE; } return FALSE; } if (file_mapping->fd < 0) return FALSE; if (lseek (file_mapping->fd, ofs, SEEK_SET) != ofs) return FALSE; if (safe_read (file_mapping->fd, out, length) != length) return FALSE; return TRUE; } gssize chicle_file_mapping_read (ChicleFileMapping *file_mapping, gpointer out, goffset ofs, gsize length) { if (!ensure_open_file (file_mapping)) return FALSE; if (file_mapping->data) { if (ofs <= (gssize) file_mapping->length) { gssize seg_len = MIN (length, file_mapping->length - ofs); memcpy (out, ((const gchar *) file_mapping->data) + ofs, seg_len); return seg_len; } return -1; } /* FIXME: Shouldn't happen */ if (file_mapping->fd < 0) return -1; if (lseek (file_mapping->fd, ofs, SEEK_SET) != ofs) return -1; return safe_read (file_mapping->fd, out, length); } gboolean chicle_file_mapping_has_magic (ChicleFileMapping *file_mapping, goffset ofs, gconstpointer data, gsize length) { gchar buf [MAGIC_LENGTH_MAX]; g_assert (length <= MAGIC_LENGTH_MAX); if (!ensure_open_file (file_mapping)) return FALSE; if (file_mapping->data) { if (ofs + length <= file_mapping->length && !memcmp ((const guint8 *) file_mapping->data + ofs, data, length)) return TRUE; return FALSE; } /* FIXME: Shouldn't happen */ if (file_mapping->fd < 0) return FALSE; if (lseek (file_mapping->fd, ofs, SEEK_SET) != ofs) return FALSE; if (safe_read (file_mapping->fd, buf, length) != length) return FALSE; if (memcmp (buf, data, length)) return FALSE; return TRUE; } chafa-1.18.2/tools/chafa/chicle-file-mapping.h000066400000000000000000000034631517447374300210420ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_FILE_MAPPING_H__ #define __CHICLE_FILE_MAPPING_H__ #include G_BEGIN_DECLS typedef struct ChicleFileMapping ChicleFileMapping; ChicleFileMapping *chicle_file_mapping_new (const gchar *path); void chicle_file_mapping_destroy (ChicleFileMapping *file_mapping); gboolean chicle_file_mapping_open_now (ChicleFileMapping *file_mapping, GError **error); const gchar *chicle_file_mapping_get_path (ChicleFileMapping *file_mapping); gboolean chicle_file_mapping_taste (ChicleFileMapping *file_mapping, gpointer out, goffset ofs, gsize length); gssize chicle_file_mapping_read (ChicleFileMapping *file_mapping, gpointer out, goffset ofs, gsize length); gconstpointer chicle_file_mapping_get_data (ChicleFileMapping *file_mapping, gsize *length_out); gboolean chicle_file_mapping_has_magic (ChicleFileMapping *file_mapping, goffset ofs, gconstpointer data, gsize length); G_END_DECLS #endif /* __CHICLE_FILE_MAPPING_H__ */ chafa-1.18.2/tools/chafa/chicle-font-loader.c000066400000000000000000000364541517447374300207050ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include FT_FREETYPE_H #include #include "chicle-font-loader.h" #define DEBUG(x) #define REQ_WIDTH_DEFAULT 15 #define REQ_HEIGHT_DEFAULT 8 /* The font is read in two passes; once for narrow (single-cell) symbols, * and once for wide (double-cell) ones. This allows us to use a different * resolution for each -- 8x8 vs 16x8. */ typedef enum { FONT_PASS_NARROW, FONT_PASS_WIDE } FontPass; struct ChicleFontLoader { /* General / I/O */ ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; FT_Library ft_lib; FT_Face ft_face; /* Cell size that provides a good fit for font, pre-scaled */ gint font_width; gint font_height; /* Baseline offset, vertical from top */ gint baseline_ofs; /* Iterator */ FontPass pass; FT_ULong glyph_charcode; gint n_glyphs_read; }; /* With 256 bins we get a histogram for integer values [-128 .. 127]. This * is more than enough for the sizes we'll be getting, which should be in the * 0..16 range, give or take a little. Values outside the histogram's range * will be silently discarded. */ #define SMALL_HISTOGRAM_N_BINS 256 typedef struct { gint count [SMALL_HISTOGRAM_N_BINS]; gint first_bin; gint n_values; } SmallHistogram; static void small_histogram_init (SmallHistogram *hist) { memset (hist, 0, sizeof (*hist)); hist->first_bin = - (SMALL_HISTOGRAM_N_BINS / 2); } static void small_histogram_add (SmallHistogram *hist, gint value) { gint bin_index; bin_index = value - hist->first_bin; if (bin_index < 0 || bin_index >= SMALL_HISTOGRAM_N_BINS) return; hist->count [bin_index]++; hist->n_values++; } static gint small_histogram_get_quantile (SmallHistogram *hist, gint dividend, gint divisor) { gint i; gint n = 0; g_return_val_if_fail (dividend <= divisor, 0); for (i = 0; i < SMALL_HISTOGRAM_N_BINS; i++) { n += hist->count [i]; if (n >= (hist->n_values * dividend) / divisor) break; } return hist->first_bin + i; } static void small_histogram_get_range (SmallHistogram *hist, gint *min_out, gint *max_out) { gint min, max; min = small_histogram_get_quantile (hist, 1, 8); max = small_histogram_get_quantile (hist, 7, 8); if (min_out) *min_out = min; if (max_out) *max_out = max; } static ChicleFontLoader * chicle_font_loader_new (void) { return g_new0 (ChicleFontLoader, 1); } /* Get a bit from a rendered FreeType glyph bitmap. Going out of bounds is allowed * and will return zero. * * Returns: 1 for inked bits or 0 for uninked. */ static guint get_bitmap_bit (const ChicleFontLoader *loader, const FT_GlyphSlot slot, gint i, gint j) { const FT_Bitmap *bm; gint x, y; bm = &slot->bitmap; x = i - (gint) slot->bitmap_left - (loader->font_width - (slot->advance.x >> 6)) / 2; y = j - (loader->font_height - (gint) slot->bitmap_top) + (loader->font_height - loader->baseline_ofs); if (x < 0 || x >= (gint) bm->width || y < 0 || y >= (gint) bm->rows) return 0; /* MSB first */ return (bm->buffer [y * bm->pitch + (x / 8)] >> (7 - (x % 8))) & 1; } /* Get the 7th octile values for glyph width, height and baseline. This means 87.5% of * the glyphs will have values equal to or lower than the returned value. Discarding * the upper 12.5% prevents outliers from affecting the result. */ static gboolean measure_glyphs (ChicleFontLoader *loader, gint *width_out, gint *height_out, gint *baseline_out) { FT_ULong glyph_charcode; FT_UInt glyph_index; FT_GlyphSlot slot; SmallHistogram x_adv_hist; SmallHistogram asc_hist; SmallHistogram desc_hist; gint asc_max, desc_max; gboolean success = FALSE; small_histogram_init (&x_adv_hist); small_histogram_init (&asc_hist); small_histogram_init (&desc_hist); for (glyph_charcode = FT_Get_First_Char (loader->ft_face, &glyph_index); glyph_index != 0; glyph_charcode = FT_Get_Next_Char (loader->ft_face, glyph_charcode, &glyph_index)) { if (!g_unichar_isprint (glyph_charcode) || g_unichar_ismark (glyph_charcode)) continue; /* Skip glyphs that are not relevant to this pass */ if ((loader->pass == FONT_PASS_NARROW && g_unichar_iswide (glyph_charcode)) || (loader->pass == FONT_PASS_WIDE && !g_unichar_iswide (glyph_charcode))) continue; /* FIXME: No need to render? */ if (FT_Load_Glyph (loader->ft_face, glyph_index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO)) continue; slot = loader->ft_face->glyph; small_histogram_add (&x_adv_hist, slot->advance.x / 64 > 0 ? slot->advance.x / 64 : slot->bitmap_left + (gint) slot->bitmap.width); small_histogram_add (&asc_hist, slot->bitmap_top); small_histogram_add (&desc_hist, (gint) slot->bitmap.rows - (gint) slot->bitmap_top); } if (x_adv_hist.n_values == 0) goto out; small_histogram_get_range (&x_adv_hist, NULL, width_out); small_histogram_get_range (&asc_hist, NULL, &asc_max); small_histogram_get_range (&desc_hist, NULL, &desc_max); if (height_out) *height_out = asc_max + desc_max; if (baseline_out) *baseline_out = asc_max; success = TRUE; out: return success; } /* Find a pixel size that produces rendered symbols matching our ideal * size as closely as possible. Due to variable-width fonts, precise * font sizes being unavailable, etc. we do this by probing and * simple statistical analysis. * * We start with an initial guess and change our request in increments * until we either hit our desired size or exceed it. Then we back off * once. This is done in both dimensions simultaneously. */ static gboolean find_best_pixel_size_scalable (ChicleFontLoader *loader, gint target_width) { gboolean success = FALSE; gint req_width = REQ_WIDTH_DEFAULT; gint req_height = REQ_HEIGHT_DEFAULT; gint width = 0, height = 0, baseline; gint width_chg = 0, height_chg = 0; while ((width != target_width && width_chg != 3) || (height != CHAFA_SYMBOL_HEIGHT_PIXELS && height_chg != 3)) { if (FT_Set_Pixel_Sizes (loader->ft_face, req_width, req_height)) goto out; if (!measure_glyphs (loader, &width, &height, &baseline)) goto out; if (width < target_width) { req_width++; width_chg |= 1; } if (width > target_width) { req_width--; width_chg |= 2; } if (height < CHAFA_SYMBOL_HEIGHT_PIXELS) { req_height++; height_chg |= 1; } if (height > CHAFA_SYMBOL_HEIGHT_PIXELS) { req_height--; height_chg |= 2; } } /* If we can't get the exact size we want, make sure we get something * slightly bigger instead of slightly smaller. */ while (height < CHAFA_SYMBOL_HEIGHT_PIXELS) { req_height++; if (FT_Set_Pixel_Sizes (loader->ft_face, req_width, req_height)) goto out; if (!measure_glyphs (loader, &width, &height, &baseline)) goto out; } loader->font_width = width; loader->font_height = height; loader->baseline_ofs = baseline; success = TRUE; out: return success; } /* See the description of find_best_pixel_size_scalable() for the overall * strategy used here. */ static gboolean find_best_pixel_size_fixed (ChicleFontLoader *loader, gint target_width) { gboolean success = FALSE; const FT_Bitmap_Size *avsz = loader->ft_face->available_sizes; gint best_width = 0, best_height = 0, best_baseline = 0; gint i; if (!loader->ft_face->available_sizes) goto out; for (i = 0; i < loader->ft_face->num_fixed_sizes; i++) { gint width, height, baseline; if (FT_Set_Pixel_Sizes (loader->ft_face, avsz [i].width, avsz [i].height)) continue; if (!measure_glyphs (loader, &width, &height, &baseline)) goto out; /* Prefer strikes bigger than and as close as possible to actual target size */ if (((best_width < target_width || best_height < CHAFA_SYMBOL_HEIGHT_PIXELS) && (width >= best_width && height >= best_height)) || ((best_width > target_width || best_height > CHAFA_SYMBOL_HEIGHT_PIXELS) && (width >= target_width && height >= CHAFA_SYMBOL_HEIGHT_PIXELS) && (width < best_width || height < best_height))) { best_width = width; best_height = height; best_baseline = baseline; } } if (best_width == 0 || best_height == 0) goto out; if (FT_Set_Pixel_Sizes (loader->ft_face, best_width, best_height)) goto out; loader->font_width = best_width; loader->font_height = best_height; loader->baseline_ofs = best_baseline; success = TRUE; out: return success; } static gboolean begin_pass (ChicleFontLoader *loader, FontPass pass) { loader->pass = pass; if (pass == FONT_PASS_NARROW) { if (!find_best_pixel_size_scalable (loader, CHAFA_SYMBOL_WIDTH_PIXELS) && !find_best_pixel_size_fixed (loader, CHAFA_SYMBOL_WIDTH_PIXELS)) return FALSE; } else if (pass == FONT_PASS_WIDE) { if (!find_best_pixel_size_scalable (loader, CHAFA_SYMBOL_WIDTH_PIXELS * 2) && !find_best_pixel_size_fixed (loader, CHAFA_SYMBOL_WIDTH_PIXELS * 2)) return FALSE; } else { g_assert_not_reached (); } return TRUE; } static gboolean next_pass (ChicleFontLoader *loader) { loader->n_glyphs_read = 0; if (loader->pass == FONT_PASS_NARROW) return begin_pass (loader, FONT_PASS_WIDE); return FALSE; } ChicleFontLoader * chicle_font_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleFontLoader *loader = NULL; gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); loader = chicle_font_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; if (FT_Init_FreeType (&loader->ft_lib) != 0) goto out; if (FT_New_Memory_Face (loader->ft_lib, loader->file_data, loader->file_data_len, 0, /* face index */ &loader->ft_face)) goto out; if (!begin_pass (loader, FONT_PASS_NARROW) && !begin_pass (loader, FONT_PASS_WIDE)) goto out; success = TRUE; out: if (!success) { if (loader) { chicle_font_loader_destroy (loader); loader = NULL; } } return loader; } void chicle_font_loader_destroy (ChicleFontLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->ft_face) FT_Done_Face (loader->ft_face); if (loader->ft_lib) FT_Done_FreeType (loader->ft_lib); g_free (loader); } static void generate_glyph (const ChicleFontLoader *loader, const FT_GlyphSlot slot, gpointer *glyph_out, gint *width_out, gint *height_out) { guint8 *glyph_data; gint i, j; const guint8 val [2] = { 0x00, 0xff }; glyph_data = g_malloc (loader->font_width * loader->font_height * 4); for (j = 0; j < loader->font_height; j++) { for (i = 0; i < loader->font_width; i++) { guint b = get_bitmap_bit (loader, slot, i, j); if (b) { DEBUG (g_printerr ("XX")); } else { DEBUG (g_printerr ("..")); } glyph_data [(j * loader->font_width + i) * 4] = val [b]; glyph_data [(j * loader->font_width + i) * 4 + 1] = val [b]; glyph_data [(j * loader->font_width + i) * 4 + 2] = val [b]; glyph_data [(j * loader->font_width + i) * 4 + 3] = val [b]; } DEBUG (g_printerr ("\n")); } DEBUG (g_printerr ("\n")); *glyph_out = glyph_data; *width_out = loader->font_width; *height_out = loader->font_height; } /* Load a glyph to an RGBA8 output buffer of fixed size CHAFA_SYMBOL_WIDTH_PIXELS * * CHAFA_SYMBOL_HEIGHT_PIXELS. Each pixel will be set to either 0xffffffff (inked) * or 0x00000000 (uninked). */ gboolean chicle_font_loader_get_next_glyph (ChicleFontLoader *loader, gunichar *char_out, gpointer *glyph_out, gint *width_out, gint *height_out) { FT_GlyphSlot slot; gboolean success = FALSE; FT_UInt glyph_index = 0; slot = loader->ft_face->glyph; while (!glyph_index) { if (loader->n_glyphs_read == 0) { loader->glyph_charcode = FT_Get_First_Char (loader->ft_face, &glyph_index); } else { loader->glyph_charcode = FT_Get_Next_Char (loader->ft_face, loader->glyph_charcode, &glyph_index); } if (!glyph_index) { if (next_pass (loader)) continue; break; } loader->n_glyphs_read++; /* Skip glyphs that are not relevant to this pass */ if (!g_unichar_isprint (loader->glyph_charcode) || g_unichar_ismark (loader->glyph_charcode) || (loader->pass == FONT_PASS_NARROW && g_unichar_iswide (loader->glyph_charcode)) || (loader->pass == FONT_PASS_WIDE && !g_unichar_iswide (loader->glyph_charcode))) glyph_index = 0; } if (!glyph_index) goto out; if (FT_Load_Glyph (loader->ft_face, glyph_index, FT_LOAD_RENDER | FT_LOAD_MONOCHROME | FT_LOAD_TARGET_MONO)) goto out; generate_glyph (loader, slot, glyph_out, width_out, height_out); *char_out = loader->glyph_charcode; DEBUG (g_printerr ("Loaded symbol %04x: %dx%d -> %dx%d (ofs %d,%d bmsize %dx%d xadv %d/64=%d)\n", *char_out, loader->font_width, loader->font_height, *width_out, *height_out, slot->bitmap_left, slot->bitmap_top, slot->bitmap.width, slot->bitmap.rows, (gint) slot->advance.x, (gint) slot->advance.x >> 6)); success = TRUE; out: return success; } chafa-1.18.2/tools/chafa/chicle-font-loader.h000066400000000000000000000030301517447374300206720ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2019-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_FONT_LOADER_H__ #define __CHICLE_FONT_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleFontLoader ChicleFontLoader; ChicleFontLoader *chicle_font_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_font_loader_destroy (ChicleFontLoader *loader); gboolean chicle_font_loader_get_next_glyph (ChicleFontLoader *loader, gunichar *char_out, gpointer *glyph_out, gint *width_out, gint *height_out); G_END_DECLS #endif /* __CHICLE_FONT_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-gif-loader.c000066400000000000000000000153671517447374300205040ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "chicle-gif-loader.h" #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) struct ChicleGifLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gif_animation gif; gif_result code; gint current_frame_index; guint gif_is_initialized : 1; guint frame_is_decoded : 1; guint frame_is_success : 1; }; static void * bitmap_create (int width, int height) { if ((width * (gint64) height * BYTES_PER_PIXEL) > IMAGE_BUFFER_SIZE_MAX) return NULL; return g_malloc0 (width * height * BYTES_PER_PIXEL); } static gboolean maybe_decode_frame (ChicleGifLoader *loader) { gif_result code; if (loader->frame_is_decoded) return loader->frame_is_success; code = gif_decode_frame (&loader->gif, loader->current_frame_index); loader->frame_is_decoded = TRUE; loader->frame_is_success = (code == GIF_OK ? TRUE : FALSE); return loader->frame_is_success; } static void bitmap_set_opaque (void *bitmap, bool opaque) { (void) opaque; /* unused */ (void) bitmap; /* unused */ g_assert (bitmap); } static bool bitmap_test_opaque (void *bitmap) { (void) bitmap; /* unused */ g_assert (bitmap != NULL); return false; } static unsigned char * bitmap_get_buffer (void *bitmap) { g_assert (bitmap != NULL); return bitmap; } static void bitmap_destroy (void *bitmap) { g_assert (bitmap != NULL); g_free (bitmap); } static void bitmap_modified (void *bitmap) { (void) bitmap; /* unused */ g_assert (bitmap != NULL); } static ChicleGifLoader * chicle_gif_loader_new (void) { return g_new0 (ChicleGifLoader, 1); } ChicleGifLoader * chicle_gif_loader_new_from_mapping (ChicleFileMapping *mapping) { gif_bitmap_callback_vt bitmap_callbacks = { bitmap_create, bitmap_destroy, bitmap_get_buffer, bitmap_set_opaque, bitmap_test_opaque, bitmap_modified }; gif_result code; ChicleGifLoader *loader = NULL; gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); if (!chicle_file_mapping_has_magic (mapping, 0, "GIF89a", 6) && !chicle_file_mapping_has_magic (mapping, 0, "GIF87a", 6)) goto out; loader = chicle_gif_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; gif_create (&loader->gif, &bitmap_callbacks); loader->gif_is_initialized = TRUE; do { code = gif_initialise (&loader->gif, loader->file_data_len, loader->file_data); if (code != GIF_OK && code != GIF_WORKING) goto out; } while (code != GIF_OK); /* Ensure we can decode a frame. If not, we can try other loaders */ if (!maybe_decode_frame (loader)) goto out; success = TRUE; out: if (!success) { if (loader) { if (loader->gif_is_initialized) gif_finalise (&loader->gif); g_free (loader); loader = NULL; } } return loader; } void chicle_gif_loader_destroy (ChicleGifLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->gif_is_initialized) gif_finalise (&loader->gif); g_free (loader); } gboolean chicle_gif_loader_get_is_animation (ChicleGifLoader *loader) { g_return_val_if_fail (loader != NULL, 0); g_return_val_if_fail (loader->gif_is_initialized, 0); return loader->gif.frame_count > 1 ? TRUE : FALSE; } gconstpointer chicle_gif_loader_get_frame_data (ChicleGifLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); g_return_val_if_fail (loader->gif_is_initialized, NULL); if (!maybe_decode_frame (loader)) return NULL; if (width_out) *width_out = loader->gif.width; if (height_out) *height_out = loader->gif.height; if (pixel_type_out) *pixel_type_out = CHAFA_PIXEL_RGBA8_UNASSOCIATED; if (rowstride_out) *rowstride_out = loader->gif.width * 4; return loader->gif.frame_image; } gint chicle_gif_loader_get_frame_delay (ChicleGifLoader *loader) { gint frame_delay_ms; g_return_val_if_fail (loader != NULL, 0); g_return_val_if_fail (loader->gif_is_initialized, 0); if (!maybe_decode_frame (loader)) return 0; frame_delay_ms = loader->gif.frames [loader->current_frame_index].frame_delay; /* Convert from centiseconds to milliseconds */ frame_delay_ms *= 10; /* It's common for GIF animations to omit the frame delays. If it looks like that's * what's happening, go with a 20fps default. */ if (frame_delay_ms == 0) frame_delay_ms = 50; return frame_delay_ms; } void chicle_gif_loader_goto_first_frame (ChicleGifLoader *loader) { g_return_if_fail (loader != NULL); g_return_if_fail (loader->gif_is_initialized); if (loader->current_frame_index == 0) return; loader->current_frame_index = 0; loader->frame_is_decoded = FALSE; loader->frame_is_success = FALSE; } gboolean chicle_gif_loader_goto_next_frame (ChicleGifLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); g_return_val_if_fail (loader->gif_is_initialized, FALSE); if (loader->current_frame_index + 1 >= (gint) loader->gif.frame_count) return FALSE; loader->current_frame_index++; loader->frame_is_decoded = FALSE; return TRUE; } chafa-1.18.2/tools/chafa/chicle-gif-loader.h000066400000000000000000000035021517447374300204750ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_GIF_LOADER_H__ #define __CHICLE_GIF_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleGifLoader ChicleGifLoader; ChicleGifLoader *chicle_gif_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_gif_loader_destroy (ChicleGifLoader *loader); gboolean chicle_gif_loader_get_is_animation (ChicleGifLoader *loader); gconstpointer chicle_gif_loader_get_frame_data (ChicleGifLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_gif_loader_get_frame_delay (ChicleGifLoader *loader); void chicle_gif_loader_goto_first_frame (ChicleGifLoader *loader); gboolean chicle_gif_loader_goto_next_frame (ChicleGifLoader *loader); G_END_DECLS #endif /* __CHICLE_GIF_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-grid-layout.c000066400000000000000000000325051517447374300207240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chicle-grid-layout.h" #include "chicle-media-pipeline.h" #include "chicle-util.h" #define MAX_COLS 1024 struct ChicleGridLayout { gint view_width, view_height; gint n_cols, n_rows; ChafaCanvasConfig *canvas_config; ChafaTermInfo *term_info; ChafaAlign halign; ChafaAlign valign; ChafaTuck tuck; ChiclePathQueue *path_queue; ChicleMediaPipeline *media_pipeline; gint n_items, next_item; guint finished_chunks : 1; guint print_labels : 1; guint link_labels : 1; guint use_unicode : 1; guint is_printing : 1; }; static void update_geometry (ChicleGridLayout *grid) { gint view_width, view_height; gint n_cols, n_rows; gint item_width, item_height; gint cell_width_px, cell_height_px; /* FIXME: May want to honor font_ratio */ if (!grid->canvas_config) return; chafa_canvas_config_get_cell_geometry (grid->canvas_config, &cell_width_px, &cell_height_px); if (cell_width_px < 1 || cell_height_px < 1) { cell_width_px = 10; cell_height_px = 20; } view_width = MAX (grid->view_width, 1); view_height = MAX (grid->view_height, 1); n_cols = grid->n_cols; n_rows = grid->n_rows; if (n_cols < 1 && n_rows < 1) n_cols = n_rows = 1; /* If one dimension is not provided, make square tiles */ if (n_cols < 1) { item_height = view_height / n_rows - 1; item_width = (item_height * cell_height_px) / cell_width_px; } else if (n_rows < 1) { item_width = view_width / n_cols - 1; item_height = (item_width * cell_width_px) / cell_height_px; } else { item_width = view_width / n_cols - 1; item_height = view_height / n_rows - 1; } item_width = MAX (item_width, 1); item_height = MAX (item_height, 1); if (grid->n_cols < 1) { grid->n_cols = MIN (view_width / (item_width + 1), MAX_COLS); grid->n_cols = MAX (grid->n_cols, 1); } chafa_canvas_config_set_geometry (grid->canvas_config, item_width, item_height); } static void get_approx_canvas_size_px (ChafaCanvasConfig *config, gint *target_width_out, gint *target_height_out) { gint cell_width_px, cell_height_px; chafa_canvas_config_get_cell_geometry (config, &cell_width_px, &cell_height_px); if (cell_width_px < 1 || cell_height_px < 1) { cell_width_px = 10; cell_height_px = 20; } chafa_canvas_config_get_geometry (config, target_width_out, target_height_out); *target_width_out *= cell_width_px; *target_height_out *= cell_height_px; } static gboolean print_grid_row_symbols (ChicleGridLayout *grid, ChafaTerm *term) { GString **item_gsa [MAX_COLS]; GList *paths = NULL; gint item_height [MAX_COLS]; gint col_width, row_height; gint n_cols_produced; gint i, j; if (grid->finished_chunks) return FALSE; chafa_canvas_config_get_geometry (grid->canvas_config, &col_width, &row_height); for (i = 0; i < MAX_COLS; i++) item_height [i] = G_MAXINT; for (n_cols_produced = 0; n_cols_produced < grid->n_cols; ) { gchar *path; item_gsa [n_cols_produced] = NULL; if (!chicle_media_pipeline_pop (grid->media_pipeline, &path, NULL, &item_gsa [n_cols_produced], NULL /* FIXME */)) break; if (item_gsa [n_cols_produced]) { paths = g_list_prepend (paths, path); n_cols_produced++; } else { /* FIXME: Use a placeholder image */ g_free (path); } grid->next_item++; } if (n_cols_produced < 1) { grid->finished_chunks = TRUE; return FALSE; } paths = g_list_reverse (paths); for (i = 0; i < row_height; i++) { for (j = 0; j < n_cols_produced; j++) { if (i < item_height [j] && !item_gsa [j] [i]) { /* Pad with spaces */ item_height [j] = i; } } } for (i = 0; i < row_height; i++) { for (j = 0; j < n_cols_produced; j++) { if (i >= item_height [j]) { /* Pad with spaces */ chicle_print_rep_char (term, ' ', col_width + 1); } else { gint col_row_data_len = item_gsa [j] [i]->len; if (j > 0) chafa_term_write (term, " ", 1); chafa_term_write (term, item_gsa [j] [i]->str, col_row_data_len); } } chafa_term_write (term, "\n", 1); } if (grid->print_labels) { GList *l = paths; for (j = 0; l && j < n_cols_produced; j++) { const gchar *path = l->data; chicle_path_print_label (term, path, grid->halign, col_width, grid->use_unicode, grid->link_labels); chafa_term_write (term, " ", 1); l = g_list_next (l); } chafa_term_write (term, "\n", 1); } chafa_term_write (term, "\n", 1); for (i = 0; i < n_cols_produced; i++) chafa_free_gstring_array (item_gsa [i]); g_list_free_full (paths, g_free); return TRUE; } static gboolean print_grid_image (ChicleGridLayout *grid, ChafaTerm *term) { GString **item_gsa [1] = { NULL }; gchar *path = NULL; gint col_width, row_height; gint i, j; if (grid->finished_chunks) return FALSE; /* Setup */ chafa_canvas_config_get_geometry (grid->canvas_config, &col_width, &row_height); /* Format first available item */ while (!item_gsa [0]) { if (!chicle_media_pipeline_pop (grid->media_pipeline, &path, NULL, &item_gsa [0], NULL /* FIXME */)) break; if (!item_gsa [0]) { /* FIXME: Use a placeholder image */ g_free (path); path = NULL; } } if (!path) path = g_strdup ("?"); /* Optional: End previous row */ if (grid->next_item != 0 && (grid->next_item % grid->n_cols == 0 || !item_gsa [0])) { for (i = 0; i < row_height + (grid->print_labels ? 1 : 0) + 1; i++) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL, -1); } /* FIXME: Make relative */ chafa_term_write (term, "\r", 1); } if (!item_gsa [0]) { grid->finished_chunks = TRUE; g_free (path); return FALSE; } /* Optional: Begin row */ if (grid->next_item % grid->n_cols == 0) { /* Reserve space on terminal, scrolling if necessary */ for (i = 0; i < row_height + 1; i++) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_DOWN_SCROLL, -1); } chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_UP, row_height + 1, -1); } /* Format image */ chafa_term_print_seq (term, CHAFA_TERM_SEQ_SAVE_CURSOR_POS, -1); for (j = 0; item_gsa [0] [j]; j++) { gint col_row_data_len = item_gsa [0] [j]->len; chafa_term_write (term, item_gsa [0] [j]->str, col_row_data_len); } /* Print label */ if (grid->print_labels) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_RESTORE_CURSOR_POS, -1); chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_DOWN, row_height, -1); chicle_path_print_label (term, path, grid->halign, col_width, grid->use_unicode, grid->link_labels); } /* Prepare for next image */ chafa_term_print_seq (term, CHAFA_TERM_SEQ_RESTORE_CURSOR_POS, -1); chafa_term_print_seq (term, CHAFA_TERM_SEQ_CURSOR_RIGHT, col_width + 1, -1); grid->next_item++; chafa_free_gstring_array (item_gsa [0]); g_free (path); return TRUE; } static gboolean print_grid_chunk (ChicleGridLayout *grid, ChafaTerm *term) { ChafaPixelMode pixel_mode; pixel_mode = chafa_canvas_config_get_pixel_mode (grid->canvas_config); if (pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) return print_grid_row_symbols (grid, term); else return print_grid_image (grid, term); } ChicleGridLayout * chicle_grid_layout_new (void) { ChicleGridLayout *grid; grid = g_new0 (ChicleGridLayout, 1); grid->tuck = CHAFA_TUCK_FIT; return grid; } void chicle_grid_layout_destroy (ChicleGridLayout *grid) { if (grid->canvas_config) chafa_canvas_config_unref (grid->canvas_config); if (grid->term_info) chafa_term_info_unref (grid->term_info); if (grid->path_queue) chicle_path_queue_unref (grid->path_queue); if (grid->media_pipeline) chicle_media_pipeline_destroy (grid->media_pipeline); g_free (grid); } void chicle_grid_layout_set_path_queue (ChicleGridLayout *grid, ChiclePathQueue *path_queue) { if (path_queue) chicle_path_queue_ref (path_queue); if (grid->path_queue) chicle_path_queue_unref (grid->path_queue); grid->path_queue = path_queue; } void chicle_grid_layout_set_canvas_config (ChicleGridLayout *grid, ChafaCanvasConfig *canvas_config) { g_return_if_fail (grid != NULL); chafa_canvas_config_ref (canvas_config); if (grid->canvas_config) chafa_canvas_config_unref (grid->canvas_config); grid->canvas_config = canvas_config; update_geometry (grid); } void chicle_grid_layout_set_term_info (ChicleGridLayout *grid, ChafaTermInfo *term_info) { g_return_if_fail (grid != NULL); chafa_term_info_ref (term_info); if (grid->term_info) chafa_term_info_unref (grid->term_info); grid->term_info = term_info; update_geometry (grid); } void chicle_grid_layout_set_view_size (ChicleGridLayout *grid, gint width, gint height) { g_return_if_fail (grid != NULL); grid->view_width = width; grid->view_height = height; update_geometry (grid); } void chicle_grid_layout_set_grid_size (ChicleGridLayout *grid, gint n_cols, gint n_rows) { g_return_if_fail (grid != NULL); grid->n_cols = MIN (n_cols, MAX_COLS); grid->n_rows = n_rows; update_geometry (grid); } void chicle_grid_layout_set_align (ChicleGridLayout *grid, ChafaAlign halign, ChafaAlign valign) { g_return_if_fail (grid != NULL); grid->halign = halign; grid->valign = valign; } void chicle_grid_layout_set_tuck (ChicleGridLayout *grid, ChafaTuck tuck) { g_return_if_fail (grid != NULL); grid->tuck = tuck; } void chicle_grid_layout_set_print_labels (ChicleGridLayout *grid, gboolean print_labels) { g_return_if_fail (grid != NULL); grid->print_labels = print_labels; } void chicle_grid_layout_set_link_labels (ChicleGridLayout *grid, gboolean link_labels) { g_return_if_fail (grid != NULL); grid->link_labels = link_labels; } void chicle_grid_layout_set_use_unicode (ChicleGridLayout *grid, gboolean use_unicode) { g_return_if_fail (grid != NULL); grid->use_unicode = use_unicode; } gboolean chicle_grid_layout_print_chunk (ChicleGridLayout *grid, ChafaTerm *term) { g_return_val_if_fail (grid != NULL, FALSE); if (!grid->is_printing) { gint target_width, target_height; grid->is_printing = TRUE; if (!grid->path_queue) grid->path_queue = chicle_path_queue_new (); if (!grid->canvas_config) grid->canvas_config = chafa_canvas_config_new (); if (!grid->term_info) grid->term_info = chafa_term_db_get_fallback_info (chafa_term_db_get_default ()); get_approx_canvas_size_px (grid->canvas_config, &target_width, &target_height); grid->media_pipeline = chicle_media_pipeline_new (grid->path_queue, target_width, target_height); chicle_media_pipeline_set_want_loader (grid->media_pipeline, FALSE); chicle_media_pipeline_set_want_output (grid->media_pipeline, TRUE); chicle_media_pipeline_set_formatting (grid->media_pipeline, grid->canvas_config, grid->term_info, grid->halign, grid->valign, grid->tuck); update_geometry (grid); } return print_grid_chunk (grid, term); } chafa-1.18.2/tools/chafa/chicle-grid-layout.h000066400000000000000000000042421517447374300207260ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_GRID_LAYOUT_H__ #define __CHICLE_GRID_LAYOUT_H__ #include #include "chafa-term.h" #include "chicle-path-queue.h" G_BEGIN_DECLS typedef struct ChicleGridLayout ChicleGridLayout; ChicleGridLayout *chicle_grid_layout_new (void); void chicle_grid_layout_destroy (ChicleGridLayout *grid); void chicle_grid_layout_set_path_queue (ChicleGridLayout *grid, ChiclePathQueue *path_queue); void chicle_grid_layout_set_canvas_config (ChicleGridLayout *grid, ChafaCanvasConfig *canvas_config); void chicle_grid_layout_set_term_info (ChicleGridLayout *grid, ChafaTermInfo *term_info); void chicle_grid_layout_set_view_size (ChicleGridLayout *grid, gint width, gint height); void chicle_grid_layout_set_grid_size (ChicleGridLayout *grid, gint n_cols, gint n_rows); void chicle_grid_layout_set_align (ChicleGridLayout *grid, ChafaAlign halign, ChafaAlign valign); void chicle_grid_layout_set_tuck (ChicleGridLayout *grid, ChafaTuck tuck); void chicle_grid_layout_set_print_labels (ChicleGridLayout *grid, gboolean print_labels); void chicle_grid_layout_set_link_labels (ChicleGridLayout *grid, gboolean link_labels); void chicle_grid_layout_set_use_unicode (ChicleGridLayout *grid, gboolean use_unicode); gboolean chicle_grid_layout_print_chunk (ChicleGridLayout *grid, ChafaTerm *term); G_END_DECLS #endif /* __CHICLE_GRID_LAYOUT_H__ */ chafa-1.18.2/tools/chafa/chicle-heif-loader.c000066400000000000000000000131711517447374300206410ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "chicle-heif-loader.h" #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) struct ChicleHeifLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gint width, height; gint stride; struct heif_context *ctx; struct heif_image_handle *handle; struct heif_image *image; const uint8_t *frame_data; }; static void free_heif_handles (ChicleHeifLoader *loader) { if (loader->image) heif_image_release (loader->image); if (loader->handle) heif_image_handle_release (loader->handle); if (loader->ctx) heif_context_free (loader->ctx); loader->image = NULL; loader->handle = NULL; loader->ctx = NULL; } static ChicleHeifLoader * chicle_heif_loader_new (void) { return g_new0 (ChicleHeifLoader, 1); } ChicleHeifLoader * chicle_heif_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleHeifLoader *loader = NULL; gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); /* Quick check for the ISOBMFF ftyp box to filter out files that are * something else entirely */ if (!chicle_file_mapping_has_magic (mapping, 4, "ftyp", 4)) goto out; loader = chicle_heif_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; loader->ctx = heif_context_alloc (); if (!loader->ctx) goto out; if (heif_context_read_from_memory_without_copy (loader->ctx, loader->file_data, loader->file_data_len, NULL).code != heif_error_Ok) goto out; heif_context_get_primary_image_handle (loader->ctx, &loader->handle); if (!loader->handle) goto out; heif_decode_image (loader->handle, &loader->image, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, NULL); if (!loader->image) goto out; loader->width = heif_image_get_primary_width (loader->image); loader->height = heif_image_get_primary_height (loader->image); if (loader->width < 1 || loader->width >= (1 << 28) || loader->height < 1 || loader->height >= (1 << 28)) goto out; if ((unsigned int) loader->width * loader->height * BYTES_PER_PIXEL > IMAGE_BUFFER_SIZE_MAX) goto out; loader->frame_data = heif_image_get_plane_readonly (loader->image, heif_channel_interleaved, &loader->stride); if (!loader->frame_data || loader->stride < 1) goto out; success = TRUE; out: if (!success) { if (loader) { free_heif_handles (loader); g_free (loader); loader = NULL; } } return loader; } void chicle_heif_loader_destroy (ChicleHeifLoader *loader) { free_heif_handles (loader); if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); g_free (loader); } gboolean chicle_heif_loader_get_is_animation (ChicleHeifLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return FALSE; } gconstpointer chicle_heif_loader_get_frame_data (ChicleHeifLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) { *pixel_type_out = heif_image_is_premultiplied_alpha (loader->image) ? CHAFA_PIXEL_RGBA8_PREMULTIPLIED : CHAFA_PIXEL_RGBA8_UNASSOCIATED; } if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->stride; return loader->frame_data; } gint chicle_heif_loader_get_frame_delay (ChicleHeifLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return 0; } void chicle_heif_loader_goto_first_frame (ChicleHeifLoader *loader) { g_return_if_fail (loader != NULL); } gboolean chicle_heif_loader_goto_next_frame (ChicleHeifLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return FALSE; } chafa-1.18.2/tools/chafa/chicle-heif-loader.h000066400000000000000000000035241517447374300206470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_HEIF_LOADER_H__ #define __CHICLE_HEIF_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleHeifLoader ChicleHeifLoader; ChicleHeifLoader *chicle_heif_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_heif_loader_destroy (ChicleHeifLoader *loader); gboolean chicle_heif_loader_get_is_animation (ChicleHeifLoader *loader); gconstpointer chicle_heif_loader_get_frame_data (ChicleHeifLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_heif_loader_get_frame_delay (ChicleHeifLoader *loader); void chicle_heif_loader_goto_first_frame (ChicleHeifLoader *loader); gboolean chicle_heif_loader_goto_next_frame (ChicleHeifLoader *loader); G_END_DECLS #endif /* __CHICLE_HEIF_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-jpeg-loader.c000066400000000000000000000277141517447374300206630ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include "chicle-jpeg-loader.h" #include "chicle-util.h" /* ----------------------- * * Global macros and types * * ----------------------- */ #undef ENABLE_DEBUG #define BYTES_PER_PIXEL 3 #define ROWSTRIDE_ALIGN 16 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) #define PAD_TO_N(p, n) (((p) + ((n) - 1)) & ~((unsigned) (n) - 1)) #define ROWSTRIDE_PAD(rowstride) (PAD_TO_N ((rowstride), (ROWSTRIDE_ALIGN))) struct JpegLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gpointer frame_data; gint width, height, rowstride; }; /* ----------------------- * * Exif orientation reader * * ----------------------- */ static guint16 read_uint16 (const guchar *p, gboolean is_big_endian) { return is_big_endian ? ((p [0] << 8) | p [1]) : ((p [1] << 8) | p [0]); } static guint32 read_uint32 (const guchar *p, gboolean is_big_endian) { return is_big_endian ? ((p [0] << 24) | (p [1] << 16) | (p [2] << 8) | p [3]) : ((p [3] << 24) | (p [2] << 16) | (p [1] << 8) | p [0]); } static ChicleRotationType read_orientation (JpegLoader *loader) { const guchar *p0, *end; size_t len; ChicleRotationType rot = CHICLE_ROTATION_NONE; gboolean is_big_endian; guint n, m, o; p0 = loader->file_data; len = loader->file_data_len; end = p0 + len; /* Assume we already checked the JPEG header. Now find the Exif header. */ p0 += 2; for (;;) { if (p0 + 20 > end) goto out; /* Get app type */ if (read_uint16 (p0, TRUE) < 0xffdb) goto out; p0 += 2; /* Get marker length; note length field includes itself */ n = read_uint16 (p0, TRUE); if (n < 2 || p0 + n > end) goto out; if (!memcmp (p0 + 2, "Exif\0\0", 6)) { p0 += 8; break; } /* Not an Exif marker; skip it */ p0 += n; } /* Get byte order */ m = read_uint16 (p0, TRUE); if (m == 0x4949) is_big_endian = FALSE; else if (m == 0x4d4d) is_big_endian = TRUE; else goto out; /* Tag mark */ if (read_uint16 (p0 + 2, is_big_endian) != 0x002a) goto out; /* First IFD offset */ m = read_uint32 (p0 + 4, is_big_endian); if (m > 0xffff) goto out; if (p0 + m + 2 > end) goto out; if (m + 2 > n) goto out; /* Number of directory entries in this IFD */ o = read_uint16 (p0 + m, is_big_endian); m += 2; for (;;) { guint16 tagnum; if (!o) goto out; if (p0 + m + 12 > end) goto out; if (m + 12 > n) goto out; tagnum = read_uint16 (p0 + m, is_big_endian); if (tagnum == 0x0112) break; o--; m += 12; } m = read_uint16 (p0 + m + 8, is_big_endian); if (m > 9) goto out; rot = m; out: return rot; } /* ----------- * * JPEG loader * * ----------- */ /* --- Memory source --- */ /* libjpeg-turbo can provide jpeg_mem_src (), and usually does. However, we * supply our own for strict conformance with libjpeg v6b. */ static void init_source (G_GNUC_UNUSED j_decompress_ptr cinfo) { } static boolean fill_input_buffer (j_decompress_ptr cinfo) { ERREXIT (cinfo, JERR_INPUT_EMPTY); return TRUE; } static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) { struct jpeg_source_mgr *src = (struct jpeg_source_mgr *) cinfo->src; if (num_bytes < 0) return; num_bytes = MIN ((size_t) num_bytes, src->bytes_in_buffer); src->next_input_byte += (size_t) num_bytes; src->bytes_in_buffer -= (size_t) num_bytes; } static void term_source (G_GNUC_UNUSED j_decompress_ptr cinfo) { } static void my_jpeg_mem_src (j_decompress_ptr cinfo, const void *buffer, long nbytes) { struct jpeg_source_mgr *src; if (cinfo->src == NULL) { cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof (struct jpeg_source_mgr)); } src = (struct jpeg_source_mgr *) cinfo->src; src->init_source = init_source; src->fill_input_buffer = fill_input_buffer; src->skip_input_data = skip_input_data; src->resync_to_restart = jpeg_resync_to_restart; /* Use default method */ src->term_source = term_source; src->bytes_in_buffer = nbytes; src->next_input_byte = (const JOCTET *) buffer; } /* --- Error handler --- */ struct my_jpeg_error_mgr { struct jpeg_error_mgr jerr; jmp_buf setjmp_buffer; }; static void my_jpeg_error_exit (j_common_ptr cinfo) { struct my_jpeg_error_mgr *my_jerr = (struct my_jpeg_error_mgr *) cinfo->err; longjmp (my_jerr->setjmp_buffer, 1); } static void my_jpeg_output_message (G_GNUC_UNUSED j_common_ptr cinfo) { } /* --- Magic probe --- */ static gboolean have_any_apptype_magic (ChicleFileMapping *mapping) { guchar magic [4] = { 0xff, 0xd8, 0xff, 0x00 }; guchar n; for (n = 0xe0; n <= 0xef; n++) { magic [3] = n; /* APPn */ if (chicle_file_mapping_has_magic (mapping, 0, magic, 4)) return TRUE; } magic [3] = 0xdb; /* DQT */ if (chicle_file_mapping_has_magic (mapping, 0, magic, 4)) return TRUE; magic [3] = 0xfe; /* COM */ return chicle_file_mapping_has_magic (mapping, 0, magic, 4); } /* --- Loader --- */ static JpegLoader * chicle_jpeg_loader_new (void) { return g_new0 (JpegLoader, 1); } static guchar convert_cmyk_ch_to_rgb (gint k, gint cmy) { gint v = k * cmy + 128; v = ((v >> 8) + v) >> 8; return (guchar) CLAMP (k - v, 0, 255); } static void convert_cmyk_pixel_to_rgb (const guchar *cmyk, guchar *rgb) { gint c, m, y, k; c = cmyk [0]; m = cmyk [1]; y = cmyk [2]; k = cmyk [3]; rgb [0] = convert_cmyk_ch_to_rgb (k, 255 - c); rgb [1] = convert_cmyk_ch_to_rgb (k, 255 - m); rgb [2] = convert_cmyk_ch_to_rgb (k, 255 - y); } static void convert_cmyk_row_to_rgb (const guchar *cmyk, guchar *rgb, gint width) { gint i; for (i = 0; i < width; i++) convert_cmyk_pixel_to_rgb (cmyk + 4 * i, rgb + 3 * i); } JpegLoader * chicle_jpeg_loader_new_from_mapping (ChicleFileMapping *mapping) { guint width, height; guint rowstride; struct jpeg_decompress_struct cinfo = { 0 }; struct my_jpeg_error_mgr my_jerr; JpegLoader * volatile loader = NULL; gpointer frame_data = NULL; volatile gboolean convert_cmyk_to_rgb = FALSE; guchar *cmyk_buf = NULL; volatile gboolean have_decompress = FALSE; volatile gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); /* Check magic */ if (!have_any_apptype_magic (mapping)) goto out; loader = chicle_jpeg_loader_new (); loader->mapping = mapping; /* Get file data */ loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; /* Prepare to decode */ cinfo.err = jpeg_std_error ((struct jpeg_error_mgr *) &my_jerr); my_jerr.jerr.error_exit = my_jpeg_error_exit; my_jerr.jerr.output_message = my_jpeg_output_message; if (setjmp (my_jerr.setjmp_buffer)) { #ifdef ENABLE_DEBUG static gchar jpeg_error_msg [JMSG_LENGTH_MAX]; (*cinfo.err->format_message) ((j_common_ptr) &cinfo, jpeg_error_msg); g_printerr ("JPEG error: %s\n", jpeg_error_msg); #endif goto out; } jpeg_create_decompress (&cinfo); cinfo.mem->max_memory_to_use = IMAGE_BUFFER_SIZE_MAX; have_decompress = TRUE; my_jpeg_mem_src (&cinfo, loader->file_data, loader->file_data_len); (void) jpeg_read_header (&cinfo, TRUE); if (cinfo.jpeg_color_space == JCS_CMYK || cinfo.jpeg_color_space == JCS_YCCK) { convert_cmyk_to_rgb = TRUE; cinfo.out_color_space = JCS_CMYK; } else { cinfo.out_color_space = JCS_RGB; } cinfo.output_components = 3; jpeg_start_decompress (&cinfo); width = cinfo.output_width; height = cinfo.output_height; if (width < 1 || width >= (1 << 28) || height < 1 || height >= (1 << 28) || (width * (guint64) height >= (1 << 29))) goto out; rowstride = ROWSTRIDE_PAD (width * BYTES_PER_PIXEL); if (height * rowstride > IMAGE_BUFFER_SIZE_MAX) goto out; frame_data = g_malloc (height * (guint64) rowstride); /* Decoding loop */ if (convert_cmyk_to_rgb) cmyk_buf = g_malloc (width * 4); while (cinfo.output_scanline < height) { guchar *row_data = ((guchar *) frame_data) + cinfo.output_scanline * rowstride; if (convert_cmyk_to_rgb) { if (jpeg_read_scanlines (&cinfo, &cmyk_buf, 1) < 1) goto out; convert_cmyk_row_to_rgb (cmyk_buf, row_data, width); } else { if (jpeg_read_scanlines (&cinfo, &row_data, 1) < 1) goto out; } } /* Orientation and cleanup */ (void) jpeg_finish_decompress (&cinfo); chicle_rotate_image (&frame_data, &width, &height, &rowstride, 3, chicle_invert_rotation (read_orientation (loader))); loader->frame_data = frame_data; loader->width = (gint) width; loader->height = (gint) height; loader->rowstride = (gint) rowstride; success = TRUE; out: g_free (cmyk_buf); if (have_decompress) jpeg_destroy_decompress (&cinfo); if (!success) { if (frame_data) g_free (frame_data); if (loader) { g_free (loader); loader = NULL; } } return loader; } void chicle_jpeg_loader_destroy (JpegLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->frame_data) free (loader->frame_data); g_free (loader); } gboolean chicle_jpeg_loader_get_is_animation (JpegLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return FALSE; } gconstpointer chicle_jpeg_loader_get_frame_data (JpegLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) *pixel_type_out = CHAFA_PIXEL_RGB8; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->rowstride; return loader->frame_data; } gint chicle_jpeg_loader_get_frame_delay (JpegLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return 0; } void chicle_jpeg_loader_goto_first_frame (JpegLoader *loader) { g_return_if_fail (loader != NULL); } gboolean chicle_jpeg_loader_goto_next_frame (JpegLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return FALSE; } chafa-1.18.2/tools/chafa/chicle-jpeg-loader.h000066400000000000000000000034431517447374300206610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_JPEG_LOADER_H__ #define __CHICLE_JPEG_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct JpegLoader JpegLoader; JpegLoader *chicle_jpeg_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_jpeg_loader_destroy (JpegLoader *loader); gboolean chicle_jpeg_loader_get_is_animation (JpegLoader *loader); gconstpointer chicle_jpeg_loader_get_frame_data (JpegLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_jpeg_loader_get_frame_delay (JpegLoader *loader); void chicle_jpeg_loader_goto_first_frame (JpegLoader *loader); gboolean chicle_jpeg_loader_goto_next_frame (JpegLoader *loader); G_END_DECLS #endif /* __CHICLE_JPEG_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-jxl-loader.c000066400000000000000000000207101517447374300205200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; ent su: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 oupson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "chafa.h" #include "chicle-file-mapping.h" #include "glib.h" #include #include #include #include #include "chicle-jxl-loader.h" #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) GList *jxl_get_frames (JxlDecoder *dec, JxlParallelRunner *runner, ChicleFileMapping *mapping); void jxl_cleanup_frame_list (GList *frame_list); struct ChicleJxlLoader { GList *frames; int frame_count; int index; }; typedef struct JxlFrame { uint8_t *buffer; int width; int height; gboolean have_alpha; gboolean is_premul; int frame_duration; } JxlFrame; static ChicleJxlLoader * chicle_jxl_loader_new (void) { return g_new0 (ChicleJxlLoader, 1); } GList * jxl_get_frames (JxlDecoder *dec, JxlParallelRunner *runner, ChicleFileMapping *mapping) { if (JXL_DEC_SUCCESS != JxlDecoderSetParallelRunner (dec, JxlResizableParallelRunner, runner)) { return NULL; } if (JXL_DEC_SUCCESS != JxlDecoderSubscribeEvents (dec, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE | JXL_DEC_FRAME)) { return NULL; } JxlPixelFormat format = { 4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0 }; JxlDecoderStatus decode_status = JXL_DEC_NEED_MORE_INPUT; gpointer image_buffer = NULL; GList *frame_list = NULL; JxlBasicInfo info; JxlFrameHeader frame_header; gboolean success = FALSE; guint64 total_alloced = 0; gsize bytes_read = 0; const uint8_t* data = chicle_file_mapping_get_data(mapping, &bytes_read); if (JXL_DEC_SUCCESS != JxlDecoderSetInput (dec, data, bytes_read)) { decode_status = JXL_DEC_ERROR; } JxlDecoderCloseInput(dec); while (JXL_DEC_ERROR != decode_status) { decode_status = JxlDecoderProcessInput (dec); if (JXL_DEC_BASIC_INFO == decode_status) { if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo (dec, &info)) { break; } if (!info.alpha_bits) { format.num_channels = 3; } total_alloced += info.xsize * info.ysize * format.num_channels; if (total_alloced > IMAGE_BUFFER_SIZE_MAX) break; image_buffer = g_malloc (info.xsize * info.ysize * format.num_channels); } else if (JXL_DEC_NEED_IMAGE_OUT_BUFFER == decode_status) { if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer (dec, &format, image_buffer, info.xsize * info.ysize * format.num_channels)) { break; } } else if (JXL_DEC_FRAME == decode_status) { if (JXL_DEC_SUCCESS != JxlDecoderGetFrameHeader (dec, &frame_header)) { break; } } else if (JXL_DEC_FULL_IMAGE == decode_status) { const uint32_t num = info.animation.tps_numerator == 0 ? 1 : info.animation.tps_numerator; JxlFrame *frame = g_new (JxlFrame, 1); frame->buffer = image_buffer; frame->width = info.xsize; frame->height = info.ysize; frame->have_alpha = format.num_channels == 4; frame->is_premul = info.alpha_premultiplied; frame->frame_duration = frame_header.duration * 1000 * info.animation.tps_denominator / num; frame_list = g_list_prepend (frame_list, frame); total_alloced += info.xsize * info.ysize * format.num_channels; if (total_alloced > IMAGE_BUFFER_SIZE_MAX) break; image_buffer = g_malloc (info.xsize * info.ysize * format.num_channels); } else if (JXL_DEC_SUCCESS == decode_status) { frame_list = g_list_reverse (frame_list); success = TRUE; break; } else if (JXL_DEC_NEED_MORE_INPUT == decode_status) { break; } } // Decoding failed if (image_buffer != NULL) { g_free (image_buffer); } if (!success && frame_list != NULL) { jxl_cleanup_frame_list (frame_list); g_list_free (frame_list); frame_list = NULL; } return frame_list; } ChicleJxlLoader * chicle_jxl_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleJxlLoader *loader = NULL; gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); if (!chicle_file_mapping_has_magic (mapping, 0, "\xFF\x0A", 2) && !chicle_file_mapping_has_magic ( mapping, 0, "\x00\x00\x00\x0C\x4A\x58\x4C\x20\x0D\x0A\x87\x0A", 12)) { return NULL; } loader = chicle_jxl_loader_new (); JxlDecoder *decoder = JxlDecoderCreate (NULL); JxlParallelRunner *runner = JxlResizableParallelRunnerCreate (NULL); GList *frames = jxl_get_frames (decoder, runner, mapping); JxlDecoderDestroy (decoder); JxlResizableParallelRunnerDestroy (runner); success = frames != NULL; if (success) { loader->frames = frames; loader->frame_count = g_list_length (frames); loader->index = 0; /* _new_from_mapping() steals the mapping on success. We're done with * it at this point, so destroy. */ chicle_file_mapping_destroy (mapping); } else { if (loader) { g_free (loader); loader = NULL; } } return loader; } void jxl_cleanup_frame_list (GList *frame_list) { GList *frame = frame_list; while (frame != NULL) { if (frame->data != NULL) { JxlFrame *jxl_frame = frame->data; g_free (jxl_frame->buffer); g_free (jxl_frame); frame->data = NULL; } frame = frame->next; } } void chicle_jxl_loader_destroy (ChicleJxlLoader *loader) { GList *list = loader->frames; jxl_cleanup_frame_list (list); g_list_free (loader->frames); g_free (loader); } gboolean chicle_jxl_loader_get_is_animation (ChicleJxlLoader *loader) { return loader->frame_count > 1; } gconstpointer chicle_jxl_loader_get_frame_data (ChicleJxlLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { const JxlFrame *frame; int num_channels; g_return_val_if_fail (loader != NULL, NULL); frame = g_list_nth_data (loader->frames, loader->index); if (frame->have_alpha) { num_channels = 4; *pixel_type_out = frame->is_premul ? CHAFA_PIXEL_RGBA8_PREMULTIPLIED : CHAFA_PIXEL_RGBA8_UNASSOCIATED; } else { num_channels = 3; *pixel_type_out = CHAFA_PIXEL_RGB8; } *width_out = frame->width; *height_out = frame->height; *rowstride_out = frame->width * num_channels; return frame->buffer; } gint chicle_jxl_loader_get_frame_delay (ChicleJxlLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return ((JxlFrame *) g_list_nth_data (loader->frames, loader->index))->frame_duration; } void chicle_jxl_loader_goto_first_frame (ChicleJxlLoader *loader) { g_return_if_fail (loader != NULL); loader->index = 0; } gboolean chicle_jxl_loader_goto_next_frame (ChicleJxlLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); loader->index = loader->index + 1; return loader->index < loader->frame_count; } chafa-1.18.2/tools/chafa/chicle-jxl-loader.h000066400000000000000000000034651517447374300205350ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 oupson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_JXL_LOADER_H__ #define __CHICLE_JXL_LOADER_H__ #include "chicle-file-mapping.h" #include G_BEGIN_DECLS typedef struct ChicleJxlLoader ChicleJxlLoader; ChicleJxlLoader *chicle_jxl_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_jxl_loader_destroy (ChicleJxlLoader *loader); gboolean chicle_jxl_loader_get_is_animation (ChicleJxlLoader *loader); gconstpointer chicle_jxl_loader_get_frame_data (ChicleJxlLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_jxl_loader_get_frame_delay (ChicleJxlLoader *loader); void chicle_jxl_loader_goto_first_frame (ChicleJxlLoader *loader); gboolean chicle_jxl_loader_goto_next_frame (ChicleJxlLoader *loader); G_END_DECLS #endif /* __CHICLE_JXL_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-media-loader.c000066400000000000000000000323051517447374300210050ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "chicle-file-mapping.h" #include "chicle-gif-loader.h" #include "chicle-xwd-loader.h" #include "chicle-jpeg-loader.h" #include "chicle-media-loader.h" #include "chicle-png-loader.h" #include "chicle-qoi-loader.h" #include "chicle-svg-loader.h" #include "chicle-tiff-loader.h" #include "chicle-webp-loader.h" #include "chicle-avif-loader.h" #include "chicle-jxl-loader.h" #include "chicle-heif-loader.h" #include "chicle-coregraphics-loader.h" typedef enum { LOADER_TYPE_GIF, LOADER_TYPE_PNG, LOADER_TYPE_XWD, LOADER_TYPE_QOI, LOADER_TYPE_JPEG, LOADER_TYPE_TIFF, LOADER_TYPE_WEBP, LOADER_TYPE_AVIF, LOADER_TYPE_SVG, LOADER_TYPE_JXL, LOADER_TYPE_COREGRAPHICS, LOADER_TYPE_HEIF, LOADER_TYPE_LAST } LoaderType; typedef gpointer (NewFromMappingFunc) (gpointer, gint, gint); static const struct { const gchar * const name; void (*new_from_mapping) (void); gpointer (*new_from_path) (gconstpointer); void (*destroy) (gpointer); gboolean (*get_is_animation) (gpointer); void (*goto_first_frame) (gpointer); gboolean (*goto_next_frame) (gpointer); gconstpointer (*get_frame_data) (gpointer, gpointer, gpointer, gpointer, gpointer); gint (*get_frame_delay) (gpointer); } loader_vtable [LOADER_TYPE_LAST] = { [LOADER_TYPE_GIF] = { "GIF", (void (*)(void)) chicle_gif_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_gif_loader_destroy, (gboolean (*)(gpointer)) chicle_gif_loader_get_is_animation, (void (*)(gpointer)) chicle_gif_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_gif_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_gif_loader_get_frame_data, (gint (*) (gpointer)) chicle_gif_loader_get_frame_delay }, [LOADER_TYPE_PNG] = { "PNG", (void (*)(void)) chicle_png_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_png_loader_destroy, (gboolean (*)(gpointer)) chicle_png_loader_get_is_animation, (void (*)(gpointer)) chicle_png_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_png_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_png_loader_get_frame_data, (gint (*) (gpointer)) chicle_png_loader_get_frame_delay }, [LOADER_TYPE_XWD] = { "XWD", (void (*)(void)) chicle_xwd_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_xwd_loader_destroy, (gboolean (*)(gpointer)) chicle_xwd_loader_get_is_animation, (void (*)(gpointer)) chicle_xwd_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_xwd_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_xwd_loader_get_frame_data, (gint (*) (gpointer)) chicle_xwd_loader_get_frame_delay }, [LOADER_TYPE_QOI] = { "QOI", (void (*)(void)) chicle_qoi_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_qoi_loader_destroy, (gboolean (*)(gpointer)) chicle_qoi_loader_get_is_animation, (void (*)(gpointer)) chicle_qoi_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_qoi_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_qoi_loader_get_frame_data, (gint (*) (gpointer)) chicle_qoi_loader_get_frame_delay }, #ifdef HAVE_JPEG [LOADER_TYPE_JPEG] = { "JPEG", (void (*)(void)) chicle_jpeg_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_jpeg_loader_destroy, (gboolean (*)(gpointer)) chicle_jpeg_loader_get_is_animation, (void (*)(gpointer)) chicle_jpeg_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_jpeg_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_jpeg_loader_get_frame_data, (gint (*) (gpointer)) chicle_jpeg_loader_get_frame_delay }, #endif #ifdef HAVE_SVG [LOADER_TYPE_SVG] = { "SVG", (void (*)(void)) chicle_svg_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_svg_loader_destroy, (gboolean (*)(gpointer)) chicle_svg_loader_get_is_animation, (void (*)(gpointer)) chicle_svg_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_svg_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_svg_loader_get_frame_data, (gint (*) (gpointer)) chicle_svg_loader_get_frame_delay }, #endif #ifdef HAVE_TIFF [LOADER_TYPE_TIFF] = { "TIFF", (void (*)(void)) chicle_tiff_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_tiff_loader_destroy, (gboolean (*)(gpointer)) chicle_tiff_loader_get_is_animation, (void (*)(gpointer)) chicle_tiff_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_tiff_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_tiff_loader_get_frame_data, (gint (*) (gpointer)) chicle_tiff_loader_get_frame_delay }, #endif #ifdef HAVE_WEBP [LOADER_TYPE_WEBP] = { "WebP", (void (*)(void)) chicle_webp_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_webp_loader_destroy, (gboolean (*)(gpointer)) chicle_webp_loader_get_is_animation, (void (*)(gpointer)) chicle_webp_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_webp_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_webp_loader_get_frame_data, (gint (*) (gpointer)) chicle_webp_loader_get_frame_delay }, #endif #ifdef HAVE_AVIF [LOADER_TYPE_AVIF] = { "AVIF", (void (*)(void)) chicle_avif_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_avif_loader_destroy, (gboolean (*)(gpointer)) chicle_avif_loader_get_is_animation, (void (*)(gpointer)) chicle_avif_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_avif_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_avif_loader_get_frame_data, (gint (*) (gpointer)) chicle_avif_loader_get_frame_delay }, #endif #ifdef HAVE_JXL [LOADER_TYPE_JXL] = { "JXL", (void (*)(void)) chicle_jxl_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_jxl_loader_destroy, (gboolean (*)(gpointer)) chicle_jxl_loader_get_is_animation, (void (*)(gpointer)) chicle_jxl_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_jxl_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_jxl_loader_get_frame_data, (gint (*) (gpointer)) chicle_jxl_loader_get_frame_delay }, #endif #ifdef HAVE_COREGRAPHICS [LOADER_TYPE_COREGRAPHICS] = { "CoreGraphics", (void (*)(void)) chicle_coregraphics_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_coregraphics_loader_destroy, (gboolean (*)(gpointer)) chicle_coregraphics_loader_get_is_animation, (void (*)(gpointer)) chicle_coregraphics_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_coregraphics_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_coregraphics_loader_get_frame_data, (gint (*) (gpointer)) chicle_coregraphics_loader_get_frame_delay }, #endif #ifdef HAVE_HEIF /* Due to its complexity and broad format support, libheif should run last */ [LOADER_TYPE_HEIF] = { "HEIF", (void (*)(void)) chicle_heif_loader_new_from_mapping, (gpointer (*)(gconstpointer)) NULL, (void (*)(gpointer)) chicle_heif_loader_destroy, (gboolean (*)(gpointer)) chicle_heif_loader_get_is_animation, (void (*)(gpointer)) chicle_heif_loader_goto_first_frame, (gboolean (*)(gpointer)) chicle_heif_loader_goto_next_frame, (gconstpointer (*) (gpointer, gpointer, gpointer, gpointer, gpointer)) chicle_heif_loader_get_frame_data, (gint (*) (gpointer)) chicle_heif_loader_get_frame_delay }, #endif }; struct ChicleMediaLoader { LoaderType loader_type; gpointer loader; }; static int ascii_strcasecmp_ptrs (const void *a, const void *b) { gchar * const *sa = a, * const *sb = b; return g_ascii_strcasecmp (*sa, *sb); } ChicleMediaLoader * chicle_media_loader_new (const gchar *path, gint target_width, gint target_height, GError **error) { ChicleMediaLoader *loader; ChicleFileMapping *mapping = NULL; gboolean success = FALSE; gint i; g_return_val_if_fail (path != NULL, NULL); loader = g_new0 (ChicleMediaLoader, 1); mapping = chicle_file_mapping_new (path); if (!chicle_file_mapping_open_now (mapping, error)) goto out; for (i = 0; i < LOADER_TYPE_LAST && !loader->loader; i++) { loader->loader_type = i; if (mapping && loader_vtable [i].new_from_mapping) { loader->loader = (*(NewFromMappingFunc *) loader_vtable [i].new_from_mapping) (mapping, target_width, target_height); } else if (loader_vtable [i].new_from_path) { loader->loader = loader_vtable [i].new_from_path (path); if (loader->loader) chicle_file_mapping_destroy (mapping); } if (loader->loader) { /* Mapping was either transferred to the loader or destroyed by us above */ mapping = NULL; break; } } if (!loader->loader) goto out; success = TRUE; out: if (!success) { if (mapping) chicle_file_mapping_destroy (mapping); chicle_media_loader_destroy (loader); loader = NULL; if (error && !*error) { g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Unknown file format"); } } return loader; } void chicle_media_loader_destroy (ChicleMediaLoader *loader) { if (loader->loader) { loader_vtable [loader->loader_type].destroy (loader->loader); loader->loader = NULL; } g_free (loader); } gboolean chicle_media_loader_get_is_animation (ChicleMediaLoader *loader) { return loader_vtable [loader->loader_type].get_is_animation (loader->loader); } void chicle_media_loader_goto_first_frame (ChicleMediaLoader *loader) { loader_vtable [loader->loader_type].goto_first_frame (loader->loader); } gboolean chicle_media_loader_goto_next_frame (ChicleMediaLoader *loader) { return loader_vtable [loader->loader_type].goto_next_frame (loader->loader); } gconstpointer chicle_media_loader_get_frame_data (ChicleMediaLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { return loader_vtable [loader->loader_type].get_frame_data (loader->loader, pixel_type_out, width_out, height_out, rowstride_out); } gint chicle_media_loader_get_frame_delay (ChicleMediaLoader *loader) { return loader_vtable [loader->loader_type].get_frame_delay (loader->loader); } gchar ** chicle_get_loader_names (void) { gchar **strv; gint i, j; strv = g_new0 (gchar *, LOADER_TYPE_LAST + 1); for (i = 0, j = 0; i < LOADER_TYPE_LAST; i++) { if (loader_vtable [i].name == NULL) continue; strv [j++] = g_strdup (loader_vtable [i].name); } qsort (strv, j, sizeof (gchar *), ascii_strcasecmp_ptrs); return strv; } chafa-1.18.2/tools/chafa/chicle-media-loader.h000066400000000000000000000040351517447374300210110ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_MEDIA_LOADER_H__ #define __CHICLE_MEDIA_LOADER_H__ #include G_BEGIN_DECLS typedef struct ChicleMediaLoader ChicleMediaLoader; ChicleMediaLoader *chicle_media_loader_new (const gchar *path, gint target_width, gint target_height, GError **error); void chicle_media_loader_destroy (ChicleMediaLoader *loader); gboolean chicle_media_loader_get_is_animation (ChicleMediaLoader *loader); void chicle_media_loader_goto_first_frame (ChicleMediaLoader *loader); gboolean chicle_media_loader_goto_next_frame (ChicleMediaLoader *loader); gconstpointer chicle_media_loader_get_frame_data (ChicleMediaLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_media_loader_get_frame_delay (ChicleMediaLoader *loader); gchar **chicle_get_loader_names (void); G_END_DECLS #endif /* __CHICLE_MEDIA_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-media-pipeline.c000066400000000000000000000250631517447374300213470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include "chicle-media-pipeline.h" #define DEBUG(x) typedef struct { gchar *path; ChicleMediaLoader *loader; GString **output; GError *error; } Slot; struct ChicleMediaPipeline { ChiclePathQueue *path_queue; GThreadPool *thread_pool; ChafaTermInfo *term_info; ChafaCanvasConfig *canvas_config; GMutex mutex; GCond cond; Slot *slot_ring; gint first_slot; gint n_slots; gint target_width, target_height; ChafaAlign halign, valign; ChafaTuck tuck; guint want_loader : 1; guint want_output : 1; }; static ChafaCanvas * build_canvas (ChafaPixelType pixel_type, const guint8 *pixels, gint src_width, gint src_height, gint src_rowstride, const ChafaCanvasConfig *config, gint placement_id, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck) { ChafaFrame *frame; ChafaImage *image; ChafaPlacement *placement; ChafaCanvas *canvas; canvas = chafa_canvas_new (config); frame = chafa_frame_new_borrow (pixels, pixel_type, src_width, src_height, src_rowstride); image = chafa_image_new (); chafa_image_set_frame (image, frame); placement = chafa_placement_new (image, placement_id); chafa_placement_set_tuck (placement, tuck); chafa_placement_set_halign (placement, halign); chafa_placement_set_valign (placement, valign); chafa_canvas_set_placement (canvas, placement); chafa_placement_unref (placement); chafa_image_unref (image); chafa_frame_unref (frame); return canvas; } static GString ** format_image (ChicleMediaPipeline *pipeline, ChicleMediaLoader *loader) { ChafaPixelType pixel_type; gconstpointer pixels; ChafaCanvas *canvas = NULL; gint src_width, src_height, src_rowstride; GString **output = NULL; pixels = chicle_media_loader_get_frame_data (loader, &pixel_type, &src_width, &src_height, &src_rowstride); if (!pixels) goto out; canvas = build_canvas (pixel_type, pixels, src_width, src_height, src_rowstride, pipeline->canvas_config, -1, pipeline->halign, pipeline->valign, pipeline->tuck); chafa_canvas_print_rows (canvas, pipeline->term_info, &output, NULL); out: if (canvas) chafa_canvas_unref (canvas); return output; } static void thread_func (gpointer ctx, gpointer data) { ChicleMediaPipeline *pipeline = data; Slot *slot = ctx; ChicleMediaLoader *loader; GString **output = NULL; GError *error = NULL; loader = chicle_media_loader_new (slot->path, pipeline->target_width, pipeline->target_height, &error); if (loader && pipeline->want_output && pipeline->canvas_config && pipeline->term_info) { output = format_image (pipeline, loader); if (!output) g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_FAILED, "Decoding failed"); } if (loader && !pipeline->want_loader) { /* Destroy loaders early to reduce peak memory footprint */ chicle_media_loader_destroy (loader); loader = NULL; } g_mutex_lock (&pipeline->mutex); DEBUG (g_printerr ("Push %s\n", slot->path)); slot->loader = loader; slot->output = output; slot->error = error; g_cond_broadcast (&pipeline->cond); g_mutex_unlock (&pipeline->mutex); } static gint nth_slot (ChicleMediaPipeline *pipeline, gint n) { return (pipeline->first_slot + n) % (pipeline->n_slots); } static void fill_pipeline (ChicleMediaPipeline *pipeline) { gint i; for (i = 0; i < pipeline->n_slots; i++) { Slot *slot = &pipeline->slot_ring [nth_slot (pipeline, i)]; if (slot->path) break; /* Get at least one path, more if available. If we get NULL from a * blocking pop, the path queue is done. */ slot->path = chicle_path_queue_try_pop (pipeline->path_queue); if (!slot->path && i == 0) slot->path = chicle_path_queue_pop (pipeline->path_queue); if (!slot->path) break; DEBUG (g_printerr ("Req (%d) %s\n", nth_slot (pipeline, i), slot->path)); g_thread_pool_push (pipeline->thread_pool, slot, NULL); } } static gboolean wait_for_next (ChicleMediaPipeline *pipeline, gchar **path_out, ChicleMediaLoader **loader_out, GString ***output_out, GError **error_out) { gboolean result = FALSE; g_mutex_lock (&pipeline->mutex); for (;;) { Slot *slot = &pipeline->slot_ring [nth_slot (pipeline, 0)]; fill_pipeline (pipeline); if (!slot->path) { /* Reached end of path queue */ DEBUG (g_printerr ("Reached end (%d)\n", nth_slot (pipeline, 0))); break; } if (slot->loader || slot->output || slot->error) { DEBUG (g_printerr ("Pop (%d) %s\n", nth_slot (pipeline, 0), slot->path)); if (path_out) *path_out = slot->path; else g_free (slot->path); if (loader_out) *loader_out = slot->loader; else if (slot->loader) chicle_media_loader_destroy (slot->loader); if (output_out) *output_out = slot->output; else if (slot->output) chafa_free_gstring_array (slot->output); if (error_out) *error_out = slot->error; else if (slot->error) g_error_free (slot->error); memset (slot, 0, sizeof (*slot)); pipeline->first_slot++; result = TRUE; break; } g_cond_wait (&pipeline->cond, &pipeline->mutex); } g_mutex_unlock (&pipeline->mutex); return result; } ChicleMediaPipeline * chicle_media_pipeline_new (ChiclePathQueue *path_queue, gint target_width, gint target_height) { ChicleMediaPipeline *pipeline; pipeline = g_new0 (ChicleMediaPipeline, 1); pipeline->n_slots = chafa_get_n_actual_threads (); pipeline->slot_ring = g_new0 (Slot, pipeline->n_slots); pipeline->path_queue = chicle_path_queue_ref (path_queue); pipeline->target_width = target_width; pipeline->target_height = target_height; pipeline->want_loader = TRUE; pipeline->want_output = TRUE; g_mutex_init (&pipeline->mutex); g_cond_init (&pipeline->cond); pipeline->thread_pool = g_thread_pool_new ((GFunc) thread_func, (gpointer) pipeline, pipeline->n_slots, FALSE, NULL); return pipeline; } void chicle_media_pipeline_destroy (ChicleMediaPipeline *pipeline) { gint i; g_thread_pool_free (pipeline->thread_pool, FALSE, TRUE); chicle_path_queue_unref (pipeline->path_queue); g_mutex_clear (&pipeline->mutex); g_cond_clear (&pipeline->cond); for (i = 0; i < pipeline->n_slots; i++) { Slot *slot = &pipeline->slot_ring [i]; g_free (slot->path); if (slot->loader) chicle_media_loader_destroy (slot->loader); if (slot->output) chafa_free_gstring_array (slot->output); if (slot->error) g_error_free (slot->error); } if (pipeline->canvas_config) chafa_canvas_config_unref (pipeline->canvas_config); if (pipeline->term_info) chafa_term_info_unref (pipeline->term_info); g_free (pipeline->slot_ring); g_free (pipeline); } void chicle_media_pipeline_set_want_loader (ChicleMediaPipeline *pipeline, gboolean want_loader) { pipeline->want_loader = !!want_loader; } void chicle_media_pipeline_set_want_output (ChicleMediaPipeline *pipeline, gboolean want_output) { pipeline->want_output = !!want_output; } void chicle_media_pipeline_set_formatting (ChicleMediaPipeline *pipeline, ChafaCanvasConfig *canvas_config, ChafaTermInfo *term_info, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck) { ChafaCanvasConfig *old_canvas_config = pipeline->canvas_config; ChafaTermInfo *old_term_info = pipeline->term_info; if (canvas_config) chafa_canvas_config_ref (canvas_config); pipeline->canvas_config = canvas_config; if (old_canvas_config) chafa_canvas_config_unref (old_canvas_config); if (term_info) chafa_term_info_ref (term_info); pipeline->term_info = term_info; if (old_term_info) chafa_term_info_unref (old_term_info); pipeline->halign = halign; pipeline->valign = valign; pipeline->tuck = tuck; } gboolean chicle_media_pipeline_pop (ChicleMediaPipeline *pipeline, gchar **path_out, ChicleMediaLoader **loader_out, GString ***output_out, GError **error_out) { gboolean result; result = wait_for_next (pipeline, path_out, loader_out, output_out, error_out); return result; } chafa-1.18.2/tools/chafa/chicle-media-pipeline.h000066400000000000000000000045571517447374300213610ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_MEDIA_PIPELINE_H__ #define __CHICLE_MEDIA_PIPELINE_H__ #include #include "chicle-media-loader.h" #include "chicle-path-queue.h" G_BEGIN_DECLS typedef struct ChicleMediaPipeline ChicleMediaPipeline; ChicleMediaPipeline *chicle_media_pipeline_new (ChiclePathQueue *path_queue, gint target_width, gint target_height); void chicle_media_pipeline_destroy (ChicleMediaPipeline *pipeline); void chicle_media_pipeline_set_want_loader (ChicleMediaPipeline *pipeline, gboolean want_loader); void chicle_media_pipeline_set_want_output (ChicleMediaPipeline *pipeline, gboolean want_output); void chicle_media_pipeline_set_formatting (ChicleMediaPipeline *pipeline, ChafaCanvasConfig *canvas_config, ChafaTermInfo *term_info, ChafaAlign halign, ChafaAlign valign, ChafaTuck tuck); gboolean chicle_media_pipeline_pop (ChicleMediaPipeline *pipeline, gchar **path_out, ChicleMediaLoader **loader_out, GString ***output_out, GError **error_out); G_END_DECLS #endif /* __CHICLE_MEDIA_PIPELINE_H__ */ chafa-1.18.2/tools/chafa/chicle-named-colors.c000066400000000000000000000700511517447374300210450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* strlen */ #include "chicle-named-colors.h" /* These colors are from X.Org's rgb.txt, filtered to remove duplicate * entries with spaces in them. We handle names with spaces in the lookup * function instead. Grey/gray variants were kept. * * For more background see https://en.wikipedia.org/wiki/X11_color_names */ static const ChicleNamedColor named_colors [] = { { { 255, 250, 250 }, "snow" }, { { 248, 248, 255 }, "GhostWhite" }, { { 245, 245, 245 }, "WhiteSmoke" }, { { 220, 220, 220 }, "gainsboro" }, { { 255, 250, 240 }, "FloralWhite" }, { { 253, 245, 230 }, "OldLace" }, { { 250, 240, 230 }, "linen" }, { { 250, 235, 215 }, "AntiqueWhite" }, { { 255, 239, 213 }, "PapayaWhip" }, { { 255, 235, 205 }, "BlanchedAlmond" }, { { 255, 228, 196 }, "bisque" }, { { 255, 218, 185 }, "PeachPuff" }, { { 255, 222, 173 }, "NavajoWhite" }, { { 255, 228, 181 }, "moccasin" }, { { 255, 248, 220 }, "cornsilk" }, { { 255, 255, 240 }, "ivory" }, { { 255, 250, 205 }, "LemonChiffon" }, { { 255, 245, 238 }, "seashell" }, { { 240, 255, 240 }, "honeydew" }, { { 245, 255, 250 }, "MintCream" }, { { 240, 255, 255 }, "azure" }, { { 240, 248, 255 }, "AliceBlue" }, { { 230, 230, 250 }, "lavender" }, { { 255, 240, 245 }, "LavenderBlush" }, { { 255, 228, 225 }, "MistyRose" }, { { 255, 255, 255 }, "white" }, { { 0, 0, 0 }, "black" }, { { 47, 79, 79 }, "DarkSlateGray" }, { { 47, 79, 79 }, "DarkSlateGrey" }, { { 105, 105, 105 }, "DimGray" }, { { 105, 105, 105 }, "DimGrey" }, { { 112, 128, 144 }, "SlateGray" }, { { 112, 128, 144 }, "SlateGrey" }, { { 119, 136, 153 }, "LightSlateGray" }, { { 119, 136, 153 }, "LightSlateGrey" }, { { 190, 190, 190 }, "gray" }, { { 190, 190, 190 }, "grey" }, { { 190, 190, 190 }, "X11Gray" }, { { 190, 190, 190 }, "X11Grey" }, { { 128, 128, 128 }, "WebGray" }, { { 128, 128, 128 }, "WebGrey" }, { { 211, 211, 211 }, "LightGrey" }, { { 211, 211, 211 }, "LightGray" }, { { 25, 25, 112 }, "MidnightBlue" }, { { 0, 0, 128 }, "navy" }, { { 0, 0, 128 }, "NavyBlue" }, { { 100, 149, 237 }, "CornflowerBlue" }, { { 72, 61, 139 }, "DarkSlateBlue" }, { { 106, 90, 205 }, "SlateBlue" }, { { 123, 104, 238 }, "MediumSlateBlue" }, { { 132, 112, 255 }, "LightSlateBlue" }, { { 0, 0, 205 }, "MediumBlue" }, { { 65, 105, 225 }, "RoyalBlue" }, { { 0, 0, 255 }, "blue" }, { { 30, 144, 255 }, "DodgerBlue" }, { { 0, 191, 255 }, "DeepSkyBlue" }, { { 135, 206, 235 }, "SkyBlue" }, { { 135, 206, 250 }, "LightSkyBlue" }, { { 70, 130, 180 }, "SteelBlue" }, { { 176, 196, 222 }, "LightSteelBlue" }, { { 173, 216, 230 }, "LightBlue" }, { { 176, 224, 230 }, "PowderBlue" }, { { 175, 238, 238 }, "PaleTurquoise" }, { { 0, 206, 209 }, "DarkTurquoise" }, { { 72, 209, 204 }, "MediumTurquoise" }, { { 64, 224, 208 }, "turquoise" }, { { 0, 255, 255 }, "cyan" }, { { 0, 255, 255 }, "aqua" }, { { 224, 255, 255 }, "LightCyan" }, { { 95, 158, 160 }, "CadetBlue" }, { { 102, 205, 170 }, "MediumAquamarine" }, { { 127, 255, 212 }, "aquamarine" }, { { 0, 100, 0 }, "DarkGreen" }, { { 85, 107, 47 }, "DarkOliveGreen" }, { { 143, 188, 143 }, "DarkSeaGreen" }, { { 46, 139, 87 }, "SeaGreen" }, { { 60, 179, 113 }, "MediumSeaGreen" }, { { 32, 178, 170 }, "LightSeaGreen" }, { { 152, 251, 152 }, "PaleGreen" }, { { 0, 255, 127 }, "SpringGreen" }, { { 124, 252, 0 }, "LawnGreen" }, { { 0, 255, 0 }, "green" }, { { 0, 255, 0 }, "lime" }, { { 0, 255, 0 }, "X11Green" }, { { 0, 128, 0 }, "WebGreen" }, { { 127, 255, 0 }, "chartreuse" }, { { 0, 250, 154 }, "MediumSpringGreen" }, { { 173, 255, 47 }, "GreenYellow" }, { { 50, 205, 50 }, "LimeGreen" }, { { 154, 205, 50 }, "YellowGreen" }, { { 34, 139, 34 }, "ForestGreen" }, { { 107, 142, 35 }, "OliveDrab" }, { { 189, 183, 107 }, "DarkKhaki" }, { { 240, 230, 140 }, "khaki" }, { { 238, 232, 170 }, "PaleGoldenrod" }, { { 250, 250, 210 }, "LightGoldenrodYellow" }, { { 255, 255, 224 }, "LightYellow" }, { { 255, 255, 0 }, "yellow" }, { { 255, 215, 0 }, "gold" }, { { 238, 221, 130 }, "LightGoldenrod" }, { { 218, 165, 32 }, "goldenrod" }, { { 184, 134, 11 }, "DarkGoldenrod" }, { { 188, 143, 143 }, "RosyBrown" }, { { 205, 92, 92 }, "IndianRed" }, { { 139, 69, 19 }, "SaddleBrown" }, { { 160, 82, 45 }, "sienna" }, { { 205, 133, 63 }, "peru" }, { { 222, 184, 135 }, "burlywood" }, { { 245, 245, 220 }, "beige" }, { { 245, 222, 179 }, "wheat" }, { { 244, 164, 96 }, "SandyBrown" }, { { 210, 180, 140 }, "tan" }, { { 210, 105, 30 }, "chocolate" }, { { 178, 34, 34 }, "firebrick" }, { { 165, 42, 42 }, "brown" }, { { 233, 150, 122 }, "DarkSalmon" }, { { 250, 128, 114 }, "salmon" }, { { 255, 160, 122 }, "LightSalmon" }, { { 255, 165, 0 }, "orange" }, { { 255, 140, 0 }, "DarkOrange" }, { { 255, 127, 80 }, "coral" }, { { 240, 128, 128 }, "LightCoral" }, { { 255, 99, 71 }, "tomato" }, { { 255, 69, 0 }, "OrangeRed" }, { { 255, 0, 0 }, "red" }, { { 255, 105, 180 }, "HotPink" }, { { 255, 20, 147 }, "DeepPink" }, { { 255, 192, 203 }, "pink" }, { { 255, 182, 193 }, "LightPink" }, { { 219, 112, 147 }, "PaleVioletRed" }, { { 176, 48, 96 }, "maroon" }, { { 176, 48, 96 }, "X11Maroon" }, { { 128, 0, 0 }, "WebMaroon" }, { { 199, 21, 133 }, "MediumVioletRed" }, { { 208, 32, 144 }, "VioletRed" }, { { 255, 0, 255 }, "magenta" }, { { 255, 0, 255 }, "fuchsia" }, { { 238, 130, 238 }, "violet" }, { { 221, 160, 221 }, "plum" }, { { 218, 112, 214 }, "orchid" }, { { 186, 85, 211 }, "MediumOrchid" }, { { 153, 50, 204 }, "DarkOrchid" }, { { 148, 0, 211 }, "DarkViolet" }, { { 138, 43, 226 }, "BlueViolet" }, { { 160, 32, 240 }, "purple" }, { { 160, 32, 240 }, "X11Purple" }, { { 128, 0, 128 }, "WebPurple" }, { { 147, 112, 219 }, "MediumPurple" }, { { 216, 191, 216 }, "thistle" }, { { 255, 250, 250 }, "snow1" }, { { 238, 233, 233 }, "snow2" }, { { 205, 201, 201 }, "snow3" }, { { 139, 137, 137 }, "snow4" }, { { 255, 245, 238 }, "seashell1" }, { { 238, 229, 222 }, "seashell2" }, { { 205, 197, 191 }, "seashell3" }, { { 139, 134, 130 }, "seashell4" }, { { 255, 239, 219 }, "AntiqueWhite1" }, { { 238, 223, 204 }, "AntiqueWhite2" }, { { 205, 192, 176 }, "AntiqueWhite3" }, { { 139, 131, 120 }, "AntiqueWhite4" }, { { 255, 228, 196 }, "bisque1" }, { { 238, 213, 183 }, "bisque2" }, { { 205, 183, 158 }, "bisque3" }, { { 139, 125, 107 }, "bisque4" }, { { 255, 218, 185 }, "PeachPuff1" }, { { 238, 203, 173 }, "PeachPuff2" }, { { 205, 175, 149 }, "PeachPuff3" }, { { 139, 119, 101 }, "PeachPuff4" }, { { 255, 222, 173 }, "NavajoWhite1" }, { { 238, 207, 161 }, "NavajoWhite2" }, { { 205, 179, 139 }, "NavajoWhite3" }, { { 139, 121, 94 }, "NavajoWhite4" }, { { 255, 250, 205 }, "LemonChiffon1" }, { { 238, 233, 191 }, "LemonChiffon2" }, { { 205, 201, 165 }, "LemonChiffon3" }, { { 139, 137, 112 }, "LemonChiffon4" }, { { 255, 248, 220 }, "cornsilk1" }, { { 238, 232, 205 }, "cornsilk2" }, { { 205, 200, 177 }, "cornsilk3" }, { { 139, 136, 120 }, "cornsilk4" }, { { 255, 255, 240 }, "ivory1" }, { { 238, 238, 224 }, "ivory2" }, { { 205, 205, 193 }, "ivory3" }, { { 139, 139, 131 }, "ivory4" }, { { 240, 255, 240 }, "honeydew1" }, { { 224, 238, 224 }, "honeydew2" }, { { 193, 205, 193 }, "honeydew3" }, { { 131, 139, 131 }, "honeydew4" }, { { 255, 240, 245 }, "LavenderBlush1" }, { { 238, 224, 229 }, "LavenderBlush2" }, { { 205, 193, 197 }, "LavenderBlush3" }, { { 139, 131, 134 }, "LavenderBlush4" }, { { 255, 228, 225 }, "MistyRose1" }, { { 238, 213, 210 }, "MistyRose2" }, { { 205, 183, 181 }, "MistyRose3" }, { { 139, 125, 123 }, "MistyRose4" }, { { 240, 255, 255 }, "azure1" }, { { 224, 238, 238 }, "azure2" }, { { 193, 205, 205 }, "azure3" }, { { 131, 139, 139 }, "azure4" }, { { 131, 111, 255 }, "SlateBlue1" }, { { 122, 103, 238 }, "SlateBlue2" }, { { 105, 89, 205 }, "SlateBlue3" }, { { 71, 60, 139 }, "SlateBlue4" }, { { 72, 118, 255 }, "RoyalBlue1" }, { { 67, 110, 238 }, "RoyalBlue2" }, { { 58, 95, 205 }, "RoyalBlue3" }, { { 39, 64, 139 }, "RoyalBlue4" }, { { 0, 0, 255 }, "blue1" }, { { 0, 0, 238 }, "blue2" }, { { 0, 0, 205 }, "blue3" }, { { 0, 0, 139 }, "blue4" }, { { 30, 144, 255 }, "DodgerBlue1" }, { { 28, 134, 238 }, "DodgerBlue2" }, { { 24, 116, 205 }, "DodgerBlue3" }, { { 16, 78, 139 }, "DodgerBlue4" }, { { 99, 184, 255 }, "SteelBlue1" }, { { 92, 172, 238 }, "SteelBlue2" }, { { 79, 148, 205 }, "SteelBlue3" }, { { 54, 100, 139 }, "SteelBlue4" }, { { 0, 191, 255 }, "DeepSkyBlue1" }, { { 0, 178, 238 }, "DeepSkyBlue2" }, { { 0, 154, 205 }, "DeepSkyBlue3" }, { { 0, 104, 139 }, "DeepSkyBlue4" }, { { 135, 206, 255 }, "SkyBlue1" }, { { 126, 192, 238 }, "SkyBlue2" }, { { 108, 166, 205 }, "SkyBlue3" }, { { 74, 112, 139 }, "SkyBlue4" }, { { 176, 226, 255 }, "LightSkyBlue1" }, { { 164, 211, 238 }, "LightSkyBlue2" }, { { 141, 182, 205 }, "LightSkyBlue3" }, { { 96, 123, 139 }, "LightSkyBlue4" }, { { 198, 226, 255 }, "SlateGray1" }, { { 185, 211, 238 }, "SlateGray2" }, { { 159, 182, 205 }, "SlateGray3" }, { { 108, 123, 139 }, "SlateGray4" }, { { 202, 225, 255 }, "LightSteelBlue1" }, { { 188, 210, 238 }, "LightSteelBlue2" }, { { 162, 181, 205 }, "LightSteelBlue3" }, { { 110, 123, 139 }, "LightSteelBlue4" }, { { 191, 239, 255 }, "LightBlue1" }, { { 178, 223, 238 }, "LightBlue2" }, { { 154, 192, 205 }, "LightBlue3" }, { { 104, 131, 139 }, "LightBlue4" }, { { 224, 255, 255 }, "LightCyan1" }, { { 209, 238, 238 }, "LightCyan2" }, { { 180, 205, 205 }, "LightCyan3" }, { { 122, 139, 139 }, "LightCyan4" }, { { 187, 255, 255 }, "PaleTurquoise1" }, { { 174, 238, 238 }, "PaleTurquoise2" }, { { 150, 205, 205 }, "PaleTurquoise3" }, { { 102, 139, 139 }, "PaleTurquoise4" }, { { 152, 245, 255 }, "CadetBlue1" }, { { 142, 229, 238 }, "CadetBlue2" }, { { 122, 197, 205 }, "CadetBlue3" }, { { 83, 134, 139 }, "CadetBlue4" }, { { 0, 245, 255 }, "turquoise1" }, { { 0, 229, 238 }, "turquoise2" }, { { 0, 197, 205 }, "turquoise3" }, { { 0, 134, 139 }, "turquoise4" }, { { 0, 255, 255 }, "cyan1" }, { { 0, 238, 238 }, "cyan2" }, { { 0, 205, 205 }, "cyan3" }, { { 0, 139, 139 }, "cyan4" }, { { 151, 255, 255 }, "DarkSlateGray1" }, { { 141, 238, 238 }, "DarkSlateGray2" }, { { 121, 205, 205 }, "DarkSlateGray3" }, { { 82, 139, 139 }, "DarkSlateGray4" }, { { 127, 255, 212 }, "aquamarine1" }, { { 118, 238, 198 }, "aquamarine2" }, { { 102, 205, 170 }, "aquamarine3" }, { { 69, 139, 116 }, "aquamarine4" }, { { 193, 255, 193 }, "DarkSeaGreen1" }, { { 180, 238, 180 }, "DarkSeaGreen2" }, { { 155, 205, 155 }, "DarkSeaGreen3" }, { { 105, 139, 105 }, "DarkSeaGreen4" }, { { 84, 255, 159 }, "SeaGreen1" }, { { 78, 238, 148 }, "SeaGreen2" }, { { 67, 205, 128 }, "SeaGreen3" }, { { 46, 139, 87 }, "SeaGreen4" }, { { 154, 255, 154 }, "PaleGreen1" }, { { 144, 238, 144 }, "PaleGreen2" }, { { 124, 205, 124 }, "PaleGreen3" }, { { 84, 139, 84 }, "PaleGreen4" }, { { 0, 255, 127 }, "SpringGreen1" }, { { 0, 238, 118 }, "SpringGreen2" }, { { 0, 205, 102 }, "SpringGreen3" }, { { 0, 139, 69 }, "SpringGreen4" }, { { 0, 255, 0 }, "green1" }, { { 0, 238, 0 }, "green2" }, { { 0, 205, 0 }, "green3" }, { { 0, 139, 0 }, "green4" }, { { 127, 255, 0 }, "chartreuse1" }, { { 118, 238, 0 }, "chartreuse2" }, { { 102, 205, 0 }, "chartreuse3" }, { { 69, 139, 0 }, "chartreuse4" }, { { 192, 255, 62 }, "OliveDrab1" }, { { 179, 238, 58 }, "OliveDrab2" }, { { 154, 205, 50 }, "OliveDrab3" }, { { 105, 139, 34 }, "OliveDrab4" }, { { 202, 255, 112 }, "DarkOliveGreen1" }, { { 188, 238, 104 }, "DarkOliveGreen2" }, { { 162, 205, 90 }, "DarkOliveGreen3" }, { { 110, 139, 61 }, "DarkOliveGreen4" }, { { 255, 246, 143 }, "khaki1" }, { { 238, 230, 133 }, "khaki2" }, { { 205, 198, 115 }, "khaki3" }, { { 139, 134, 78 }, "khaki4" }, { { 255, 236, 139 }, "LightGoldenrod1" }, { { 238, 220, 130 }, "LightGoldenrod2" }, { { 205, 190, 112 }, "LightGoldenrod3" }, { { 139, 129, 76 }, "LightGoldenrod4" }, { { 255, 255, 224 }, "LightYellow1" }, { { 238, 238, 209 }, "LightYellow2" }, { { 205, 205, 180 }, "LightYellow3" }, { { 139, 139, 122 }, "LightYellow4" }, { { 255, 255, 0 }, "yellow1" }, { { 238, 238, 0 }, "yellow2" }, { { 205, 205, 0 }, "yellow3" }, { { 139, 139, 0 }, "yellow4" }, { { 255, 215, 0 }, "gold1" }, { { 238, 201, 0 }, "gold2" }, { { 205, 173, 0 }, "gold3" }, { { 139, 117, 0 }, "gold4" }, { { 255, 193, 37 }, "goldenrod1" }, { { 238, 180, 34 }, "goldenrod2" }, { { 205, 155, 29 }, "goldenrod3" }, { { 139, 105, 20 }, "goldenrod4" }, { { 255, 185, 15 }, "DarkGoldenrod1" }, { { 238, 173, 14 }, "DarkGoldenrod2" }, { { 205, 149, 12 }, "DarkGoldenrod3" }, { { 139, 101, 8 }, "DarkGoldenrod4" }, { { 255, 193, 193 }, "RosyBrown1" }, { { 238, 180, 180 }, "RosyBrown2" }, { { 205, 155, 155 }, "RosyBrown3" }, { { 139, 105, 105 }, "RosyBrown4" }, { { 255, 106, 106 }, "IndianRed1" }, { { 238, 99, 99 }, "IndianRed2" }, { { 205, 85, 85 }, "IndianRed3" }, { { 139, 58, 58 }, "IndianRed4" }, { { 255, 130, 71 }, "sienna1" }, { { 238, 121, 66 }, "sienna2" }, { { 205, 104, 57 }, "sienna3" }, { { 139, 71, 38 }, "sienna4" }, { { 255, 211, 155 }, "burlywood1" }, { { 238, 197, 145 }, "burlywood2" }, { { 205, 170, 125 }, "burlywood3" }, { { 139, 115, 85 }, "burlywood4" }, { { 255, 231, 186 }, "wheat1" }, { { 238, 216, 174 }, "wheat2" }, { { 205, 186, 150 }, "wheat3" }, { { 139, 126, 102 }, "wheat4" }, { { 255, 165, 79 }, "tan1" }, { { 238, 154, 73 }, "tan2" }, { { 205, 133, 63 }, "tan3" }, { { 139, 90, 43 }, "tan4" }, { { 255, 127, 36 }, "chocolate1" }, { { 238, 118, 33 }, "chocolate2" }, { { 205, 102, 29 }, "chocolate3" }, { { 139, 69, 19 }, "chocolate4" }, { { 255, 48, 48 }, "firebrick1" }, { { 238, 44, 44 }, "firebrick2" }, { { 205, 38, 38 }, "firebrick3" }, { { 139, 26, 26 }, "firebrick4" }, { { 255, 64, 64 }, "brown1" }, { { 238, 59, 59 }, "brown2" }, { { 205, 51, 51 }, "brown3" }, { { 139, 35, 35 }, "brown4" }, { { 255, 140, 105 }, "salmon1" }, { { 238, 130, 98 }, "salmon2" }, { { 205, 112, 84 }, "salmon3" }, { { 139, 76, 57 }, "salmon4" }, { { 255, 160, 122 }, "LightSalmon1" }, { { 238, 149, 114 }, "LightSalmon2" }, { { 205, 129, 98 }, "LightSalmon3" }, { { 139, 87, 66 }, "LightSalmon4" }, { { 255, 165, 0 }, "orange1" }, { { 238, 154, 0 }, "orange2" }, { { 205, 133, 0 }, "orange3" }, { { 139, 90, 0 }, "orange4" }, { { 255, 127, 0 }, "DarkOrange1" }, { { 238, 118, 0 }, "DarkOrange2" }, { { 205, 102, 0 }, "DarkOrange3" }, { { 139, 69, 0 }, "DarkOrange4" }, { { 255, 114, 86 }, "coral1" }, { { 238, 106, 80 }, "coral2" }, { { 205, 91, 69 }, "coral3" }, { { 139, 62, 47 }, "coral4" }, { { 255, 99, 71 }, "tomato1" }, { { 238, 92, 66 }, "tomato2" }, { { 205, 79, 57 }, "tomato3" }, { { 139, 54, 38 }, "tomato4" }, { { 255, 69, 0 }, "OrangeRed1" }, { { 238, 64, 0 }, "OrangeRed2" }, { { 205, 55, 0 }, "OrangeRed3" }, { { 139, 37, 0 }, "OrangeRed4" }, { { 255, 0, 0 }, "red1" }, { { 238, 0, 0 }, "red2" }, { { 205, 0, 0 }, "red3" }, { { 139, 0, 0 }, "red4" }, { { 255, 20, 147 }, "DeepPink1" }, { { 238, 18, 137 }, "DeepPink2" }, { { 205, 16, 118 }, "DeepPink3" }, { { 139, 10, 80 }, "DeepPink4" }, { { 255, 110, 180 }, "HotPink1" }, { { 238, 106, 167 }, "HotPink2" }, { { 205, 96, 144 }, "HotPink3" }, { { 139, 58, 98 }, "HotPink4" }, { { 255, 181, 197 }, "pink1" }, { { 238, 169, 184 }, "pink2" }, { { 205, 145, 158 }, "pink3" }, { { 139, 99, 108 }, "pink4" }, { { 255, 174, 185 }, "LightPink1" }, { { 238, 162, 173 }, "LightPink2" }, { { 205, 140, 149 }, "LightPink3" }, { { 139, 95, 101 }, "LightPink4" }, { { 255, 130, 171 }, "PaleVioletRed1" }, { { 238, 121, 159 }, "PaleVioletRed2" }, { { 205, 104, 137 }, "PaleVioletRed3" }, { { 139, 71, 93 }, "PaleVioletRed4" }, { { 255, 52, 179 }, "maroon1" }, { { 238, 48, 167 }, "maroon2" }, { { 205, 41, 144 }, "maroon3" }, { { 139, 28, 98 }, "maroon4" }, { { 255, 62, 150 }, "VioletRed1" }, { { 238, 58, 140 }, "VioletRed2" }, { { 205, 50, 120 }, "VioletRed3" }, { { 139, 34, 82 }, "VioletRed4" }, { { 255, 0, 255 }, "magenta1" }, { { 238, 0, 238 }, "magenta2" }, { { 205, 0, 205 }, "magenta3" }, { { 139, 0, 139 }, "magenta4" }, { { 255, 131, 250 }, "orchid1" }, { { 238, 122, 233 }, "orchid2" }, { { 205, 105, 201 }, "orchid3" }, { { 139, 71, 137 }, "orchid4" }, { { 255, 187, 255 }, "plum1" }, { { 238, 174, 238 }, "plum2" }, { { 205, 150, 205 }, "plum3" }, { { 139, 102, 139 }, "plum4" }, { { 224, 102, 255 }, "MediumOrchid1" }, { { 209, 95, 238 }, "MediumOrchid2" }, { { 180, 82, 205 }, "MediumOrchid3" }, { { 122, 55, 139 }, "MediumOrchid4" }, { { 191, 62, 255 }, "DarkOrchid1" }, { { 178, 58, 238 }, "DarkOrchid2" }, { { 154, 50, 205 }, "DarkOrchid3" }, { { 104, 34, 139 }, "DarkOrchid4" }, { { 155, 48, 255 }, "purple1" }, { { 145, 44, 238 }, "purple2" }, { { 125, 38, 205 }, "purple3" }, { { 85, 26, 139 }, "purple4" }, { { 171, 130, 255 }, "MediumPurple1" }, { { 159, 121, 238 }, "MediumPurple2" }, { { 137, 104, 205 }, "MediumPurple3" }, { { 93, 71, 139 }, "MediumPurple4" }, { { 255, 225, 255 }, "thistle1" }, { { 238, 210, 238 }, "thistle2" }, { { 205, 181, 205 }, "thistle3" }, { { 139, 123, 139 }, "thistle4" }, { { 0, 0, 0 }, "gray0" }, { { 0, 0, 0 }, "grey0" }, { { 3, 3, 3 }, "gray1" }, { { 3, 3, 3 }, "grey1" }, { { 5, 5, 5 }, "gray2" }, { { 5, 5, 5 }, "grey2" }, { { 8, 8, 8 }, "gray3" }, { { 8, 8, 8 }, "grey3" }, { { 10, 10, 10 }, "gray4" }, { { 10, 10, 10 }, "grey4" }, { { 13, 13, 13 }, "gray5" }, { { 13, 13, 13 }, "grey5" }, { { 15, 15, 15 }, "gray6" }, { { 15, 15, 15 }, "grey6" }, { { 18, 18, 18 }, "gray7" }, { { 18, 18, 18 }, "grey7" }, { { 20, 20, 20 }, "gray8" }, { { 20, 20, 20 }, "grey8" }, { { 23, 23, 23 }, "gray9" }, { { 23, 23, 23 }, "grey9" }, { { 26, 26, 26 }, "gray10" }, { { 26, 26, 26 }, "grey10" }, { { 28, 28, 28 }, "gray11" }, { { 28, 28, 28 }, "grey11" }, { { 31, 31, 31 }, "gray12" }, { { 31, 31, 31 }, "grey12" }, { { 33, 33, 33 }, "gray13" }, { { 33, 33, 33 }, "grey13" }, { { 36, 36, 36 }, "gray14" }, { { 36, 36, 36 }, "grey14" }, { { 38, 38, 38 }, "gray15" }, { { 38, 38, 38 }, "grey15" }, { { 41, 41, 41 }, "gray16" }, { { 41, 41, 41 }, "grey16" }, { { 43, 43, 43 }, "gray17" }, { { 43, 43, 43 }, "grey17" }, { { 46, 46, 46 }, "gray18" }, { { 46, 46, 46 }, "grey18" }, { { 48, 48, 48 }, "gray19" }, { { 48, 48, 48 }, "grey19" }, { { 51, 51, 51 }, "gray20" }, { { 51, 51, 51 }, "grey20" }, { { 54, 54, 54 }, "gray21" }, { { 54, 54, 54 }, "grey21" }, { { 56, 56, 56 }, "gray22" }, { { 56, 56, 56 }, "grey22" }, { { 59, 59, 59 }, "gray23" }, { { 59, 59, 59 }, "grey23" }, { { 61, 61, 61 }, "gray24" }, { { 61, 61, 61 }, "grey24" }, { { 64, 64, 64 }, "gray25" }, { { 64, 64, 64 }, "grey25" }, { { 66, 66, 66 }, "gray26" }, { { 66, 66, 66 }, "grey26" }, { { 69, 69, 69 }, "gray27" }, { { 69, 69, 69 }, "grey27" }, { { 71, 71, 71 }, "gray28" }, { { 71, 71, 71 }, "grey28" }, { { 74, 74, 74 }, "gray29" }, { { 74, 74, 74 }, "grey29" }, { { 77, 77, 77 }, "gray30" }, { { 77, 77, 77 }, "grey30" }, { { 79, 79, 79 }, "gray31" }, { { 79, 79, 79 }, "grey31" }, { { 82, 82, 82 }, "gray32" }, { { 82, 82, 82 }, "grey32" }, { { 84, 84, 84 }, "gray33" }, { { 84, 84, 84 }, "grey33" }, { { 87, 87, 87 }, "gray34" }, { { 87, 87, 87 }, "grey34" }, { { 89, 89, 89 }, "gray35" }, { { 89, 89, 89 }, "grey35" }, { { 92, 92, 92 }, "gray36" }, { { 92, 92, 92 }, "grey36" }, { { 94, 94, 94 }, "gray37" }, { { 94, 94, 94 }, "grey37" }, { { 97, 97, 97 }, "gray38" }, { { 97, 97, 97 }, "grey38" }, { { 99, 99, 99 }, "gray39" }, { { 99, 99, 99 }, "grey39" }, { { 102, 102, 102 }, "gray40" }, { { 102, 102, 102 }, "grey40" }, { { 105, 105, 105 }, "gray41" }, { { 105, 105, 105 }, "grey41" }, { { 107, 107, 107 }, "gray42" }, { { 107, 107, 107 }, "grey42" }, { { 110, 110, 110 }, "gray43" }, { { 110, 110, 110 }, "grey43" }, { { 112, 112, 112 }, "gray44" }, { { 112, 112, 112 }, "grey44" }, { { 115, 115, 115 }, "gray45" }, { { 115, 115, 115 }, "grey45" }, { { 117, 117, 117 }, "gray46" }, { { 117, 117, 117 }, "grey46" }, { { 120, 120, 120 }, "gray47" }, { { 120, 120, 120 }, "grey47" }, { { 122, 122, 122 }, "gray48" }, { { 122, 122, 122 }, "grey48" }, { { 125, 125, 125 }, "gray49" }, { { 125, 125, 125 }, "grey49" }, { { 127, 127, 127 }, "gray50" }, { { 127, 127, 127 }, "grey50" }, { { 130, 130, 130 }, "gray51" }, { { 130, 130, 130 }, "grey51" }, { { 133, 133, 133 }, "gray52" }, { { 133, 133, 133 }, "grey52" }, { { 135, 135, 135 }, "gray53" }, { { 135, 135, 135 }, "grey53" }, { { 138, 138, 138 }, "gray54" }, { { 138, 138, 138 }, "grey54" }, { { 140, 140, 140 }, "gray55" }, { { 140, 140, 140 }, "grey55" }, { { 143, 143, 143 }, "gray56" }, { { 143, 143, 143 }, "grey56" }, { { 145, 145, 145 }, "gray57" }, { { 145, 145, 145 }, "grey57" }, { { 148, 148, 148 }, "gray58" }, { { 148, 148, 148 }, "grey58" }, { { 150, 150, 150 }, "gray59" }, { { 150, 150, 150 }, "grey59" }, { { 153, 153, 153 }, "gray60" }, { { 153, 153, 153 }, "grey60" }, { { 156, 156, 156 }, "gray61" }, { { 156, 156, 156 }, "grey61" }, { { 158, 158, 158 }, "gray62" }, { { 158, 158, 158 }, "grey62" }, { { 161, 161, 161 }, "gray63" }, { { 161, 161, 161 }, "grey63" }, { { 163, 163, 163 }, "gray64" }, { { 163, 163, 163 }, "grey64" }, { { 166, 166, 166 }, "gray65" }, { { 166, 166, 166 }, "grey65" }, { { 168, 168, 168 }, "gray66" }, { { 168, 168, 168 }, "grey66" }, { { 171, 171, 171 }, "gray67" }, { { 171, 171, 171 }, "grey67" }, { { 173, 173, 173 }, "gray68" }, { { 173, 173, 173 }, "grey68" }, { { 176, 176, 176 }, "gray69" }, { { 176, 176, 176 }, "grey69" }, { { 179, 179, 179 }, "gray70" }, { { 179, 179, 179 }, "grey70" }, { { 181, 181, 181 }, "gray71" }, { { 181, 181, 181 }, "grey71" }, { { 184, 184, 184 }, "gray72" }, { { 184, 184, 184 }, "grey72" }, { { 186, 186, 186 }, "gray73" }, { { 186, 186, 186 }, "grey73" }, { { 189, 189, 189 }, "gray74" }, { { 189, 189, 189 }, "grey74" }, { { 191, 191, 191 }, "gray75" }, { { 191, 191, 191 }, "grey75" }, { { 194, 194, 194 }, "gray76" }, { { 194, 194, 194 }, "grey76" }, { { 196, 196, 196 }, "gray77" }, { { 196, 196, 196 }, "grey77" }, { { 199, 199, 199 }, "gray78" }, { { 199, 199, 199 }, "grey78" }, { { 201, 201, 201 }, "gray79" }, { { 201, 201, 201 }, "grey79" }, { { 204, 204, 204 }, "gray80" }, { { 204, 204, 204 }, "grey80" }, { { 207, 207, 207 }, "gray81" }, { { 207, 207, 207 }, "grey81" }, { { 209, 209, 209 }, "gray82" }, { { 209, 209, 209 }, "grey82" }, { { 212, 212, 212 }, "gray83" }, { { 212, 212, 212 }, "grey83" }, { { 214, 214, 214 }, "gray84" }, { { 214, 214, 214 }, "grey84" }, { { 217, 217, 217 }, "gray85" }, { { 217, 217, 217 }, "grey85" }, { { 219, 219, 219 }, "gray86" }, { { 219, 219, 219 }, "grey86" }, { { 222, 222, 222 }, "gray87" }, { { 222, 222, 222 }, "grey87" }, { { 224, 224, 224 }, "gray88" }, { { 224, 224, 224 }, "grey88" }, { { 227, 227, 227 }, "gray89" }, { { 227, 227, 227 }, "grey89" }, { { 229, 229, 229 }, "gray90" }, { { 229, 229, 229 }, "grey90" }, { { 232, 232, 232 }, "gray91" }, { { 232, 232, 232 }, "grey91" }, { { 235, 235, 235 }, "gray92" }, { { 235, 235, 235 }, "grey92" }, { { 237, 237, 237 }, "gray93" }, { { 237, 237, 237 }, "grey93" }, { { 240, 240, 240 }, "gray94" }, { { 240, 240, 240 }, "grey94" }, { { 242, 242, 242 }, "gray95" }, { { 242, 242, 242 }, "grey95" }, { { 245, 245, 245 }, "gray96" }, { { 245, 245, 245 }, "grey96" }, { { 247, 247, 247 }, "gray97" }, { { 247, 247, 247 }, "grey97" }, { { 250, 250, 250 }, "gray98" }, { { 250, 250, 250 }, "grey98" }, { { 252, 252, 252 }, "gray99" }, { { 252, 252, 252 }, "grey99" }, { { 255, 255, 255 }, "gray100" }, { { 255, 255, 255 }, "grey100" }, { { 169, 169, 169 }, "DarkGrey" }, { { 169, 169, 169 }, "DarkGray" }, { { 0, 0, 139 }, "DarkBlue" }, { { 0, 139, 139 }, "DarkCyan" }, { { 139, 0, 139 }, "DarkMagenta" }, { { 139, 0, 0 }, "DarkRed" }, { { 144, 238, 144 }, "LightGreen" }, { { 220, 20, 60 }, "crimson" }, { { 75, 0, 130 }, "indigo" }, { { 128, 128, 0 }, "olive" }, { { 102, 51, 153 }, "RebeccaPurple" }, { { 192, 192, 192 }, "silver" }, { { 0, 128, 128 }, "teal" }, { { 0, 0, 0 }, NULL } }; /* Eliminate spaces from input name */ static gchar * mangle_name (const gchar *name) { gchar *mangled_name; const gchar *p0; gchar *p1; mangled_name = g_malloc (strlen (name) + 1); for (p0 = name, p1 = mangled_name; *p0; p0++) { gchar c = *p0; if (c == ' ') continue; *(p1++) = c; } *p1 = '\0'; return mangled_name; } const ChicleNamedColor * chicle_find_color_by_name (const gchar *name) { const ChicleNamedColor *named_color; gchar *mangled_name; mangled_name = mangle_name (name); for (named_color = named_colors; named_color->name; named_color++) { if (!g_ascii_strcasecmp (mangled_name, named_color->name)) break; } if (!named_color->name) named_color = NULL; g_free (mangled_name); return named_color; } chafa-1.18.2/tools/chafa/chicle-named-colors.h000066400000000000000000000022151517447374300210470ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_NAMED_COLORS_H__ #define __CHICLE_NAMED_COLORS_H__ #include G_BEGIN_DECLS typedef struct { guint8 color [3]; const gchar *name; } ChicleNamedColor; const ChicleNamedColor *chicle_find_color_by_name (const gchar *name); G_END_DECLS #endif /* __CHICLE_NAMED_COLORS_H__ */ chafa-1.18.2/tools/chafa/chicle-options.c000066400000000000000000002435371517447374300201700ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include /* strspn, strlen, strcmp, strncmp, memset */ #include /* setlocale */ #ifdef HAVE_SYS_IOCTL_H # include /* ioctl */ #endif #include /* open */ #include /* stat */ #include /* open */ #include /* STDOUT_FILENO */ #ifdef HAVE_SIGACTION # include /* sigaction */ #endif #include /* exit */ #ifdef HAVE_TERMIOS_H # include /* tcgetattr, tcsetattr */ #endif #include #include #include "chafa-term.h" #include "chicle-font-loader.h" #include "chicle-grid-layout.h" #include "chicle-media-pipeline.h" #include "chicle-options.h" #include "chicle-path-queue.h" #include "chicle-placement-counter.h" #include "chicle-util.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #endif ChicleOptions options; ChicleTermSize detected_term_size; gboolean using_detected_size = FALSE; ChiclePathQueue *global_path_queue; gint global_path_queue_n_stdin; gint global_n_path_streams; ChafaTerm *term; static guchar get_hex_byte (const gchar *str) { gint b = 0; if (*str >= '0' && *str <= '9') b = *str - '0'; else if (*str >= 'a' && *str <= 'f') b = *str - 'a' + 10; else if (*str >= 'A' && *str <= 'F') b = *str - 'A' + 10; else g_assert_not_reached (); b <<= 4; str++; if (*str >= '0' && *str <= '9') b |= *str - '0'; else if (*str >= 'a' && *str <= 'f') b |= *str - 'a' + 10; else if (*str >= 'A' && *str <= 'F') b |= *str - 'A' + 10; else g_assert_not_reached (); return b; } static gint count_dash_strings (GList *l) { gint n = 0; for ( ; l; l = g_list_next (l)) { if (!strcmp (l->data, "-")) n++; } return n; } static gboolean parse_color (const gchar *str, guint32 *col_out, GError **error) { gint len; gchar *label = NULL; gchar *p0; gboolean result = FALSE; str += strspn (str, " \t"); len = strspn (str, "#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); if (len < 1) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unrecognized color '%s'.", str); goto out; } p0 = label = g_ascii_strdown (str, len); /* Hex triplet, optionally prefixed with # or 0x */ if (*p0 == '#') p0++; else if (p0 [0] == '0' && (p0 [1] == 'x')) p0 += 2; len = strspn (p0, "0123456789abcdef"); if (len != (gint) strlen (p0) || len < 6) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unrecognized color '%s'.", str); goto out; } if (len > 6) p0 += (len - 6); *col_out = (get_hex_byte (p0) << 16) + (get_hex_byte (p0 + 2) << 8) + get_hex_byte (p0 + 4); result = TRUE; out: g_free (label); return result; } static GList * collect_variable_arguments (int *argc, char **argv [], gint first_arg) { GList *l = NULL; gint i; for (i = first_arg; i < *argc; i++) l = g_list_prepend (l, g_strdup ((*argv) [i])); return g_list_reverse (l); } static const gchar copyright_notice [] = "Copyright (C) 2018-2025 Hans Petter Jansson et al.\n" "Incl. libnsgif copyright (C) 2004 Richard Wilson, copyright (C) 2008 Sean Fox\n" "Incl. LodePNG copyright (C) 2005-2018 Lode Vandevenne\n" "Incl. QOI decoder copyright (C) 2021 Dominic Szablewski\n\n" "This is free software; see the source for copying conditions. There is NO\n" "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"; static void print_version (void) { gchar *builtin_features_str = chafa_describe_features (chafa_get_builtin_features ()); gchar *supported_features_str = chafa_describe_features (chafa_get_supported_features ()); gchar **loaders = chicle_get_loader_names (); gchar *loaders_joined = g_strjoinv (" ", loaders); g_print ("Chafa version %s\n\nLoaders: %s\nFeatures: %s\nApplying: %s\n\n%s\n", CHAFA_VERSION, loaders_joined, chafa_get_builtin_features () ? builtin_features_str : "none", chafa_get_supported_features () ? supported_features_str : "none", copyright_notice); g_free (builtin_features_str); g_free (supported_features_str); g_strfreev (loaders); g_free (loaders_joined); } static void print_brief_summary (void) { g_printerr ("%s: You must specify input files as arguments or pipe a file to stdin.\n" "Try '%s --help' for more information.\n", options.executable_name, options.executable_name); } static void print_summary (void) { const gchar *summary = " Chafa (Character Art Facsimile) terminal graphics and character art generator.\n" "\nGeneral options:\n" " --files=PATH Read list of files to process from PATH, or \"-\" for stdin.\n" " --files0=PATH Similar to --files, using NUL separator instead of newline.\n" " -h, --help Show help.\n" " --probe=ARG Probe terminal's capabilities and wait for response [auto,\n" " on, off]. A positive real number denotes the maximum time\n" " to wait for a response, in seconds. Defaults to " G_STRINGIFY (CHICLE_PROBE_DURATION_DEFAULT) ".\n" " --probe-mode=ARG How to probe the terminal [any, ctty, stdio].\n" " --version Show version.\n" " -v, --verbose Be verbose.\n" "\nOutput encoding:\n" " -f, --format=FORMAT Set output format; one of [iterm, kitty, sixels,\n" " symbols]. Iterm, kitty and sixels yield much higher\n" " quality but enjoy limited support. Symbols mode yields\n" " beautiful character art.\n" " -O, --optimize=NUM Compress the output by using control sequences\n" " intelligently [0-9]. 0 disables, 9 enables every\n" " available optimization. Defaults to 5, except for when\n" " used with \"-c none\", where it defaults to 0.\n" " --relative=BOOL Use relative cursor positioning [on, off]. When on,\n" " control sequences will be used to position images relative\n" " to the cursor. When off, newlines will be used to separate\n" " rows instead for e.g. 'less -R' interop. Defaults to off.\n" " --passthrough=MODE Graphics protocol passthrough [auto, none, screen,\n" " tmux]. Used to show pixel graphics through multiplexers.\n" " --polite=BOOL Polite mode [on, off]. Inhibits escape sequences that may\n" " confuse other programs. Defaults to off.\n" "\nSize and layout:\n" " --align=ALIGN Horizontal and vertical alignment (e.g. \"top,left\").\n" " --clear Clear screen before processing each file.\n" " --exact-size=MODE Try to match the input's size exactly [auto, on, off].\n" " --fit-width Fit images to view's width, possibly exceeding its height.\n" " --font-ratio=W/H Target font's width/height ratio. Can be specified as\n" " a real number or a fraction. Defaults to 1/2.\n" " --grid=CxR Lay out images in a grid of CxR columns/rows per screenful.\n" " C or R may be omitted, e.g. \"--grid 4\". Can be \"auto\".\n" " -g Alias for \"--grid auto\".\n" " --label=BOOL Labeling [on, off]. Filenames below images. Default off.\n" " -l Alias for \"--label on\".\n" " --link=BOOL Link labels [auto, on, off]. Turns labels into clickable\n" " hyperlinks. Use with \"--label on\". Defaults to auto.\n" " --margin-bottom=NUM When terminal size is detected, reserve at least NUM\n" " rows at the bottom as a safety margin. Can be used to\n" " prevent images from scrolling out. Defaults to 1.\n" " --margin-right=NUM When terminal size is detected, reserve at least NUM\n" " columns safety margin on right-hand side. Defaults to 0.\n" " --scale=NUM Scale image, respecting view's dimensions. 1.0 approximates\n" " image's pixel dimensions. Specify \"max\" to fit view.\n" " Defaults to 1.0 for pixel graphics and 4.0 for symbols.\n" " -s, --size=WxH Set maximum image dimensions in columns and rows. By\n" " default this will be equal to the view size.\n" " --stretch Stretch image to fit output dimensions; ignore aspect.\n" " Implies --scale max.\n" " --view-size=WxH Set the view size in columns and rows. By default this\n" " will be the size of your terminal, or 80x25 if size\n" " detection fails. If one dimension is omitted, it will\n" " be set to a reasonable approximation of infinity.\n" "\nAnimation and timing:\n" " --animate=BOOL Whether to allow animation [on, off]. Defaults to on.\n" " When off, will show a still frame from each animation.\n" " -d, --duration=SECONDS How long to show each file. If showing a single file,\n" " defaults to zero for a still image and infinite for an\n" " animation. For multiple files, defaults to zero. Animations\n" " will always be played through at least once.\n" " --speed=SPEED Animation speed. Either a unitless multiplier, or a real\n" " number followed by \"fps\" to apply a specific framerate.\n" " --watch Watch a single input file, redisplaying it whenever its\n" " contents change. Will run until manually interrupted\n" " or, if --duration is set, until it expires.\n" "\nColors and processing:\n" " --bg=COLOR Background color of display (color name or hex).\n" " -c, --colors=MODE Set output color mode; one of [none, 2, 8, 16/8, 16, 240,\n" " 256, full]. Defaults to best guess.\n" " --color-extractor=EXTR Method for extracting color from an area\n" " [average, median]. Average is the default.\n" " --color-space=CS Color space used for quantization; one of [rgb, din99d].\n" " Defaults to rgb, which is faster but less accurate.\n" " --dither=DITHER Set output dither mode; one of [none, ordered,\n" " diffusion, noise]. No effect with 24-bit color. Defaults to\n" " noise for sixels, none otherwise.\n" " --dither-grain=WxH Set dimensions of dither grains in 1/8ths of a\n" " character cell [1, 2, 4, 8]. Defaults to 4x4.\n" " --dither-intensity=NUM Multiplier for dither intensity [0.0 - inf].\n" " Defaults to 1.0.\n" " --fg=COLOR Foreground color of display (color name or hex).\n" " --invert Swaps --fg and --bg. Useful with light terminal background.\n" " -p, --preprocess=BOOL Image preprocessing [on, off]. Defaults to on with 16\n" " colors or lower, off otherwise.\n" " -t, --threshold=NUM Lower threshold for full transparency [0.0 - 1.0].\n" "\nResource allocation:\n" " --threads=NUM Maximum number of CPU threads to use. If left unspecified\n" " or negative, this will equal available CPU cores.\n" " -w, --work=NUM How hard to work in terms of CPU and memory [1-9]. 1 is the\n" " cheapest, 9 is the most accurate. Defaults to 5.\n" "\nExtra options for symbol encoding:\n" " --fg-only Leave the background color untouched. This produces\n" " character-cell output using foreground colors only.\n" " --fill=SYMS Specify character symbols to use for fill/gradients.\n" " Defaults to none. See below for full usage.\n" " --glyph-file=FILE Load glyph information from FILE, which can be any\n" " font file supported by FreeType (TTF, PCF, etc).\n" " --symbols=SYMS Specify character symbols to employ in final output.\n" " See below for full usage and a list of symbol classes.\n" "\nAccepted classes for --symbols and --fill:\n" " all ascii braille extra imported narrow solid ugly\n" " alnum bad diagonal geometric inverted none space vhalf\n" " alpha block digit half latin quad stipple wedge\n" " ambiguous border dot hhalf legacy sextant technical wide\n" "\n These can be combined with + and -, e.g. block+border-diagonal or all-wide.\n" "\nExamples:\n" " $ chafa --scale max in.jpg # As big as will fit\n" " $ chafa --clear --align mid,mid -d 5 *.gif # Centered slideshow\n" " $ chafa -f symbols --symbols ascii -c none in.png # Old-school ASCII art\n" " $ find /usr -type f -print0 | chafa --files0 - -g -l # System images (Unix)\n\n" "If your OS comes with manual pages, you can type 'man chafa' for more.\n"; g_print ("Usage:\n %s [OPTION...] [FILE...]\n\n%s", options.executable_name, summary); } static gboolean parse_boolean_token (const gchar *token, gboolean *value_out) { gboolean success = FALSE; if (!g_ascii_strcasecmp (token, "on") || !g_ascii_strcasecmp (token, "yes") || !g_ascii_strcasecmp (token, "true")) { *value_out = TRUE; } else if (!g_ascii_strcasecmp (token, "off") || !g_ascii_strcasecmp (token, "no") || !g_ascii_strcasecmp (token, "false")) { *value_out = FALSE; } else { goto out; } success = TRUE; out: return success; } static gboolean parse_tristate_token (const gchar *token, ChicleTristate *value_out) { gboolean success = FALSE; gboolean value_bool = FALSE; if (!g_ascii_strcasecmp (token, "auto") || !g_ascii_strcasecmp (token, "default")) { *value_out = CHICLE_TRISTATE_AUTO; } else { success = parse_boolean_token (token, &value_bool); if (!success) goto out; *value_out = value_bool ? CHICLE_TRISTATE_TRUE : CHICLE_TRISTATE_FALSE; } success = TRUE; out: return success; } static gboolean parse_probe_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = FALSE; result = parse_tristate_token (value, &options.probe); if (!result) { gdouble d = -1.0; gchar *endptr; d = g_strtod (value, &endptr); if (endptr == value || d <= 0.0) goto out; options.probe = CHICLE_TRISTATE_TRUE; options.probe_duration = d; result = TRUE; } out: if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Probe duration must be a positive real number or one of [on, off, auto]."); return result; } static gboolean parse_probe_mode_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; if (!g_ascii_strcasecmp (value, "any")) options.probe_mode = CHICLE_PROBE_MODE_ANY; else if (!g_ascii_strcasecmp (value, "ctty")) options.probe_mode = CHICLE_PROBE_MODE_CTTY; else if (!g_ascii_strcasecmp (value, "stdio")) options.probe_mode = CHICLE_PROBE_MODE_STDIO; else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Probe mode must be one of [any, ctty, stdio]."); result = FALSE; } return result; } static gboolean parse_colors_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; if (!g_ascii_strcasecmp (value, "none")) options.mode = CHAFA_CANVAS_MODE_FGBG; else if (!g_ascii_strcasecmp (value, "2")) options.mode = CHAFA_CANVAS_MODE_FGBG_BGFG; else if (!g_ascii_strcasecmp (value, "8")) options.mode = CHAFA_CANVAS_MODE_INDEXED_8; else if (!g_ascii_strcasecmp (value, "16-8") || !g_ascii_strcasecmp (value, "16/8")) options.mode = CHAFA_CANVAS_MODE_INDEXED_16_8; else if (!g_ascii_strcasecmp (value, "16")) options.mode = CHAFA_CANVAS_MODE_INDEXED_16; else if (!g_ascii_strcasecmp (value, "240")) options.mode = CHAFA_CANVAS_MODE_INDEXED_240; else if (!g_ascii_strcasecmp (value, "256")) options.mode = CHAFA_CANVAS_MODE_INDEXED_256; else if (!g_ascii_strcasecmp (value, "full") || !g_ascii_strcasecmp (value, "rgb") || !g_ascii_strcasecmp (value, "tc") || !g_ascii_strcasecmp (value, "direct") || !g_ascii_strcasecmp (value, "directcolor") || !g_ascii_strcasecmp (value, "truecolor")) options.mode = CHAFA_CANVAS_MODE_TRUECOLOR; else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Colors must be one of [none, 2, 8, 16/8, 16, 240, 256, full]."); result = FALSE; } return result; } static gboolean parse_color_extractor_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; if (!g_ascii_strcasecmp (value, "average")) options.color_extractor = CHAFA_COLOR_EXTRACTOR_AVERAGE; else if (!g_ascii_strcasecmp (value, "median")) options.color_extractor = CHAFA_COLOR_EXTRACTOR_MEDIAN; else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Color extractor must be one of [average, median]."); result = FALSE; } return result; } static gboolean parse_color_space_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; if (!g_ascii_strcasecmp (value, "rgb")) options.color_space = CHAFA_COLOR_SPACE_RGB; else if (!g_ascii_strcasecmp (value, "din99d")) options.color_space = CHAFA_COLOR_SPACE_DIN99D; else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Color space must be one of [rgb, din99d]."); result = FALSE; } return result; } static gboolean parse_dither_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; if (!g_ascii_strcasecmp (value, "none")) options.dither_mode = CHAFA_DITHER_MODE_NONE; else if (!g_ascii_strcasecmp (value, "ordered") || !g_ascii_strcasecmp (value, "bayer")) options.dither_mode = CHAFA_DITHER_MODE_ORDERED; else if (!g_ascii_strcasecmp (value, "diffusion") || !g_ascii_strcasecmp (value, "fs")) options.dither_mode = CHAFA_DITHER_MODE_DIFFUSION; else if (!g_ascii_strcasecmp (value, "noise")) options.dither_mode = CHAFA_DITHER_MODE_NOISE; else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Dither must be one of [none, ordered, diffusion, noise]."); result = FALSE; } options.dither_mode_set = TRUE; return result; } static const gchar * utf8_skip_spaces (const gchar *str) { gunichar c; for (c = g_utf8_get_char (str); c != 0 && g_unichar_isspace (c); c = g_utf8_get_char (str)) { str = g_utf8_next_char (str); } return str; } static gboolean parse_fraction_or_real (const gchar *str, gdouble *real_out) { gboolean success = FALSE; gdouble ratio = G_MAXDOUBLE; gint64 width = -1, height = -1; const gchar *sep; const gchar *p0 = NULL; const gchar *end = NULL; p0 = utf8_skip_spaces (str); sep = g_utf8_strchr (p0, -1, '/'); if (!sep) sep = g_utf8_strchr (p0, -1, ':'); if (sep) { width = g_ascii_strtoll (p0, (gchar **)(intptr_t) &end, 10); if (!end || end == p0) goto out; end = utf8_skip_spaces (end); if (g_utf8_get_char (end) != '/' && g_utf8_get_char (end) != ':') goto out; sep = g_utf8_next_char (sep); p0 = utf8_skip_spaces (sep); height = g_ascii_strtoll (p0, (gchar **)(intptr_t) &end, 10); if (end == p0) goto out; end = utf8_skip_spaces (end); if (!end || *end) goto out; if ((gdouble) height != 0.0) ratio = width / (gdouble) height; } else { ratio = g_strtod (p0, (gchar **)(intptr_t) &end); if (!end || end == p0) goto out; end = utf8_skip_spaces (end); if (!end || *end) goto out; } if (ratio == G_MAXDOUBLE) goto out; *real_out = ratio; success = TRUE; out: return success; } static gboolean parse_align_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean success = FALSE; gchar **tokens = NULL; ChafaAlign halign = CHAFA_ALIGN_MAX; ChafaAlign valign = CHAFA_ALIGN_MAX; gint i; tokens = g_strsplit (value, ",", -1); for (i = 0; tokens [i]; i++) { gchar *t = tokens [i]; if (i >= 2) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Too many alignment specifiers in \"%s\". Must be at most two.", value); goto out; } if (!strcasecmp (t, "left")) halign = CHAFA_ALIGN_START; else if (!strcasecmp (t, "right")) halign = CHAFA_ALIGN_END; else if (!strcasecmp (t, "hcenter") || !strcasecmp (t, "hmid")) halign = CHAFA_ALIGN_CENTER; else if (!strcasecmp (t, "top") || !strcasecmp (t, "up")) valign = CHAFA_ALIGN_START; else if (!strcasecmp (t, "bottom") || !strcasecmp (t, "down")) valign = CHAFA_ALIGN_END; else if (!strcasecmp (t, "vcenter") || !strcasecmp (t, "vmid")) valign = CHAFA_ALIGN_CENTER; else if (!strcasecmp (t, "center") || !strcasecmp (t, "mid")) ; /* Skip */ else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unknown alignment specifier \"%s\".", t); goto out; } } /* Process "center" in a second pass to allow both e.g. "center,left" * and "left,center" */ for (i = 0; tokens [i]; i++) { gchar *t = tokens [i]; if (!strcasecmp (t, "center") || !strcasecmp (t, "mid")) { /* Allow "center,center" to center in both dimensions */ if (halign == CHAFA_ALIGN_MAX) halign = CHAFA_ALIGN_CENTER; else valign = CHAFA_ALIGN_CENTER; } } if (halign != CHAFA_ALIGN_MAX) options.horiz_align = halign; if (valign != CHAFA_ALIGN_MAX) options.vert_align = valign; success = TRUE; out: g_strfreev (tokens); return success; } static gboolean parse_font_ratio_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gdouble ratio = -1.0; gboolean success = FALSE; if (!parse_fraction_or_real (value, &ratio) || ratio <= 0.0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Font ratio must be specified as a positive real number or fraction."); goto out; } options.font_ratio = ratio; success = TRUE; out: return success; } static gboolean parse_scale_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gdouble scale = -1.0; gboolean success = FALSE; if (!strcasecmp (value, "max") || !strcasecmp (value, "fill")) { scale = CHICLE_SCALE_MAX; } else if (!parse_fraction_or_real (value, &scale) || scale <= 0.0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Scale must be specified as a positive real number or fraction."); goto out; } options.scale = scale; success = TRUE; out: return success; } static gboolean parse_threshold_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gdouble threshold = -1.0; gboolean success = FALSE; if (!parse_fraction_or_real (value, &threshold) || threshold < 0.0 || threshold > 1.0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Opacity threshold must be a real number or fraction in the range [0.0-1.0]."); goto out; } options.transparency_threshold = threshold; success = TRUE; out: return success; } static gboolean parse_dither_intensity_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gdouble dither_intensity = -1.0; gboolean success = FALSE; if (!parse_fraction_or_real (value, &dither_intensity) || dither_intensity < 0.0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Dither intensity must be a positive real number or fraction."); goto out; } options.dither_intensity = dither_intensity; success = TRUE; out: return success; } static gboolean parse_duration_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gdouble duration = -1.0; gboolean success = FALSE; if (!strcasecmp (value, "max") || !strcasecmp (value, "inf") || !strcasecmp (value, "infinite")) { duration = G_MAXDOUBLE; } else if (!parse_fraction_or_real (value, &duration) || duration < 0.0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Duration must be a positive real number or fraction, \"inf\" or \"infinite\"."); goto out; } options.file_duration_s = duration; success = TRUE; out: return success; } static gboolean parse_symbols_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { options.symbols_specified = TRUE; /* FIXME: Implement a more convenient/consistent way to turn off Unicode in * labels etc. */ if (value && !strcasecmp (value, "ascii")) options.use_unicode = FALSE; return chafa_symbol_map_apply_selectors (options.symbol_map, value, error); } static gboolean parse_fill_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { return chafa_symbol_map_apply_selectors (options.fill_symbol_map, value, error); } static gboolean parse_files_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, G_GNUC_UNUSED GError **error) { global_n_path_streams++; if (!strcmp (value, "-")) global_path_queue_n_stdin++; chicle_path_queue_push_stream (global_path_queue, value, "\n", 1); return TRUE; } static gboolean parse_files0_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, G_GNUC_UNUSED GError **error) { global_n_path_streams++; if (!strcmp (value, "-")) global_path_queue_n_stdin++; chicle_path_queue_push_stream (global_path_queue, value, "\0", 1); return TRUE; } static gboolean parse_format_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; ChafaPixelMode pixel_mode = CHAFA_PIXEL_MODE_SYMBOLS; if (!strcasecmp (value, "symbol") || !strcasecmp (value, "symbols") || !strcasecmp (value, "ansi")) { pixel_mode = CHAFA_PIXEL_MODE_SYMBOLS; } else if (!strcasecmp (value, "sixel") || !strcasecmp (value, "sixels")) { pixel_mode = CHAFA_PIXEL_MODE_SIXELS; } else if (!strcasecmp (value, "kitty")) { pixel_mode = CHAFA_PIXEL_MODE_KITTY; } else if (!strcasecmp (value, "iterm") || !strcasecmp (value, "iterm2")) { pixel_mode = CHAFA_PIXEL_MODE_ITERM2; } else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Output format given as '%s'. Must be one of [iterm, kitty, sixels, symbols].", value); result = FALSE; } if (result) { options.pixel_mode = pixel_mode; options.pixel_mode_set = TRUE; } return result; } static void parse_2d_size (const gchar *value, gint *width_out, gint *height_out) { gint n; gint o = 0; *width_out = *height_out = -1; n = sscanf (value, "%d%n", width_out, &o); if (value [o] == 'x' && value [o + 1] != '\0') { gint o2; n = sscanf (value + o + 1, "%d%n", height_out, &o2); if (n == 1 && value [o + o2 + 1] != '\0') { *width_out = *height_out = -1; } } } static gboolean parse_view_size_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; gint width, height; parse_2d_size (value, &width, &height); if (width < 0 && height < 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "View size must be specified as [width]x[height], [width]x or x[height], e.g 80x25, 80x or x25."); result = FALSE; } else if (width == 0 || height == 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "View size must be at least 1x1."); result = FALSE; } options.view_width = width; options.view_height = height; return result; } static gboolean parse_size_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; gint width, height; parse_2d_size (value, &width, &height); if (width < 0 && height < 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Size must be specified as [width]x[height], [width]x or x[height], e.g 80x25, 80x or x25."); result = FALSE; } else if (width == 0 || height == 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Size must be at least 1x1."); result = FALSE; } options.width = width; options.height = height; return result; } static gboolean parse_grid_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; gboolean b = FALSE; gint width, height; if (parse_boolean_token (value, &b)) { width = height = (b ? CHICLE_GRID_AUTO : -1); options.grid_on = b; } else if (!g_ascii_strcasecmp (value, "auto")) { width = height = CHICLE_GRID_AUTO; options.grid_on = TRUE; } else { parse_2d_size (value, &width, &height); if (width < 0 && height < 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Grid size must be specified as [width]x[height], [width]x or x[height], e.g 4x4, 4x or x4."); result = FALSE; } else if (width == 0 || height == 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Grid size must be at least 1x1."); result = FALSE; } else if (width < 0) { width = -1; options.grid_on = TRUE; } else if (height < 0) { height = -1; options.grid_on = TRUE; } } options.grid_width = width; options.grid_height = height; return result; } static gboolean parse_exact_size_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_tristate_token (value, &options.use_exact_size); if (!result) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Exact size selector must be one of [on, off, auto]."); } return result; } static gboolean parse_dither_grain_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; gint width = -1, height = -1; gint n; gint o = -1; n = sscanf (value, "%d%n", &width, &o); if (o > 0 && value [o] == 'x' && value [o + 1] != '\0') { gint o2; n = sscanf (value + o + 1, "%d%n", &height, &o2); if (n == 1 && value [o + o2 + 1] != '\0') { width = height = -1; goto out; } } out: if (height < 0) height = width; if (width < 0) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Grain size must be specified as [width]x[height] or [dim], e.g. 8x4 or 4."); result = FALSE; } else if ((width != 1 && width != 2 && width != 4 && width != 8) || (height != 1 && height != 2 && height != 4 && height != 8)) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Grain dimensions must be exactly 1, 2, 4 or 8."); result = FALSE; } options.dither_grain_width = width; options.dither_grain_height = height; return result; } static gboolean parse_passthrough_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = TRUE; options.passthrough_set = TRUE; if (!g_ascii_strcasecmp (value, "none")) options.passthrough = CHAFA_PASSTHROUGH_NONE; else if (!g_ascii_strcasecmp (value, "screen")) options.passthrough = CHAFA_PASSTHROUGH_SCREEN; else if (!g_ascii_strcasecmp (value, "tmux")) options.passthrough = CHAFA_PASSTHROUGH_TMUX; else if (!g_ascii_strcasecmp (value, "auto")) { options.passthrough = CHAFA_PASSTHROUGH_NONE; options.passthrough_set = FALSE; } else { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Passthrough must be one of [auto, none, screen, tmux]."); result = FALSE; } return result; } static gboolean parse_glyph_file_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = FALSE; ChicleFileMapping *file_mapping; ChicleFontLoader *font_loader; gunichar c; gpointer c_bitmap; gint width, height; file_mapping = chicle_file_mapping_new (value); if (!file_mapping) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unable to open glyph file '%s'.", value); goto out; } font_loader = chicle_font_loader_new_from_mapping (file_mapping); file_mapping = NULL; /* Font loader owns it now */ if (!font_loader) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unable to load glyph file '%s'.", value); goto out; } while (chicle_font_loader_get_next_glyph (font_loader, &c, &c_bitmap, &width, &height)) { chafa_symbol_map_add_glyph (options.symbol_map, c, CHAFA_PIXEL_RGBA8_PREMULTIPLIED, c_bitmap, width, height, width * 4); chafa_symbol_map_add_glyph (options.fill_symbol_map, c, CHAFA_PIXEL_RGBA8_PREMULTIPLIED, c_bitmap, width, height, width * 4); g_free (c_bitmap); } chicle_font_loader_destroy (font_loader); result = TRUE; out: if (file_mapping) chicle_file_mapping_destroy (file_mapping); return result; } static void dump_glyph (gunichar c, const guint8 *pix, gint width, gint height, gint rowstride) { gint x, y; const guint8 *p; gchar buf [16]; gint len; len = g_unichar_to_utf8 (c, buf); g_assert (len >= 1 && len < 16); buf [len] = '\0'; fprintf (stdout, " {\n" " /* [%s] */\n" " CHAFA_SYMBOL_TAG_,\n" " 0x%x,\n" " CHAFA_SYMBOL_OUTLINE_%s (", buf, c, (width == 8 && height == 8) ? "8X8" : (width == 16 && height == 8) ? "16X8" : "STRANGE_SIZE"); for (y = 0; y < height; y++) { p = pix + y * rowstride; fputs ("\n \"", stdout); for (x = 0; x < width; x++) { fputc (*p < 0x80 ? ' ' : 'X' , stdout); p += 4; } fputs ("\"", stdout); } fputs (")\n },\n", stdout); } /* Undocumented functionality; dumps a font file so the glyphs can be tweaked and turned * into builtins. */ static gboolean parse_dump_glyph_file_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = FALSE; ChicleFileMapping *file_mapping; ChicleFontLoader *font_loader; ChafaSymbolMap *temp_map = NULL; gunichar c; gpointer c_bitmap; gint width, height, rowstride; options.skip_processing = TRUE; file_mapping = chicle_file_mapping_new (value); if (!file_mapping) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unable to open glyph file '%s'.", value); goto out; } font_loader = chicle_font_loader_new_from_mapping (file_mapping); file_mapping = NULL; /* Font loader owns it now */ if (!font_loader) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Unable to load glyph file '%s'.", value); goto out; } temp_map = chafa_symbol_map_new (); while (chicle_font_loader_get_next_glyph (font_loader, &c, &c_bitmap, &width, &height)) { gpointer pix; /* By adding and then querying the glyph, we get the benefit of Chafa's * internal scaling and postprocessing. */ chafa_symbol_map_add_glyph (temp_map, c, CHAFA_PIXEL_RGBA8_PREMULTIPLIED, c_bitmap, width, height, width * 4); g_free (c_bitmap); chafa_symbol_map_get_glyph (temp_map, c, CHAFA_PIXEL_RGBA8_PREMULTIPLIED, &pix, &width, &height, &rowstride); dump_glyph (c, pix, width, height, rowstride); g_free (pix); } chicle_font_loader_destroy (font_loader); result = TRUE; out: if (file_mapping) chicle_file_mapping_destroy (file_mapping); if (temp_map) chafa_symbol_map_unref (temp_map); return result; } static gboolean parse_animate_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_boolean_token (value, &options.animate); if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Animate mode must be one of [on, off]."); return result; } static gboolean parse_center_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean center = FALSE; gboolean result; result = parse_boolean_token (value, ¢er); if (result) options.horiz_align = center ? CHAFA_ALIGN_CENTER : CHAFA_ALIGN_START; else g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Centering mode must be one of [on, off]."); return result; } static gboolean parse_label_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_boolean_token (value, &options.label); if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Label mode must be one of [on, off]."); return result; } static gboolean parse_link_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_tristate_token (value, &options.link_labels); if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Link mode must be one of [auto, on, off]."); return result; } static gboolean parse_preprocess_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_boolean_token (value, &options.preprocess); if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Preprocessing must be one of [on, off]."); return result; } static gboolean parse_polite_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_boolean_token (value, &options.polite); if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Polite mode must be one of [on, off]."); return result; } static gboolean parse_relative_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result; result = parse_boolean_token (value, &options.relative); if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Relative positioning must be one of [on, off]."); options.relative_set = TRUE; return result; } static gboolean parse_anim_speed_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { gboolean result = FALSE; gdouble d; if (!g_ascii_strcasecmp (value, "max") || !g_ascii_strcasecmp (value, "maximum")) { options.anim_fps = G_MAXDOUBLE; result = TRUE; } else { gchar *endptr; d = g_strtod (value, &endptr); if (endptr == value || d <= 0.0) goto out; while (g_ascii_isspace (*endptr)) endptr++; if (!g_ascii_strcasecmp (endptr, "fps")) { options.anim_fps = d; result = TRUE; } else if (*endptr == '\0') { options.anim_speed_multiplier = d; result = TRUE; } /* If there's unknown junk at the end, fail. */ } out: if (!result) g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Animation speed must be either \"max\", a real multiplier, or a real framerate followed by \"fps\". It must be greater than zero."); return result; } static gboolean parse_color_str (const gchar *value, guint32 *col_out, const gchar *error_message, GError **error) { const ChicleNamedColor *named_color; guint32 col = 0x000000; gboolean result = TRUE; named_color = chicle_find_color_by_name (value); if (named_color) { col = (named_color->color [0] << 16) | (named_color->color [1] << 8) | (named_color->color [2]); } else if (!parse_color (value, &col, NULL)) { g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, error_message, value); result = FALSE; } if (result) *col_out = col; return result; } static gboolean parse_fg_color_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { options.fg_color_set = parse_color_str (value, &options.fg_color, "Unrecognized foreground color '%s'.", error); return options.fg_color_set; } static gboolean parse_bg_color_arg (G_GNUC_UNUSED const gchar *option_name, const gchar *value, G_GNUC_UNUSED gpointer data, GError **error) { options.bg_color_set = parse_color_str (value, &options.bg_color, "Unrecognized background color '%s'.", error); return options.bg_color_set; } /* ---------------------------------- * * Option fuzzing with --fuzz-options * * ---------------------------------- */ #define FUZZ_SEED_LEN 150 static gboolean fuzz_seed_get_bool (gconstpointer seed, gint seed_len, gint *ofs) { const guchar *seed_u8 = seed; return seed_u8 [(*ofs)++ % seed_len] < 128 ? TRUE : FALSE; } static ChicleTristate fuzz_seed_get_tristate (gconstpointer seed, gint seed_len, gint *ofs) { const guchar *seed_u8 = seed; guint v = seed_u8 [(*ofs)++ % seed_len]; return (v < 256 / 3) ? CHICLE_TRISTATE_FALSE : (v < (256 * 2) / 3) ? CHICLE_TRISTATE_TRUE : CHICLE_TRISTATE_AUTO; } static guint32 fuzz_seed_get_u32 (gconstpointer seed, gint seed_len, gint *ofs) { const guchar *seed_u8 = seed; guint32 u32 = 0; gint i; for (i = 0; i < 4; i++) { u32 |= seed_u8 [(*ofs)++ % seed_len]; u32 <<= 8; } return u32; } static guint32 fuzz_seed_get_uint (gconstpointer seed, gint seed_len, gint *ofs, guint32 min, guint32 max) { guint32 u32; u32 = fuzz_seed_get_u32 (seed, seed_len, ofs); return min + (u32 % (max - min)); } static gdouble fuzz_seed_get_double (gconstpointer seed, gint seed_len, gint *ofs, gdouble min, gdouble max) { guint32 u32; u32 = fuzz_seed_get_u32 (seed, seed_len, ofs); return min + (u32 % 65536) * ((max - min) / 65535.0); } static void fuzz_options_with_seed (ChicleOptions *opt, gconstpointer seed, gint seed_len) { gint ofs = 0; if (seed_len < 1) return; /* Fuzz as many options as possible, but avoid those needed to control * the fuzzing process -- e.g. n_threads, duration, animation speed, watch. */ opt->mode = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, CHAFA_CANVAS_MODE_MAX); opt->color_extractor = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, CHAFA_COLOR_EXTRACTOR_MAX); opt->color_space = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, CHAFA_COLOR_SPACE_MAX); opt->dither_mode = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, CHAFA_DITHER_MODE_MAX); opt->dither_mode_set = TRUE; opt->pixel_mode = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, CHAFA_PIXEL_MODE_MAX); opt->pixel_mode_set = TRUE; opt->dither_grain_width = 1 << (fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 4)); opt->dither_grain_height = 1 << (fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 4)); opt->dither_intensity = fuzz_seed_get_double (seed, seed_len, &ofs, 0.0, 10.0); opt->clear = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->verbose = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->invert = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->preprocess = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->polite = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->stretch = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->zoom = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->fg_only = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->animate = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->horiz_align = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 3); opt->vert_align = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 3); opt->relative = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->relative_set = TRUE; opt->fit_to_width = fuzz_seed_get_bool (seed, seed_len, &ofs); opt->view_width = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 32); opt->view_height = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 32); opt->width = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 32); opt->height = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 32); opt->cell_width = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 32); opt->cell_height = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 32); opt->margin_bottom = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 16); opt->margin_right = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 16); opt->scale = fuzz_seed_get_double (seed, seed_len, &ofs, 0.0, 10000.0); opt->work_factor = fuzz_seed_get_uint (seed, seed_len, &ofs, 1, 10); opt->optimization_level = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, 10); opt->passthrough = fuzz_seed_get_uint (seed, seed_len, &ofs, 0, CHAFA_PASSTHROUGH_MAX); opt->passthrough_set = TRUE; opt->transparency_threshold = fuzz_seed_get_double (seed, seed_len, &ofs, 0.0, 1.0); opt->transparency_threshold_set = TRUE; opt->use_exact_size = fuzz_seed_get_tristate (seed, seed_len, &ofs); } static void fuzz_options_with_file (ChicleOptions *opt, const gchar *filename) { FILE *fhd; guchar seed [FUZZ_SEED_LEN]; gint seed_len; fhd = fopen (filename, "rb"); if (!fhd) return; /* Read seed from the file's tail to avoid correlation with image * format headers etc. */ fseek (fhd, -FUZZ_SEED_LEN, SEEK_END); seed_len = fread (seed, sizeof (guchar), FUZZ_SEED_LEN, fhd); fclose (fhd); fuzz_options_with_seed (opt, seed, seed_len); } static gint get_tmux_version (gchar **envp) { const gchar *tmux_ver_str; const gchar *sep; tmux_ver_str = g_environ_getenv (envp, "TERM_PROGRAM_VERSION"); if (!tmux_ver_str) return 0; sep = strchr (tmux_ver_str, '.'); return g_ascii_strtoull (tmux_ver_str, NULL, 10) * 1000 + (sep ? g_ascii_strtoull (sep + 1, NULL, 10) : 0); } static void dump_settings (ChafaTermInfo *term_info, ChafaCanvasMode canvas_mode, ChafaPixelMode pixel_mode, ChafaPassthrough passthrough, gboolean polite) { const gchar *canvas_mode_desc [] = { "truecolor", "indexed-256", "indexed-240", "indexed-16", "fgbg-bgfg", "fgbg", "indexed-8", "indexed-16-8", NULL }; const gchar *pixel_mode_desc [] = { "symbols", "sixels", "kitty", "iterm2" }; const gchar *passthrough_desc [] = { "none", "screen", "tmux" }; g_print ("CHAFA_TERM='%s'\n" "CHAFA_CANVAS_MODE='%s'\n" "CHAFA_PIXEL_MODE='%s'\n" "CHAFA_PASSTHROUGH='%s'\n" "CHAFA_POLITE='%s'\n", chafa_term_info_get_name (term_info), canvas_mode_desc [canvas_mode], pixel_mode_desc [pixel_mode], passthrough_desc [passthrough], polite ? "true" : "false"); } static void detect_terminal (gchar **envp, ChafaTermInfo **term_info_out, ChafaCanvasMode *mode_out, ChafaPixelMode *pixel_mode_out, ChafaPassthrough *passthrough_out, ChafaSymbolMap **symbol_map_out, ChafaSymbolMap **fill_symbol_map_out, gboolean *polite_out) { ChafaCanvasMode mode; ChafaPixelMode pixel_mode; ChafaPassthrough passthrough; ChafaTermInfo *term_info; ChafaTermInfo *fallback_info; term_info = chafa_term_db_detect (chafa_term_db_get_default (), envp); /* Let's see what this baby can do! */ mode = chafa_term_info_get_best_canvas_mode (term_info); pixel_mode = chafa_term_info_get_best_pixel_mode (term_info); passthrough = chafa_term_info_get_is_pixel_passthrough_needed (term_info, pixel_mode) ? chafa_term_info_get_passthrough_type (term_info) : CHAFA_PASSTHROUGH_NONE; *symbol_map_out = chafa_symbol_map_new (); chafa_symbol_map_add_by_tags (*symbol_map_out, chafa_term_info_get_safe_symbol_tags (term_info)); *fill_symbol_map_out = chafa_symbol_map_new (); /* Make sure we have fallback sequences in case the user forces * a mode that's technically unsupported by the terminal. */ fallback_info = chafa_term_db_get_fallback_info (chafa_term_db_get_default ()); chafa_term_info_supplement (term_info, fallback_info); chafa_term_info_unref (fallback_info); *term_info_out = term_info; *mode_out = mode; *pixel_mode_out = pixel_mode; *passthrough_out = passthrough; /* The 'lf' file browser will choke if there are extra sequences in front * of a sixel image. Let's be polite to it. */ *polite_out = g_environ_getenv (envp, "LF_LEVEL") ? TRUE : FALSE; } static gchar *tmux_allow_passthrough_original; static gboolean tmux_allow_passthrough_is_changed; gboolean chicle_apply_passthrough_workarounds_tmux (void) { gboolean result = FALSE; gchar *standard_output = NULL; gchar *standard_error = NULL; gchar **strings; gchar *mode = NULL; gint wait_status = -1; /* allow-passthrough can be either unset, "on" or "all". Both "on" and "all" * are fine, so don't mess with it if we don't have to. * * Also note that we may be in a remote session inside tmux. */ if (!g_spawn_command_line_sync ("tmux show allow-passthrough", &standard_output, &standard_error, &wait_status, NULL)) goto out; strings = g_strsplit_set (standard_output, " ", -1); if (strings [0] && strings [1]) { mode = g_ascii_strdown (strings [1], -1); g_strstrip (mode); } g_strfreev (strings); g_free (standard_output); standard_output = NULL; g_free (standard_error); standard_error = NULL; if (!mode || (strcmp (mode, "on") && strcmp (mode, "all"))) { result = g_spawn_command_line_sync ("tmux set-option allow-passthrough on", &standard_output, &standard_error, &wait_status, NULL); if (result) { tmux_allow_passthrough_original = mode; tmux_allow_passthrough_is_changed = TRUE; } } else { g_free (mode); } out: g_free (standard_output); g_free (standard_error); return result; } gboolean chicle_retire_passthrough_workarounds_tmux (void) { gboolean result = FALSE; gchar *standard_output = NULL; gchar *standard_error = NULL; gchar *cmd = NULL; gint wait_status = -1; if (!tmux_allow_passthrough_is_changed) return TRUE; if (tmux_allow_passthrough_original) { cmd = g_strdup_printf ("tmux set-option allow-passthrough %s", tmux_allow_passthrough_original); } else { cmd = g_strdup ("tmux set-option -u allow-passthrough"); } result = g_spawn_command_line_sync (cmd, &standard_output, &standard_error, &wait_status, NULL); if (result) { g_free (tmux_allow_passthrough_original); tmux_allow_passthrough_original = NULL; tmux_allow_passthrough_is_changed = FALSE; } g_free (cmd); g_free (standard_output); g_free (standard_error); return result; } static ChafaTerm * new_ctty_term (void) { ChafaTerm *ctty_term = NULL; gint in_fd = -1, out_fd = -1; #if defined(L_ctermid) && !defined(G_OS_WIN32) gchar dev_name [L_ctermid]; pid_t proc_group; ctermid (dev_name); in_fd = open (dev_name, O_RDONLY); out_fd = open (dev_name, O_WRONLY); if (in_fd < 0 || out_fd < 0) goto out; /* Don't probe tty if we're definitely in the background. This mitigates * issues with running under timeout(1) in CI and such, but does not * guarantee that we won't be moved to background between now and * ChafaTerm's call to tcsetattr(), causing it to block. Those cases are * outside the scope of our handling. * * If the user explicitly requests ctty probing, we skip this check. */ if (options.probe_mode != CHICLE_PROBE_MODE_CTTY) { proc_group = getpgrp (); if (tcgetpgrp (in_fd) != proc_group || tcgetpgrp (out_fd) != proc_group) goto out; } ctty_term = chafa_term_new (NULL, in_fd, out_fd, out_fd); out: #endif if (!ctty_term) { if (in_fd >= 0) close (in_fd); if (out_fd >= 0) close (out_fd); } return ctty_term; } gboolean chicle_parse_options (int *argc, char **argv []) { GError *error = NULL; GOptionContext *context; gboolean result = FALSE; const GOptionEntry option_entries [] = { /* Note: The descriptive blurbs here are never shown to the user */ { "help", 'h', 0, G_OPTION_ARG_NONE, &options.show_help, "Show help", NULL }, { "version", '\0', 0, G_OPTION_ARG_NONE, &options.show_version, "Show version", NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &options.verbose, "Be verbose", NULL }, { "align", '\0', 0, G_OPTION_ARG_CALLBACK, parse_align_arg, "Align", NULL }, { "animate", '\0', 0, G_OPTION_ARG_CALLBACK, parse_animate_arg, "Animate", NULL }, { "bg", '\0', 0, G_OPTION_ARG_CALLBACK, parse_bg_color_arg, "Background color of display", NULL }, { "center", 'C', 0, G_OPTION_ARG_CALLBACK, parse_center_arg, "Center", NULL }, { "clear", '\0', 0, G_OPTION_ARG_NONE, &options.clear, "Clear", NULL }, { "colors", 'c', 0, G_OPTION_ARG_CALLBACK, parse_colors_arg, "Colors (none, 2, 16, 256, 240 or full)", NULL }, { "color-extractor", '\0', 0, G_OPTION_ARG_CALLBACK, parse_color_extractor_arg, "Color extractor (average or median)", NULL }, { "color-space", '\0', 0, G_OPTION_ARG_CALLBACK, parse_color_space_arg, "Color space (rgb or din99d)", NULL }, { "dither", '\0', 0, G_OPTION_ARG_CALLBACK, parse_dither_arg, "Dither", NULL }, { "dither-grain",'\0', 0, G_OPTION_ARG_CALLBACK, parse_dither_grain_arg, "Dither grain", NULL }, { "dither-intensity", '\0', 0, G_OPTION_ARG_CALLBACK, parse_dither_intensity_arg, "Dither intensity", NULL }, { "dump-detect", '\0', 0, G_OPTION_ARG_NONE, &options.do_dump_detect, "Dump detection results", NULL }, { "dump-glyph-file", '\0', 0, G_OPTION_ARG_CALLBACK, parse_dump_glyph_file_arg, "Dump glyph file", NULL }, { "duration", 'd', 0, G_OPTION_ARG_CALLBACK, parse_duration_arg, "Duration", NULL }, { "exact-size", '\0', 0, G_OPTION_ARG_CALLBACK, parse_exact_size_arg, "Whether to prefer the original image size", NULL }, { "fg", '\0', 0, G_OPTION_ARG_CALLBACK, parse_fg_color_arg, "Foreground color of display", NULL }, { "fg-only", '\0', 0, G_OPTION_ARG_NONE, &options.fg_only, "Foreground only", NULL }, { "files", '\0', 0, G_OPTION_ARG_CALLBACK, parse_files_arg, "File list", NULL }, { "files0", '\0', 0, G_OPTION_ARG_CALLBACK, parse_files0_arg, "File list (NUL-separated)", NULL }, { "fill", '\0', 0, G_OPTION_ARG_CALLBACK, parse_fill_arg, "Fill symbols", NULL }, { "fit-width", '\0', 0, G_OPTION_ARG_NONE, &options.fit_to_width, "Fit to width", NULL }, { "font-ratio", '\0', 0, G_OPTION_ARG_CALLBACK, parse_font_ratio_arg, "Font ratio", NULL }, { "format", 'f', 0, G_OPTION_ARG_CALLBACK, parse_format_arg, "Format of output pixel data (iterm, kitty, sixels or symbols)", NULL }, { "fuzz-options", '\0', 0, G_OPTION_ARG_NONE, &options.fuzz_options, "Fuzz the options", NULL }, { "glyph-file", '\0', 0, G_OPTION_ARG_CALLBACK, parse_glyph_file_arg, "Glyph file", NULL }, { "grid", '\0', 0, G_OPTION_ARG_CALLBACK, parse_grid_arg, "Grid", NULL }, { "grid-on", 'g', 0, G_OPTION_ARG_NONE, &options.grid_on, "Grid on", NULL }, { "invert", '\0', 0, G_OPTION_ARG_NONE, &options.invert, "Invert foreground/background", NULL }, { "label", '\0', 0, G_OPTION_ARG_CALLBACK, parse_label_arg, "Print labels", NULL }, { "label-on", 'l', 0, G_OPTION_ARG_NONE, &options.label, "Print labels on", NULL }, { "link", '\0', 0, G_OPTION_ARG_CALLBACK, parse_link_arg, "Link labels", NULL }, { "margin-bottom", '\0', 0, G_OPTION_ARG_INT, &options.margin_bottom, "Bottom margin", NULL }, { "margin-right", '\0', 0, G_OPTION_ARG_INT, &options.margin_right, "Right margin", NULL }, { "optimize", 'O', 0, G_OPTION_ARG_INT, &options.optimization_level, "Optimization", NULL }, { "passthrough", '\0', 0, G_OPTION_ARG_CALLBACK, parse_passthrough_arg, "Passthrough", NULL }, { "polite", '\0', 0, G_OPTION_ARG_CALLBACK, parse_polite_arg, "Polite", NULL }, { "preprocess", 'p', 0, G_OPTION_ARG_CALLBACK, parse_preprocess_arg, "Preprocessing", NULL }, { "probe", '\0', 0, G_OPTION_ARG_CALLBACK, parse_probe_arg, "Terminal probing", NULL }, { "probe-mode", '\0', 0, G_OPTION_ARG_CALLBACK, parse_probe_mode_arg, "Probe mode", NULL }, { "relative", '\0', 0, G_OPTION_ARG_CALLBACK, parse_relative_arg, "Relative", NULL }, { "scale", '\0', 0, G_OPTION_ARG_CALLBACK, parse_scale_arg, "Scale", NULL }, { "size", 's', 0, G_OPTION_ARG_CALLBACK, parse_size_arg, "Output size", NULL }, { "speed", '\0', 0, G_OPTION_ARG_CALLBACK, parse_anim_speed_arg, "Animation speed", NULL }, { "stretch", '\0', 0, G_OPTION_ARG_NONE, &options.stretch, "Stretch image to fix output dimensions", NULL }, { "symbols", '\0', 0, G_OPTION_ARG_CALLBACK, parse_symbols_arg, "Output symbols", NULL }, { "threads", '\0', 0, G_OPTION_ARG_INT, &options.n_threads, "Number of threads", NULL }, { "threshold", 't', 0, G_OPTION_ARG_CALLBACK, parse_threshold_arg, "Transparency threshold", NULL }, { "view-size", '\0', 0, G_OPTION_ARG_CALLBACK, parse_view_size_arg, "View size", NULL }, { "watch", '\0', 0, G_OPTION_ARG_NONE, &options.watch, "Watch a file's contents", NULL }, { "work", 'w', 0, G_OPTION_ARG_INT, &options.work_factor, "Work factor", NULL }, /* Deprecated: Equivalent to --scale max */ { "zoom", '\0', 0, G_OPTION_ARG_NONE, &options.zoom, "Allow scaling up beyond one character per pixel", NULL }, { 0 } }; ChafaCanvasMode canvas_mode; ChafaPixelMode pixel_mode; ChafaPassthrough passthrough; gboolean polite; gchar **envp; envp = g_get_environ (); memset (&options, 0, sizeof (options)); context = g_option_context_new ("[COMMAND] [OPTION...]"); g_option_context_set_help_enabled (context, FALSE); g_option_context_add_main_entries (context, option_entries, NULL); options.executable_name = g_strdup ((*argv) [0]); /* Defaults */ options.is_interactive = isatty (STDIN_FILENO) && isatty (STDOUT_FILENO); detect_terminal (envp, &options.term_info, &canvas_mode, &pixel_mode, &passthrough, &options.symbol_map, &options.fill_symbol_map, &polite); options.mode = CHAFA_CANVAS_MODE_MAX; /* Unset */ options.pixel_mode = pixel_mode; options.pixel_mode_set = FALSE; options.polite = polite; options.dither_mode = CHAFA_DITHER_MODE_NONE; options.dither_grain_width = -1; /* Unset */ options.dither_grain_height = -1; /* Unset */ options.dither_intensity = 1.0; options.animate = TRUE; options.horiz_align = CHAFA_ALIGN_MAX; /* Unset */ options.vert_align = CHAFA_ALIGN_MAX; /* Unset */ options.probe = CHICLE_TRISTATE_AUTO; options.probe_duration = CHICLE_PROBE_DURATION_DEFAULT; options.preprocess = TRUE; options.relative_set = FALSE; options.fg_only = FALSE; options.color_extractor = CHAFA_COLOR_EXTRACTOR_AVERAGE; options.color_space = CHAFA_COLOR_SPACE_RGB; options.view_width = -1; /* Unset */ options.view_height = -1; /* Unset */ options.width = -1; /* Unset */ options.height = -1; /* Unset */ options.grid_on = FALSE; options.grid_width = -1; /* Unset */ options.grid_height = -1; /* Unset */ options.fit_to_width = FALSE; options.font_ratio = -1.0; /* Unset */ options.margin_bottom = -1; /* Unset */ options.margin_right = -1; /* Unset */ options.scale = -1.0; /* Unset */ options.work_factor = 5; options.optimization_level = G_MININT; /* Unset */ options.n_threads = -1; options.fg_color = 0xffffff; options.bg_color = 0x000000; options.transparency_threshold = G_MAXDOUBLE; /* Unset */ options.file_duration_s = -1.0; /* Unset */ options.anim_fps = -1.0; options.anim_speed_multiplier = 1.0; options.use_exact_size = CHICLE_TRISTATE_AUTO; options.cell_width = 10; options.cell_height = 20; options.label = FALSE; options.link_labels = CHICLE_TRISTATE_AUTO; options.use_unicode = TRUE; if (!g_option_context_parse (context, argc, argv, &error)) { gchar *safe_message = g_strdup (error->message); chicle_flatten_cntrl_inplace (safe_message); g_printerr ("%s: %s\n", options.executable_name, safe_message); g_free (safe_message); goto out; } term = chafa_term_new (NULL, global_path_queue_n_stdin == 0 ? STDIN_FILENO : -1, STDOUT_FILENO, STDERR_FILENO); /* Parser kludges */ if (options.grid_on && options.grid_width == -1 && options.grid_height == -1) { options.grid_width = options.grid_height = CHICLE_GRID_AUTO; } /* If help, version info or config dump was requested, print it and bail out */ if (options.show_help) { print_summary (); options.skip_processing = TRUE; } if (options.show_version) { print_version (); options.skip_processing = TRUE; } if (options.do_dump_detect) { dump_settings (options.term_info, canvas_mode, pixel_mode, passthrough, polite); options.skip_processing = TRUE; } /* Some options preclude normal arg processing */ if (options.skip_processing) { result = TRUE; goto out; } /* Optionally fuzz the options */ if (options.fuzz_options && *argc > 1) { fuzz_options_with_file (&options, (*argv) [1]); } /* Synchronous probe for sixels, default colors, etc. */ { ChafaTerm *ctty_term = NULL; ChafaTerm *probe_term = NULL; if (options.probe_mode == CHICLE_PROBE_MODE_CTTY || (options.probe_mode == CHICLE_PROBE_MODE_ANY && (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO)))) probe_term = ctty_term = new_ctty_term (); if (!probe_term) probe_term = term; if ((options.probe == CHICLE_TRISTATE_TRUE || options.probe == CHICLE_TRISTATE_AUTO) && options.probe_duration >= 0.0) { chafa_term_sync_probe (probe_term, options.probe_duration * 1000); if (!options.pixel_mode_set) { options.pixel_mode = chafa_term_info_get_best_pixel_mode ( chafa_term_get_term_info (probe_term)); } if (!options.fg_color_set) { gint32 color = chafa_term_get_default_fg_color (probe_term); if (color >= 0) options.fg_color = color; } if (!options.bg_color_set) { gint32 color = chafa_term_get_default_bg_color (probe_term); if (color >= 0) options.bg_color = color; } } /* Detect terminal geometry */ chafa_term_get_size_px (probe_term, &detected_term_size.width_pixels, &detected_term_size.height_pixels); chafa_term_get_size_cells (probe_term, &detected_term_size.width_cells, &detected_term_size.height_cells); chafa_term_set_term_info (term, chafa_term_get_term_info (probe_term)); if (ctty_term) chafa_term_destroy (ctty_term); } /* Fall back on COLUMNS. It's the best we can do in some environments (e.g. CI). */ if (detected_term_size.width_cells < 1) { const gchar *columns_str = g_getenv ("COLUMNS"); if (columns_str) detected_term_size.width_cells = atoi (columns_str); if (detected_term_size.width_cells < 1) detected_term_size.width_cells = -1; } /* Figure out cell size if we can */ if (detected_term_size.width_cells > 0 && detected_term_size.height_cells > 0 && detected_term_size.width_pixels > 0 && detected_term_size.height_pixels > 0) { options.cell_width = detected_term_size.width_pixels / detected_term_size.width_cells; options.cell_height = detected_term_size.height_pixels / detected_term_size.height_cells; } /* Apply the font ratio if specified, or derive it if not */ if (options.cell_width > 0 && options.cell_height > 0) { if (options.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS && options.font_ratio > 0.0) { options.cell_height = options.cell_width / options.font_ratio; } else { options.font_ratio = (gdouble) options.cell_width / (gdouble) options.cell_height; } } /* Assign detected or default dimensions if none specified */ if (options.width < 0 && options.height < 0) { using_detected_size = TRUE; } if (options.margin_bottom < 0) { options.margin_bottom = 1; /* Default */ } /* On some terminals, sixel output leaves the cursor below the image, so * force a bottom margin of at least one even if the user wanted less. */ if (options.margin_bottom < 1 && options.pixel_mode == CHAFA_PIXEL_MODE_SIXELS && (chafa_term_info_get_quirks (chafa_term_get_term_info (term)) & CHAFA_TERM_QUIRK_SIXEL_OVERSHOOT)) options.margin_bottom = 1; if (options.margin_right < 0) { options.margin_right = 0; /* Default */ /* Kitty leaves the cursor in the column trailing the last row of the * image. However, if the image is as wide as the terminal, the cursor * will wrap to the first column of the following row, making us lose * track of its position. * * This is not a problem when instructed to clear the terminal, as we * use absolute positioning then. * * If needed, trim one column from the image to make the cursor position * predictable. */ if (options.pixel_mode == CHAFA_PIXEL_MODE_KITTY && using_detected_size && !(options.clear && options.margin_bottom >= 2)) { options.margin_right = 1; } } if (options.view_width < 0 && options.view_height < 0) { options.view_width = detected_term_size.width_cells; options.view_height = detected_term_size.height_cells; if (options.view_width < 0 && options.view_height < 0) { options.view_width = 80; options.view_height = 25; } } if (using_detected_size && ((options.stretch && (options.view_width < 0 || options.view_height < 0)) || (options.fit_to_width && options.view_width < 0))) { g_printerr ("%s: Refusing to stretch images to infinity.\n", options.executable_name); goto out; } if (options.view_width < 0) options.view_width = CHICLE_CELL_EXTENT_AUTO_MAX; if (options.view_height < 0) options.view_height = CHICLE_CELL_EXTENT_AUTO_MAX; if (using_detected_size) { options.width = options.view_width; options.height = options.view_height; options.width = (options.width > options.margin_right) ? options.width - options.margin_right : 1; options.height = (options.height > options.margin_bottom) ? options.height - options.margin_bottom : 1; if (options.fit_to_width) { options.height = CHICLE_CELL_EXTENT_AUTO_MAX; /* Fit-to-width only makes sense if we respect the aspect ratio. * We could complain about infinities here, but let's be nice and * let it override --stretch instead. */ options.stretch = FALSE; /* --fit-width implies --scale max */ options.scale = CHICLE_SCALE_MAX; } } /* Now we've established the pixel mode, apply dependent defaults */ if (options.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS) { /* Character cell defaults */ if (options.mode == CHAFA_CANVAS_MODE_MAX) options.mode = canvas_mode; if (options.dither_grain_width < 0) options.dither_grain_width = 4; if (options.dither_grain_height < 0) options.dither_grain_height = 4; if (options.scale <= 0.0) options.scale = 4.0; } else { /* iTerm2/Kitty/sixel defaults */ if (options.mode == CHAFA_CANVAS_MODE_MAX) options.mode = CHAFA_CANVAS_MODE_TRUECOLOR; if (options.dither_grain_width < 0) options.dither_grain_width = 1; if (options.dither_grain_height < 0) options.dither_grain_height = 1; if (options.scale <= 0.0) options.scale = 1.0; } if (options.pixel_mode == CHAFA_PIXEL_MODE_SIXELS) { if (!options.dither_mode_set) options.dither_mode = CHAFA_DITHER_MODE_NOISE; } /* Apply detected passthrough if auto */ if (!options.passthrough_set) { /* tmux 3.4+ supports sixels without the need for passthrough. We check * this here instead of in detect_terminal() because we need to react to * a user-requested sixel mode too */ if (options.pixel_mode == CHAFA_PIXEL_MODE_SIXELS && passthrough == CHAFA_PASSTHROUGH_TMUX && get_tmux_version (envp) >= 3004) { options.passthrough = CHAFA_PASSTHROUGH_NONE; } else { options.passthrough = passthrough; } } /* Resolve grid dimensions if necessary. Items need to be a bit bigger * in symbols mode in order to be legible. */ if (options.grid_width == CHICLE_GRID_AUTO || options.grid_height == CHICLE_GRID_AUTO) { gint item_width = (MIN (options.width, options.pixel_mode == CHAFA_PIXEL_MODE_SYMBOLS ? 19 : 12)); options.grid_width = options.width / item_width; options.grid_height = -1; } /* Set default alignment depending on run mode */ if (options.horiz_align == CHAFA_ALIGN_MAX) { options.horiz_align = ((options.grid_width > 0 || options.grid_height > 0) ? CHAFA_ALIGN_CENTER : CHAFA_ALIGN_START); } if (options.vert_align == CHAFA_ALIGN_MAX) { options.vert_align = ((options.grid_width > 0 || options.grid_height > 0) ? CHAFA_ALIGN_END : CHAFA_ALIGN_START); } /* Optionally establish parking row for the cursor */ options.have_parking_row = ((using_detected_size || options.vert_align == CHAFA_ALIGN_END) && options.margin_bottom == 0) ? FALSE : TRUE; /* Apply tmux workarounds only if both detected and desired, and a * graphics protocol is desired */ if (passthrough == CHAFA_PASSTHROUGH_TMUX && options.passthrough == CHAFA_PASSTHROUGH_TMUX && options.pixel_mode != CHAFA_PIXEL_MODE_SYMBOLS) chicle_apply_passthrough_workarounds_tmux (); if (options.work_factor < 1 || options.work_factor > 9) { g_printerr ("%s: Work factor must be in the range [1-9].\n", options.executable_name); goto out; } if (options.transparency_threshold == G_MAXDOUBLE) options.transparency_threshold = 0.5; else options.transparency_threshold_set = TRUE; if (options.transparency_threshold < 0.0 || options.transparency_threshold > 1.0) { g_printerr ("%s: Transparency threshold %.1lf is not in the range [0.0-1.0].\n", options.executable_name, options.transparency_threshold); goto out; } /* Resolve whether to hyperlink */ if (options.link_labels == CHICLE_TRISTATE_AUTO) options.link_labels = isatty (STDOUT_FILENO) ? CHICLE_TRISTATE_TRUE : CHICLE_TRISTATE_FALSE; /* Collect filenames and validate count and correct usage of stdin */ if (*argc > 1) { options.args = collect_variable_arguments (argc, argv, 1); } else if (global_path_queue_n_stdin < 1 && !isatty (STDIN_FILENO)) { /* Receiving data through a pipe, and no file arguments. Act as if * invoked with "chafa -". */ options.args = g_list_append (NULL, g_strdup ("-")); } else if (chicle_path_queue_get_length (global_path_queue) == 0) { /* No arguments, no pipe, no file lists, and no cry for help. */ print_brief_summary (); goto out; } if (count_dash_strings (options.args) + global_path_queue_n_stdin > 1) { g_printerr ("%s: Dash '-' to pipe from standard input can be used at most once.\n", options.executable_name); goto out; } if (options.watch) { if (g_list_length (options.args) != 1 || chicle_path_queue_get_length (global_path_queue) != 0) { g_printerr ("%s: Can only use --watch with exactly one file.\n", options.executable_name); goto out; } if (!strcmp (options.args->data, "-")) { g_printerr ("%s: Can only use --watch with a filename, not a pipe.\n", options.executable_name); goto out; } } if (options.zoom) { g_printerr ("%s: Warning: --zoom is deprecated, use --scale max instead.\n", options.executable_name); options.scale = CHICLE_SCALE_MAX; } /* --stretch implies --scale max (same as --zoom) */ if (options.stretch) { options.scale = CHICLE_SCALE_MAX; } /* `--exact-size on` overrides other sizing options */ if (options.use_exact_size == CHICLE_TRISTATE_TRUE) { options.fit_to_width = FALSE; options.scale = 1.0; options.stretch = FALSE; using_detected_size = TRUE; } if (options.invert) { guint32 temp_color; temp_color = options.bg_color; options.bg_color = options.fg_color; options.fg_color = temp_color; } if (options.file_duration_s < 0.0 && (!options.is_interactive || (options.args && options.args->next) || (global_n_path_streams > 0))) { /* Apply a zero default duration when we have multiple files or it looks * like we're part of a pipe; we don't want to get stuck if the user is * trying to e.g. batch convert files. Allow -d to override. */ options.file_duration_s = CHICLE_FILE_DURATION_DEFAULT; } /* Since FGBG mode can't use escape sequences to invert, it really * needs inverted symbols. In other modes they will only slow us down, * so disable them unless the user specified symbols of their own. */ if (options.mode != CHAFA_CANVAS_MODE_FGBG && !options.symbols_specified) chafa_symbol_map_remove_by_tags (options.symbol_map, CHAFA_SYMBOL_TAG_INVERTED); /* If optimization level is unset, enable optimizations. However, we * leave them off for FGBG mode, since control sequences may be * unexpected in this mode unless explicitly asked for. */ if (options.optimization_level == G_MININT) options.optimization_level = (options.mode == CHAFA_CANVAS_MODE_FGBG) ? 0 : 5; if (options.optimization_level < 0 || options.optimization_level > 9) { g_printerr ("%s: Optimization level %d is not in the range [0-9].\n", options.executable_name, options.optimization_level); goto out; } /* Translate optimization level to flags */ options.optimizations = CHAFA_OPTIMIZATION_NONE; if (options.optimization_level >= 1) options.optimizations |= CHAFA_OPTIMIZATION_REUSE_ATTRIBUTES; if (options.optimization_level >= 6) options.optimizations |= CHAFA_OPTIMIZATION_REPEAT_CELLS; if (options.optimization_level >= 7) options.optimizations |= CHAFA_OPTIMIZATION_SKIP_CELLS; chafa_set_n_threads (options.n_threads); result = TRUE; out: g_option_context_free (context); g_strfreev (envp); return result; } chafa-1.18.2/tools/chafa/chicle-options.h000066400000000000000000000122321517447374300201570ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_OPTIONS_H__ #define __CHICLE_OPTIONS_H__ #include "config.h" G_BEGIN_DECLS #include #include #include /* strspn, strlen, strcmp, strncmp, memset */ #include /* setlocale */ #ifdef HAVE_SYS_IOCTL_H # include /* ioctl */ #endif #include /* open */ #include /* stat */ #include /* open */ #include /* STDOUT_FILENO */ #ifdef HAVE_SIGACTION # include /* sigaction */ #endif #include /* exit */ #ifdef HAVE_TERMIOS_H # include /* tcgetattr, tcsetattr */ #endif #include #include #include "chicle-named-colors.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #endif #define CHICLE_ANIM_FPS_MAX 100000.0 #define CHICLE_FILE_DURATION_DEFAULT 0.0 #define CHICLE_SCALE_MAX 9999.0 #define CHICLE_CELL_EXTENT_AUTO_MAX 65535 #define CHICLE_PROBE_DURATION_DEFAULT 5.0 typedef enum { CHICLE_TRISTATE_FALSE = 0, CHICLE_TRISTATE_TRUE, CHICLE_TRISTATE_AUTO } ChicleTristate; typedef enum { CHICLE_PROBE_MODE_ANY = 0, CHICLE_PROBE_MODE_CTTY, CHICLE_PROBE_MODE_STDIO } ChicleProbeMode; /* Dimensions are set to GRID_AUTO with --grid auto. This means the user * wants us to pick appropriate grid parameters based on the view size */ #define CHICLE_GRID_AUTO -2 typedef struct { gchar *executable_name; gboolean show_help; gboolean show_version; gboolean skip_processing; GList *args; ChafaCanvasMode mode; gboolean dither_mode_set; ChafaColorExtractor color_extractor; ChafaColorSpace color_space; ChafaDitherMode dither_mode; ChafaPixelMode pixel_mode; gboolean pixel_mode_set; gint dither_grain_width; gint dither_grain_height; gdouble dither_intensity; ChafaSymbolMap *symbol_map; ChafaSymbolMap *fill_symbol_map; gboolean symbols_specified; gboolean is_interactive; gboolean clear; gboolean verbose; gboolean invert; gboolean preprocess; gboolean polite; gboolean stretch; gboolean zoom; gboolean watch; gboolean fg_only; gboolean animate; gboolean relative; gboolean relative_set; gboolean fit_to_width; gboolean grid_on; gboolean label; ChicleTristate link_labels; gboolean use_unicode; ChafaAlign horiz_align; ChafaAlign vert_align; gint view_width, view_height; gint width, height; gint cell_width, cell_height; gint grid_width, grid_height; gint margin_bottom, margin_right; ChicleTristate probe; ChicleProbeMode probe_mode; gdouble probe_duration; gdouble scale; gdouble font_ratio; gint work_factor; gint optimization_level; gint n_threads; ChafaOptimizations optimizations; ChafaPassthrough passthrough; gboolean passthrough_set; guint32 fg_color; gboolean fg_color_set; guint32 bg_color; gboolean bg_color_set; gdouble transparency_threshold; gboolean transparency_threshold_set; gdouble file_duration_s; /* If > 0.0, override the framerate specified by the input file. */ gdouble anim_fps; /* Applied after FPS is determined. If final value >= ANIM_FPS_MAX, * eliminate interframe delay altogether. */ gdouble anim_speed_multiplier; ChicleTristate use_exact_size; /* Automatically set if terminal size is detected and there is * zero bottom margin. */ gboolean have_parking_row; /* Whether to perturb the options based on a seed read from the first * input file. This improves coverage when fuzzing. */ gboolean fuzz_options; ChafaTermInfo *term_info; gboolean do_dump_detect; } ChicleOptions; typedef struct { gint width_cells, height_cells; gint width_pixels, height_pixels; } ChicleTermSize; extern ChicleOptions options; extern ChicleTermSize detected_term_size; extern gboolean using_detected_size; extern ChiclePathQueue *global_path_queue; extern gint global_path_queue_n_stdin; extern gint global_n_path_streams; extern ChafaTerm *term; gboolean chicle_parse_options (int *argc, char **argv []); gboolean chicle_apply_passthrough_workarounds_tmux (void); gboolean chicle_retire_passthrough_workarounds_tmux (void); G_END_DECLS #endif /* __CHICLE_OPTIONS_H__ */ chafa-1.18.2/tools/chafa/chicle-path-queue.c000066400000000000000000000246331517447374300205450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2024-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include /* open */ #include /* open */ #include /* STDIN_FILENO */ #include "chafa.h" #include "chafa-byte-fifo.h" #include "chicle-path-queue.h" /* Include after glib.h for G_OS_WIN32 */ #ifdef G_OS_WIN32 # ifdef HAVE_WINDOWS_H # include # endif # include # include #endif /* ------------------- * * Defines and structs * * ------------------- */ #define PATH_TOKEN_LEN_MAX 16384 typedef enum { PATH_SOURCE_PATH, PATH_SOURCE_PATH_LIST, PATH_SOURCE_STREAM } PathSourceType; typedef struct { PathSourceType type; gpointer data; /* Element separator for PATH_SOURCE_STREAM */ gchar *separator; gint separator_len; } PathSource; struct ChiclePathQueue { gint refs; GQueue *queue; PathSource *current_src; ChafaStreamReader *current_reader; gchar *current_path_token; gint n_processed; guint have_stdin_source : 1; }; static void path_source_destroy (PathSource *src) { if (!src) return; switch (src->type) { case PATH_SOURCE_PATH: g_free (src->data); break; case PATH_SOURCE_PATH_LIST: g_list_free_full (src->data, g_free); break; case PATH_SOURCE_STREAM: g_free (src->data); g_free (src->separator); break; } g_free (src); } static gboolean path_source_is_stdin (PathSource *src) { return (src->type == PATH_SOURCE_STREAM && !strcmp (src->data, "-")) ? TRUE : FALSE; } static void maybe_close_fd (ChafaStreamReader *stream_reader) { gint fd = chafa_stream_reader_get_fd (stream_reader); if (fd != STDIN_FILENO) close (fd); } static void clear_current_src (ChiclePathQueue *path_queue) { path_source_destroy (path_queue->current_src); path_queue->current_src = NULL; if (path_queue->current_reader) { maybe_close_fd (path_queue->current_reader); chafa_stream_reader_unref (path_queue->current_reader); path_queue->current_reader = NULL; } } /* Check if we've reached the end of current_src. Clear it if so. */ static void check_src_end (ChiclePathQueue *path_queue) { if (!path_queue->current_src) return; switch (path_queue->current_src->type) { case PATH_SOURCE_PATH: break; case PATH_SOURCE_PATH_LIST: if (!path_queue->current_src->data) clear_current_src (path_queue); break; case PATH_SOURCE_STREAM: if (!path_queue->current_reader || chafa_stream_reader_is_eof (path_queue->current_reader)) clear_current_src (path_queue); break; } } static void open_current_stream (ChiclePathQueue *path_queue) { gint fd; g_assert (path_queue->current_reader == NULL); g_assert (path_queue->current_src->type == PATH_SOURCE_STREAM); fd = path_source_is_stdin (path_queue->current_src) ? STDIN_FILENO : open (path_queue->current_src->data, O_RDONLY); if (fd >= 0) path_queue->current_reader = chafa_stream_reader_new_from_fd_full ( fd, path_queue->current_src->separator, path_queue->current_src->separator_len); } /* Ensure there's a current_src and that it's not empty. For streams, this * may be unknown until async reads have finished; we return TRUE for these. */ static gboolean ensure_current_src (ChiclePathQueue *path_queue) { for (;;) { if (!path_queue->current_src) { path_queue->current_src = g_queue_pop_head (path_queue->queue); if (!path_queue->current_src) break; if (path_queue->current_src->type == PATH_SOURCE_STREAM) open_current_stream (path_queue); } check_src_end (path_queue); if (path_queue->current_src) return TRUE; } return FALSE; } static void destroy_path_source (gpointer data) { PathSource *src = data; switch (src->type) { case PATH_SOURCE_PATH: g_free (src->data); break; case PATH_SOURCE_PATH_LIST: g_list_free_full (src->data, g_free); break; case PATH_SOURCE_STREAM: g_free (src->data); g_free (src->separator); break; } } static gboolean pop_stream_path_token (ChiclePathQueue *path_queue) { gint result = 0; g_assert (path_queue->current_src->type == PATH_SOURCE_STREAM); if (path_queue->current_path_token) return TRUE; /* Discard blank lines until we encounter a non-blank line or an error */ while (result == 0) { g_free (path_queue->current_path_token); path_queue->current_path_token = NULL; result = chafa_stream_reader_read_token (path_queue->current_reader, (gpointer *) &path_queue->current_path_token, PATH_TOKEN_LEN_MAX); if (result > 0 && !strcmp (path_queue->current_src->separator, "\n")) { /* If we're separating on \n, handle \r\n by eliminating the \r too */ if (path_queue->current_path_token [result - 1] == '\r') { path_queue->current_path_token [result - 1] = '\0'; result--; } } } return result >= 0 ? TRUE : FALSE; } /* ---------- * * Public API * * ---------- */ ChiclePathQueue * chicle_path_queue_new (void) { ChiclePathQueue *path_queue; path_queue = g_new0 (ChiclePathQueue, 1); path_queue->refs = 1; path_queue->queue = g_queue_new (); return path_queue; } ChiclePathQueue * chicle_path_queue_ref (ChiclePathQueue *path_queue) { gint refs; g_return_val_if_fail (path_queue != NULL, NULL); refs = g_atomic_int_get (&path_queue->refs); g_return_val_if_fail (refs > 0, NULL); g_atomic_int_inc (&path_queue->refs); return path_queue; } void chicle_path_queue_unref (ChiclePathQueue *path_queue) { gint refs; g_return_if_fail (path_queue != NULL); refs = g_atomic_int_get (&path_queue->refs); g_return_if_fail (refs > 0); if (g_atomic_int_dec_and_test (&path_queue->refs)) { clear_current_src (path_queue); g_queue_free_full (path_queue->queue, destroy_path_source); g_free (path_queue); } } void chicle_path_queue_push_path (ChiclePathQueue *path_queue, const gchar *path) { PathSource *src; src = g_new0 (PathSource, 1); src->type = PATH_SOURCE_PATH; src->data = g_strdup (path); g_queue_push_tail (path_queue->queue, src); } void chicle_path_queue_push_path_list_steal (ChiclePathQueue *path_queue, GList *path_list) { PathSource *src; src = g_new0 (PathSource, 1); src->type = PATH_SOURCE_PATH_LIST; src->data = path_list; g_queue_push_tail (path_queue->queue, src); } void chicle_path_queue_push_stream (ChiclePathQueue *path_queue, const gchar *stream_path, const gchar *separator, gint separator_len) { PathSource *src; src = g_new0 (PathSource, 1); src->type = PATH_SOURCE_STREAM; src->data = g_strdup (stream_path); src->separator = g_malloc (separator_len + 1); src->separator_len = separator_len; memcpy (src->separator, separator, separator_len); src->separator [separator_len] = '\0'; g_queue_push_tail (path_queue->queue, src); if (path_source_is_stdin (src)) path_queue->have_stdin_source = TRUE; } void chicle_path_queue_wait (ChiclePathQueue *path_queue) { if (!ensure_current_src (path_queue)) return; if (path_queue->current_src->type == PATH_SOURCE_STREAM) { if (pop_stream_path_token (path_queue)) return; chafa_stream_reader_wait (path_queue->current_reader, -1); } } gchar * chicle_path_queue_try_pop (ChiclePathQueue *path_queue) { gchar *path = NULL; GList *l; if (!ensure_current_src (path_queue)) return NULL; switch (path_queue->current_src->type) { case PATH_SOURCE_PATH: path = path_queue->current_src->data; clear_current_src (path_queue); break; case PATH_SOURCE_PATH_LIST: l = path_queue->current_src->data; path = l->data; path_queue->current_src->data = g_list_delete_link (path_queue->current_src->data, l); break; case PATH_SOURCE_STREAM: pop_stream_path_token (path_queue); if (path_queue->current_path_token) { path = path_queue->current_path_token; path_queue->current_path_token = NULL; } break; } if (path) path_queue->n_processed++; return path; } gchar * chicle_path_queue_pop (ChiclePathQueue *path_queue) { gchar *path = NULL; for (;;) { path = chicle_path_queue_try_pop (path_queue); if (path) break; if (chicle_path_queue_is_empty (path_queue)) break; chicle_path_queue_wait (path_queue); } return path; } gint chicle_path_queue_get_length (ChiclePathQueue *path_queue) { return g_queue_get_length (path_queue->queue); } gboolean chicle_path_queue_is_empty (ChiclePathQueue *path_queue) { if (!ensure_current_src (path_queue)) return TRUE; return FALSE; } gint chicle_path_queue_get_n_processed (ChiclePathQueue *path_queue) { return path_queue->n_processed; } gboolean chicle_path_queue_have_stdin_source (ChiclePathQueue *path_queue) { return path_queue->have_stdin_source ? TRUE : FALSE; } chafa-1.18.2/tools/chafa/chicle-path-queue.h000066400000000000000000000040251517447374300205430ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_PATH_QUEUE_H__ #define __CHICLE_PATH_QUEUE_H__ #include #include "chafa-stream-reader.h" G_BEGIN_DECLS typedef struct ChiclePathQueue ChiclePathQueue; ChiclePathQueue *chicle_path_queue_new (void); ChiclePathQueue *chicle_path_queue_ref (ChiclePathQueue *path_queue); void chicle_path_queue_unref (ChiclePathQueue *path_queue); void chicle_path_queue_push_path (ChiclePathQueue *path_queue, const gchar *path); void chicle_path_queue_push_path_list_steal (ChiclePathQueue *path_queue, GList *path_list); void chicle_path_queue_push_stream (ChiclePathQueue *path_queue, const gchar *stream_path, const gchar *separator, gint separator_len); void chicle_path_queue_wait (ChiclePathQueue *path_queue); gchar *chicle_path_queue_try_pop (ChiclePathQueue *path_queue); gchar *chicle_path_queue_pop (ChiclePathQueue *path_queue); gint chicle_path_queue_get_length (ChiclePathQueue *path_queue); gboolean chicle_path_queue_is_empty (ChiclePathQueue *path_queue); gint chicle_path_queue_get_n_processed (ChiclePathQueue *path_queue); gboolean chicle_path_queue_have_stdin_source (ChiclePathQueue *path_queue); G_END_DECLS #endif /* __CHICLE_PATH_QUEUE_H__ */ chafa-1.18.2/tools/chafa/chicle-placement-counter.c000066400000000000000000000047261517447374300221150ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include "chicle-placement-counter.h" #define BUF_SIZE 256 struct ChiclePlacementCounter { guint id; }; static void save_id (ChiclePlacementCounter *counter) { gchar *path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_cache_dir (), "chafa", "placement-id", NULL); gchar buf [BUF_SIZE]; snprintf (buf, BUF_SIZE, "%u\n", counter->id); g_file_set_contents (path, buf, -1, NULL); g_free (path); } static void restore_id (ChiclePlacementCounter *counter) { gchar *path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_cache_dir (), "chafa", "placement-id", NULL); gchar *buf = NULL; gsize length; g_file_get_contents (path, &buf, &length, NULL); if (buf && length > 0) { counter->id = strtoul (buf, NULL, 10); if (counter->id < 1) counter->id = 1; } g_free (buf); g_free (path); } static void ensure_id_storage (void) { gchar *path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_cache_dir (), "chafa", NULL); g_mkdir_with_parents (path, 0750); g_free (path); } ChiclePlacementCounter * chicle_placement_counter_new (void) { ChiclePlacementCounter *counter; counter = g_new0 (ChiclePlacementCounter, 1); counter->id = 0; ensure_id_storage (); restore_id (counter); return counter; } void chicle_placement_counter_destroy (ChiclePlacementCounter *counter) { save_id (counter); g_free (counter); } guint chicle_placement_counter_get_next_id (ChiclePlacementCounter *counter) { counter->id = 1 + (counter->id % 65535); return counter->id; } chafa-1.18.2/tools/chafa/chicle-placement-counter.h000066400000000000000000000024261517447374300221150ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_PLACEMENT_COUNTER_H__ #define __CHICLE_PLACEMENT_COUNTER_H__ #include G_BEGIN_DECLS typedef struct ChiclePlacementCounter ChiclePlacementCounter; ChiclePlacementCounter *chicle_placement_counter_new (void); void chicle_placement_counter_destroy (ChiclePlacementCounter *counter); guint chicle_placement_counter_get_next_id (ChiclePlacementCounter *counter); G_END_DECLS #endif /* __CHICLE_PLACEMENT_COUNTER_H__ */ chafa-1.18.2/tools/chafa/chicle-png-loader.c000066400000000000000000000105241517447374300205110ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "chicle-png-loader.h" #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) struct ChiclePngLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gpointer frame_data; gint width, height; }; static ChiclePngLoader * chicle_png_loader_new (void) { return g_new0 (ChiclePngLoader, 1); } ChiclePngLoader * chicle_png_loader_new_from_mapping (ChicleFileMapping *mapping) { ChiclePngLoader *loader = NULL; gboolean success = FALSE; guint width, height; unsigned char *frame_data = NULL; LodePNGState lode_state; gint lode_error; g_return_val_if_fail (mapping != NULL, NULL); lodepng_state_init (&lode_state); if (!chicle_file_mapping_has_magic (mapping, 0, "\x89PNG", 4)) goto out; loader = chicle_png_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; lode_state.info_raw.colortype = LCT_RGBA; lode_state.info_raw.bitdepth = 8; lode_state.decoder.zlibsettings.max_output_size = IMAGE_BUFFER_SIZE_MAX; /* Decodes to RGBA8 */ if ((lode_error = lodepng_decode (&frame_data, &width, &height, &lode_state, loader->file_data, loader->file_data_len)) != 0) goto out; if (width < 1 || width >= (1 << 28) || height < 1 || height >= (1 << 28)) goto out; loader->frame_data = frame_data; loader->width = (gint) width; loader->height = (gint) height; success = TRUE; out: if (!success) { if (loader) { g_free (loader); loader = NULL; } if (frame_data) free (frame_data); } lodepng_state_cleanup (&lode_state); return loader; } void chicle_png_loader_destroy (ChiclePngLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->frame_data) free (loader->frame_data); g_free (loader); } gboolean chicle_png_loader_get_is_animation (ChiclePngLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return FALSE; } gconstpointer chicle_png_loader_get_frame_data (ChiclePngLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) *pixel_type_out = CHAFA_PIXEL_RGBA8_UNASSOCIATED; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->width * BYTES_PER_PIXEL; return loader->frame_data; } gint chicle_png_loader_get_frame_delay (ChiclePngLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return 0; } void chicle_png_loader_goto_first_frame (ChiclePngLoader *loader) { g_return_if_fail (loader != NULL); } gboolean chicle_png_loader_goto_next_frame (ChiclePngLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return FALSE; } chafa-1.18.2/tools/chafa/chicle-png-loader.h000066400000000000000000000035021517447374300205140ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_PNG_LOADER_H__ #define __CHICLE_PNG_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChiclePngLoader ChiclePngLoader; ChiclePngLoader *chicle_png_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_png_loader_destroy (ChiclePngLoader *loader); gboolean chicle_png_loader_get_is_animation (ChiclePngLoader *loader); gconstpointer chicle_png_loader_get_frame_data (ChiclePngLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_png_loader_get_frame_delay (ChiclePngLoader *loader); void chicle_png_loader_goto_first_frame (ChiclePngLoader *loader); gboolean chicle_png_loader_goto_next_frame (ChiclePngLoader *loader); G_END_DECLS #endif /* __CHICLE_PNG_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-qoi-loader.c000066400000000000000000000077321517447374300205240ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "chicle-qoi-loader.h" #define QOI_IMPLEMENTATION #define QOI_NO_STDIO #include "qoi.h" #define BYTES_PER_PIXEL 4 struct ChicleQoiLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gpointer frame_data; gint width, height; }; static ChicleQoiLoader * chicle_qoi_loader_new (void) { return g_new0 (ChicleQoiLoader, 1); } ChicleQoiLoader * chicle_qoi_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleQoiLoader *loader = NULL; gboolean success = FALSE; unsigned char *frame_data = NULL; qoi_desc desc; g_return_val_if_fail (mapping != NULL, NULL); if (!chicle_file_mapping_has_magic (mapping, 0, "qoif", 4)) goto out; loader = chicle_qoi_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; /* Decodes to RGBA8 */ frame_data = qoi_decode (loader->file_data, loader->file_data_len, &desc, BYTES_PER_PIXEL); if (!frame_data) goto out; if (desc.width < 1 || desc.width >= (1 << 16) || desc.height < 1 || desc.height >= (1 << 16)) goto out; loader->frame_data = frame_data; loader->width = desc.width; loader->height = desc.height; success = TRUE; out: if (!success) { if (loader) { g_free (loader); loader = NULL; } if (frame_data) free (frame_data); } return loader; } void chicle_qoi_loader_destroy (ChicleQoiLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->frame_data) free (loader->frame_data); g_free (loader); } gboolean chicle_qoi_loader_get_is_animation (ChicleQoiLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return FALSE; } gconstpointer chicle_qoi_loader_get_frame_data (ChicleQoiLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) *pixel_type_out = CHAFA_PIXEL_RGBA8_UNASSOCIATED; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->width * BYTES_PER_PIXEL; return loader->frame_data; } gint chicle_qoi_loader_get_frame_delay (ChicleQoiLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return 0; } void chicle_qoi_loader_goto_first_frame (ChicleQoiLoader *loader) { g_return_if_fail (loader != NULL); } gboolean chicle_qoi_loader_goto_next_frame (ChicleQoiLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return FALSE; } chafa-1.18.2/tools/chafa/chicle-qoi-loader.h000066400000000000000000000035021517447374300205200ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_QOI_LOADER_H__ #define __CHICLE_QOI_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleQoiLoader ChicleQoiLoader; ChicleQoiLoader *chicle_qoi_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_qoi_loader_destroy (ChicleQoiLoader *loader); gboolean chicle_qoi_loader_get_is_animation (ChicleQoiLoader *loader); gconstpointer chicle_qoi_loader_get_frame_data (ChicleQoiLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_qoi_loader_get_frame_delay (ChicleQoiLoader *loader); void chicle_qoi_loader_goto_first_frame (ChicleQoiLoader *loader); gboolean chicle_qoi_loader_goto_next_frame (ChicleQoiLoader *loader); G_END_DECLS #endif /* __CHICLE_QOI_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-svg-loader.c000066400000000000000000000165741517447374300205370ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "chicle-svg-loader.h" #define DIMENSION_MAX 4096 #define MAGIC_BUF_SIZE 4096 #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) /* Cairo uses native byte order */ #if G_BYTE_ORDER == G_BIG_ENDIAN # define PIXEL_TYPE CHAFA_PIXEL_ARGB8_PREMULTIPLIED #else # define PIXEL_TYPE CHAFA_PIXEL_BGRA8_PREMULTIPLIED #endif struct ChicleSvgLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; cairo_surface_t *surface; }; static ChicleSvgLoader * chicle_svg_loader_new (void) { return g_new0 (ChicleSvgLoader, 1); } static void calc_dimensions (RsvgHandle *rsvg, gint target_width, gint target_height, guint *width_out, guint *height_out) { #if !LIBRSVG_CHECK_VERSION(2, 52, 0) RsvgDimensionData dim = { 0 }; #endif gdouble width, height; rsvg_handle_set_dpi (rsvg, 150.0); #if LIBRSVG_CHECK_VERSION(2, 52, 0) if (!rsvg_handle_get_intrinsic_size_in_pixels (rsvg, &width, &height)) { width = height = (gdouble) DIMENSION_MAX; } #else rsvg_handle_get_dimensions (rsvg, &dim); width = dim.width; height = dim.height; #endif width = MAX (width, 1.0); height = MAX (height, 1.0); /* Target dimensions can be zero or negative if unspecified */ if (target_width < 1) target_width = (gint) lrint (width); if (target_height < 1) target_height = (gint) lrint (height); /* Avoid generating tiny images that will be subjected to ugly * upscaling later */ if ((width < target_width && height < target_height) || (width > target_width && height > target_height)) { if (target_width / width > target_height / height) { height *= (gdouble) target_width / width; width *= (gdouble) target_width / width; } else { width *= (gdouble) target_height / height; height *= (gdouble) target_height / height; } } /* Enforce maximum surface size */ if (width > DIMENSION_MAX || height > DIMENSION_MAX) { if (width > height) { height *= (gdouble) DIMENSION_MAX / width; width = (gdouble) DIMENSION_MAX; } else { width *= (gdouble) DIMENSION_MAX / height; height = (gdouble) DIMENSION_MAX; } } *width_out = (guint) lrint (width); *height_out = (guint) lrint (height); } ChicleSvgLoader * chicle_svg_loader_new_from_mapping (ChicleFileMapping *mapping, gint target_width, gint target_height) { static GMutex mutex; ChicleSvgLoader *loader = NULL; gboolean success = FALSE; RsvgHandle *rsvg = NULL; cairo_t *cr = NULL; #if LIBRSVG_CHECK_VERSION(2, 46, 0) RsvgRectangle viewport = { 0 }; #endif guint width, height; g_return_val_if_fail (mapping != NULL, NULL); if (chicle_file_mapping_has_magic (mapping, 0, "mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; g_mutex_lock (&mutex); /* Malformed SVGs will typically fail here */ rsvg = rsvg_handle_new_from_data (loader->file_data, loader->file_data_len, NULL); if (!rsvg) goto locked_out; calc_dimensions (rsvg, target_width, target_height, &width, &height); if (width < 1 || width >= (1 << 28) || height < 1 || height >= (1 << 28) || (width * (guint64) height * BYTES_PER_PIXEL > IMAGE_BUFFER_SIZE_MAX)) goto locked_out; loader->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); if (!loader->surface) goto locked_out; cr = cairo_create (loader->surface); #if LIBRSVG_CHECK_VERSION(2, 46, 0) viewport.width = width; viewport.height = height; if (!rsvg_handle_render_document (rsvg, cr, &viewport, NULL)) goto locked_out; #else if (!rsvg_handle_render_cairo (rsvg, cr)) goto locked_out; #endif success = TRUE; locked_out: g_mutex_unlock (&mutex); out: if (cr) cairo_destroy (cr); if (!success) { if (loader) { if (loader->surface) cairo_surface_destroy (loader->surface); g_free (loader); loader = NULL; } } if (rsvg) g_object_unref (rsvg); return loader; } void chicle_svg_loader_destroy (ChicleSvgLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->surface) cairo_surface_destroy (loader->surface); g_free (loader); } gboolean chicle_svg_loader_get_is_animation (ChicleSvgLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return FALSE; } gconstpointer chicle_svg_loader_get_frame_data (ChicleSvgLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) *pixel_type_out = PIXEL_TYPE; if (width_out) *width_out = cairo_image_surface_get_width (loader->surface); if (height_out) *height_out = cairo_image_surface_get_height (loader->surface); if (rowstride_out) *rowstride_out = cairo_image_surface_get_stride (loader->surface); return cairo_image_surface_get_data (loader->surface); } gint chicle_svg_loader_get_frame_delay (ChicleSvgLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return 0; } void chicle_svg_loader_goto_first_frame (ChicleSvgLoader *loader) { g_return_if_fail (loader != NULL); } gboolean chicle_svg_loader_goto_next_frame (ChicleSvgLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return FALSE; } chafa-1.18.2/tools/chafa/chicle-svg-loader.h000066400000000000000000000035421517447374300205330ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_SVG_LOADER_H__ #define __CHICLE_SVG_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleSvgLoader ChicleSvgLoader; ChicleSvgLoader *chicle_svg_loader_new_from_mapping (ChicleFileMapping *mapping, gint target_width, gint target_height); void chicle_svg_loader_destroy (ChicleSvgLoader *loader); gboolean chicle_svg_loader_get_is_animation (ChicleSvgLoader *loader); gconstpointer chicle_svg_loader_get_frame_data (ChicleSvgLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_svg_loader_get_frame_delay (ChicleSvgLoader *loader); void chicle_svg_loader_goto_first_frame (ChicleSvgLoader *loader); gboolean chicle_svg_loader_goto_next_frame (ChicleSvgLoader *loader); G_END_DECLS #endif /* __SVG_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-tiff-loader.c000066400000000000000000000213751517447374300206630ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "chicle-tiff-loader.h" /* ----------------------- * * Global macros and types * * ----------------------- */ #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) struct ChicleTiffLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gpointer frame_data; gint width, height; ChafaPixelType pixel_type; toff_t file_pos; }; /* ----------- * * TIFF loader * * ----------- */ /* --- Memory source --- */ static tsize_t my_tiff_read (thandle_t obj, tdata_t buffer, tsize_t size) { ChicleTiffLoader *loader = (ChicleTiffLoader *) obj; size = CLAMP (size, 0, (tsize_t) loader->file_data_len - (tsize_t) loader->file_pos); memcpy (buffer, loader->file_data + loader->file_pos, size); loader->file_pos += size; return size; } static tsize_t my_tiff_write (G_GNUC_UNUSED thandle_t obj, G_GNUC_UNUSED tdata_t buffer, G_GNUC_UNUSED tsize_t size) { return 0; } static int my_tiff_close (G_GNUC_UNUSED thandle_t obj) { return 0; } static toff_t my_tiff_seek (thandle_t obj, toff_t pos, int whence) { ChicleTiffLoader *loader = (ChicleTiffLoader *) obj; if (whence == SEEK_SET) { loader->file_pos = pos; } else if (whence == SEEK_CUR) { /* Since toff_t is unsigned, we can't seek backwards */ loader->file_pos += pos; } else /* whence == SEEK_END */ { /* Since toff_t is unsigned, this is all we can do */ loader->file_pos = loader->file_data_len; } loader->file_pos = MIN (loader->file_pos, loader->file_data_len); return loader->file_pos; } static toff_t my_tiff_size (thandle_t obj) { ChicleTiffLoader *loader = (ChicleTiffLoader *) obj; return loader->file_data_len; } static int my_tiff_map (thandle_t obj, void **base, toff_t *len) { ChicleTiffLoader *loader = (ChicleTiffLoader *) obj; /* When the TIFFMap delegate is non-NULL, libtiff will use it preferentially. * * Our map is read-only, while base points to non-const. Fingers crossed * libtiff doesn't actually try to write to it during read operations. * * The int cast prevents a warning from -Wcast-qual. */ *base = (void *)(intptr_t) loader->file_data; *len = loader->file_data_len; return 0; } static void my_tiff_unmap (G_GNUC_UNUSED thandle_t obj, G_GNUC_UNUSED void *base, G_GNUC_UNUSED toff_t len) { } /* --- Error handlers --- */ static void my_tiff_error_handler (G_GNUC_UNUSED const char *module, G_GNUC_UNUSED const char *format, G_GNUC_UNUSED va_list ap) { } static void my_tiff_warning_handler (G_GNUC_UNUSED const char *module, G_GNUC_UNUSED const char *format, G_GNUC_UNUSED va_list ap) { } /* --- Loader --- */ #define STDTIFF_HEADER_VERSION 42 #define BIGTIFF_HEADER_VERSION 43 static gboolean have_tiff_magic (ChicleFileMapping *mapping, gchar tiff_version) { gchar magic_le [4] = { 'I', 'I', 0, 0 }; gchar magic_be [4] = { 'M', 'M', 0, 0 }; magic_le [2] = tiff_version; magic_be [3] = tiff_version; return chicle_file_mapping_has_magic (mapping, 0, magic_le, 4) || chicle_file_mapping_has_magic (mapping, 0, magic_be, 4); } static ChicleTiffLoader * chicle_tiff_loader_new (void) { return g_new0 (ChicleTiffLoader, 1); } ChicleTiffLoader * chicle_tiff_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleTiffLoader *loader = NULL; gboolean success = FALSE; gpointer frame_data = NULL; TIFF *tiff = NULL; gint samples_per_pixel = 4; uint32_t width, height; g_return_val_if_fail (mapping != NULL, NULL); if (!(have_tiff_magic (mapping, STDTIFF_HEADER_VERSION) || have_tiff_magic (mapping, BIGTIFF_HEADER_VERSION))) goto out; loader = chicle_tiff_loader_new (); loader->mapping = mapping; /* Get file data */ loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; /* Prepare to decode */ TIFFSetErrorHandler (my_tiff_error_handler); TIFFSetWarningHandler (my_tiff_warning_handler); tiff = TIFFClientOpen ("Memory", "r", (thandle_t) loader, my_tiff_read, my_tiff_write, my_tiff_seek, my_tiff_close, my_tiff_size, my_tiff_map, my_tiff_unmap); if (!tiff) goto out; if (!TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width)) goto out; if (!TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height)) goto out; if (!TIFFGetField (tiff, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel)) goto out; if (width < 1 || width > (1 << 28) || height < 1 || height > (1 << 28) || (width * (guint64) height * BYTES_PER_PIXEL > IMAGE_BUFFER_SIZE_MAX)) goto out; /* An opaque image with unassociated alpha set to 0xff is equivalent to * premultiplied alpha. This will speed up resampling later on. * * For an opaque image, samples_per_pixel will typically be 1 or 3. Other * values may indicate there's an alpha channel -- in those cases, we look * for an EXTRASAMPLES field, and if it doesn't explicitly specify * premultiplied alpha, we fail safe to unassociated alpha. */ loader->pixel_type = CHAFA_PIXEL_RGBA8_PREMULTIPLIED; if (samples_per_pixel == 2 || samples_per_pixel >= 4) { const uint16_t *extra_samples = NULL; uint16_t n_extra_samples = 0; if (TIFFGetField (tiff, TIFFTAG_EXTRASAMPLES, &n_extra_samples, &extra_samples) && n_extra_samples >= 1 && extra_samples && extra_samples [0] != EXTRASAMPLE_ASSOCALPHA) loader->pixel_type = CHAFA_PIXEL_RGBA8_UNASSOCIATED; } frame_data = _TIFFmalloc (width * height * (guint64) BYTES_PER_PIXEL); if (!frame_data) goto out; /* Decode and rotate the image */ if (!TIFFReadRGBAImageOriented (tiff, width, height, (uint32_t *) frame_data, ORIENTATION_TOPLEFT, 0)) goto out; /* Finish up */ loader->width = width; loader->height = height; loader->frame_data = frame_data; success = TRUE; out: if (tiff) TIFFClose (tiff); if (!success) { if (frame_data) _TIFFfree (frame_data); if (loader) { g_free (loader); loader = NULL; } } return loader; } void chicle_tiff_loader_destroy (ChicleTiffLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); if (loader->frame_data) _TIFFfree (loader->frame_data); g_free (loader); } gboolean chicle_tiff_loader_get_is_animation (ChicleTiffLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return FALSE; } gconstpointer chicle_tiff_loader_get_frame_data (ChicleTiffLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) *pixel_type_out = loader->pixel_type; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->width * BYTES_PER_PIXEL; return loader->frame_data; } gint chicle_tiff_loader_get_frame_delay (ChicleTiffLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return 0; } void chicle_tiff_loader_goto_first_frame (ChicleTiffLoader *loader) { g_return_if_fail (loader != NULL); } gboolean chicle_tiff_loader_goto_next_frame (ChicleTiffLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); return FALSE; } chafa-1.18.2/tools/chafa/chicle-tiff-loader.h000066400000000000000000000035311517447374300206620ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_TIFF_LOADER_H__ #define __CHICLE_TIFF_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleTiffLoader ChicleTiffLoader; ChicleTiffLoader *chicle_tiff_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_tiff_loader_destroy (ChicleTiffLoader *loader); gboolean chicle_tiff_loader_get_is_animation (ChicleTiffLoader *loader); gconstpointer chicle_tiff_loader_get_frame_data (ChicleTiffLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_tiff_loader_get_frame_delay (ChicleTiffLoader *loader); void chicle_tiff_loader_goto_first_frame (ChicleTiffLoader *loader); gboolean chicle_tiff_loader_goto_next_frame (ChicleTiffLoader *loader); G_END_DECLS #endif /* __CHICLE_TIFF_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-util.c000066400000000000000000000256651517447374300174520ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include "chicle-util.h" #define CHAR_BUF_SIZE 1024 #define ROWSTRIDE_ALIGN 16 #define PAD_TO_N(p, n) (((p) + ((n) - 1)) & ~((unsigned) (n) - 1)) #define ROWSTRIDE_PAD(rowstride) (PAD_TO_N ((rowstride), (ROWSTRIDE_ALIGN))) static void transform (const guchar *src, gint src_pixstride, gint src_rowstride, guchar *dest, gint dest_pixstride, gint dest_rowstride, gint src_width, gint src_height, gint pixsize) { const guchar *src_row = src; const guchar *src_row_end = src + src_pixstride * src_width; const guchar *src_end = src + src_rowstride * src_height; guchar *dest_row = dest; while (src_row != src_end) { src = src_row; dest = dest_row; while (src != src_row_end) { memcpy (dest, src, pixsize); src += src_pixstride; dest += dest_pixstride; } src_row += src_rowstride; src_row_end += src_rowstride; dest_row += dest_rowstride; } } ChicleRotationType chicle_invert_rotation (ChicleRotationType rot) { switch (rot) { case CHICLE_ROTATION_90: rot = CHICLE_ROTATION_270; break; case CHICLE_ROTATION_270: rot = CHICLE_ROTATION_90; break; default: break; } return rot; } void chicle_rotate_image (gpointer *src, guint *width, guint *height, guint *rowstride, guint n_channels, ChicleRotationType rot) { gint src_width, src_height; gint src_pixstride, src_rowstride; guchar *dest, *dest_start; gint dest_width, dest_height; gint dest_pixstride, dest_rowstride, dest_trans_rowstride; g_assert (n_channels == 3 || n_channels == 4); if (rot <= CHICLE_ROTATION_NONE || rot == CHICLE_ROTATION_0 || rot >= CHICLE_ROTATION_UNDEFINED) return; src_width = *width; src_height = *height; src_pixstride = n_channels; src_rowstride = *rowstride; switch (rot) { case CHICLE_ROTATION_90: case CHICLE_ROTATION_90_MIRROR: case CHICLE_ROTATION_270: case CHICLE_ROTATION_270_MIRROR: dest_width = src_height; dest_height = src_width; break; case CHICLE_ROTATION_0_MIRROR: case CHICLE_ROTATION_180: case CHICLE_ROTATION_180_MIRROR: dest_width = src_width; dest_height = src_height; break; default: g_assert_not_reached (); } dest_rowstride = ROWSTRIDE_PAD (dest_width * n_channels); dest = g_malloc (dest_rowstride * dest_height); switch (rot) { case CHICLE_ROTATION_0_MIRROR: dest_pixstride = -n_channels; dest_trans_rowstride = dest_rowstride; dest_start = dest + ((dest_width - 1) * n_channels); break; case CHICLE_ROTATION_90: dest_pixstride = dest_rowstride; dest_trans_rowstride = -n_channels; dest_start = dest + ((dest_width - 1) * n_channels); break; case CHICLE_ROTATION_90_MIRROR: dest_pixstride = -dest_rowstride; dest_trans_rowstride = -n_channels; dest_start = dest + ((dest_height - 1) * dest_rowstride) + ((dest_width - 1) * n_channels); break; case CHICLE_ROTATION_180: dest_pixstride = -n_channels; dest_trans_rowstride = -dest_rowstride; dest_start = dest + ((dest_height - 1) * dest_rowstride) + ((dest_width - 1) * n_channels); break; case CHICLE_ROTATION_180_MIRROR: dest_pixstride = n_channels; dest_trans_rowstride = -dest_rowstride; dest_start = dest + ((dest_height - 1) * dest_rowstride); break; case CHICLE_ROTATION_270: dest_pixstride = -dest_rowstride; dest_trans_rowstride = n_channels; dest_start = dest + ((dest_height - 1) * dest_rowstride); break; case CHICLE_ROTATION_270_MIRROR: dest_pixstride = dest_rowstride; dest_trans_rowstride = n_channels; dest_start = dest; break; default: g_assert_not_reached (); } transform (*src, src_pixstride, src_rowstride, dest_start, dest_pixstride, dest_trans_rowstride, src_width, src_height, n_channels); g_free (*src); *src = dest; *width = dest_width; *height = dest_height; *rowstride = dest_rowstride; } /* Replaces control characters (C0: U+0000..U+001F, U+007F; C1: * U+0080..U+009F) with '?' so attacker-controlled input cannot inject * terminal escape sequences when this string is later printed to a * terminal. Handles three cases: * * - ASCII control bytes (single-byte): Replace the byte. * - Valid UTF-8 representations of C1 controls (e.g. U+009B encoded * as 0xC2 0x9B): Replace every byte of the encoded sequence. * - Invalid UTF-8 bytes (stray continuation bytes, truncated * sequences, overlong encodings): Replace each invalid byte and * advance one byte at a time. */ void chicle_flatten_cntrl_inplace (gchar *str) { gchar *p, *t; gssize len; len = strlen (str); for (p = str; *p; ) { gunichar c; if ((guchar) *p < 0x80) { /* Single-byte: ASCII or ASCII control */ if ((guchar) *p < 0x20 || *p == 0x7f) *p = '?'; p++; len--; continue; } /* Multi-byte or invalid lead. Validate. */ c = g_utf8_get_char_validated (p, len); if (c == (gunichar) -1 || c == (gunichar) -2) { /* Invalid UTF-8 sequence at this byte. Replace just this byte * and advance by one to resync. */ *(p++) = '?'; len--; continue; } if (g_unichar_iscntrl (c)) { gchar *next = g_utf8_next_char (p); /* Valid UTF-8 control codepoint (typically C1). Replace all * bytes of the encoded sequence to neutralize trailing * continuation bytes that themselves match terminal control * codes (e.g. 0x9B). */ while (p < next) { *(p++) = '?'; len--; } continue; } /* Valid, non-control codepoint: leave it alone. */ t = g_utf8_next_char (p); len -= t - p; p = t; } } gchar * chicle_ellipsize_string (const gchar *str, gint len_max, gboolean use_unicode) { const gchar *p; gchar *ellipsized; gint i, j; if (!str || len_max <= 0) return g_strdup (""); for (p = str, i = 0; *p && i < len_max; i++) { p = g_utf8_next_char (p); } j = p - str; if (*p && !*g_utf8_next_char (p)) return g_strdup (str); ellipsized = g_malloc (j + 7); memcpy (ellipsized, str, j); if (*p) { if (use_unicode) { /* U+2026, Unicode ellipsis */ j += g_unichar_to_utf8 (0x2026, ellipsized + j); } else { *(ellipsized + (j++)) = '>'; } } *(ellipsized + j) = '\0'; return ellipsized; } gchar * chicle_path_get_ellipsized_basename (const gchar *path, gint len_max, gboolean use_unicode) { gchar *basename; gchar *ellipsized; if (len_max <= 0) return g_strdup (""); if (!path) return g_strdup ("?"); basename = g_path_get_basename (path); chicle_flatten_cntrl_inplace (basename); ellipsized = chicle_ellipsize_string (basename, len_max, use_unicode); g_free (basename); return ellipsized; } void chicle_print_rep_char (ChafaTerm *term, gchar c, gint n) { gchar buf_s [CHAR_BUF_SIZE]; gchar *buf_m = NULL; gchar *buf = buf_s; gint i; if (n > CHAR_BUF_SIZE) { buf_m = g_malloc (n); buf = buf_m; } for (i = 0; i < n; i++) buf [i] = c; chafa_term_write (term, buf, n); g_free (buf_m); } static void print_linked_label (ChafaTerm *term, const gchar *path, const gchar *label, gboolean link_label) { gchar *link_str = NULL; if (link_label) { gchar *abs_path = NULL; if (!g_path_is_absolute (path)) abs_path = g_canonicalize_filename (path, NULL); link_str = g_strdup_printf ("file://%s%s", g_get_host_name (), abs_path ? abs_path : path); g_free (abs_path); } if (link_str) { chafa_term_print_seq (term, CHAFA_TERM_SEQ_BEGIN_HYPERLINK, -1); chafa_term_write (term, link_str, strlen (link_str)); chafa_term_print_seq (term, CHAFA_TERM_SEQ_BEGIN_HYPERLINK_ANCHOR, -1); chafa_term_write (term, label, strlen (label)); chafa_term_print_seq (term, CHAFA_TERM_SEQ_END_HYPERLINK, -1); g_free (link_str); } else { chafa_term_write (term, label, strlen (label)); } } void chicle_path_print_label (ChafaTerm *term, const gchar *path, ChafaAlign halign, gint field_width, gboolean use_unicode, gboolean link_label) { gchar *label = chicle_path_get_ellipsized_basename (path, field_width - 1, use_unicode); gchar *sanitized_path; gint label_len = g_utf8_strlen (label, -1); sanitized_path = g_strdup (path); chicle_flatten_cntrl_inplace (sanitized_path); if (halign == CHAFA_ALIGN_START) { print_linked_label (term, sanitized_path, label, link_label); chicle_print_rep_char (term, ' ', field_width - label_len); } else if (halign == CHAFA_ALIGN_CENTER) { chicle_print_rep_char (term, ' ', (field_width - label_len) / 2); print_linked_label (term, sanitized_path, label, link_label); chicle_print_rep_char (term, ' ', (field_width - label_len + 1) / 2); } else { chicle_print_rep_char (term, ' ', field_width - label_len); print_linked_label (term, sanitized_path, label, link_label); } g_free (label); g_free (sanitized_path); } chafa-1.18.2/tools/chafa/chicle-util.h000066400000000000000000000041721517447374300174450ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_UTIL_H__ #define __CHICLE_UTIL_H__ #include #include "chafa-term.h" G_BEGIN_DECLS typedef enum { CHICLE_ROTATION_NONE = 0, CHICLE_ROTATION_0 = 1, CHICLE_ROTATION_0_MIRROR = 2, CHICLE_ROTATION_180 = 3, CHICLE_ROTATION_180_MIRROR = 4, CHICLE_ROTATION_270_MIRROR = 5, CHICLE_ROTATION_270 = 6, CHICLE_ROTATION_90_MIRROR = 7, CHICLE_ROTATION_90 = 8, CHICLE_ROTATION_UNDEFINED = 9, CHICLE_ROTATION_MAX } ChicleRotationType; ChicleRotationType chicle_invert_rotation (ChicleRotationType rot); void chicle_rotate_image (gpointer *src, guint *width, guint *height, guint *rowstride, guint n_channels, ChicleRotationType rot); void chicle_flatten_cntrl_inplace (gchar *str); gchar *chicle_ellipsize_string (const gchar *str, gint len_max, gboolean use_unicode); gchar *chicle_path_get_ellipsized_basename (const gchar *path, gint len_max, gboolean use_unicode); void chicle_print_rep_char (ChafaTerm *term, gchar c, gint n); void chicle_path_print_label (ChafaTerm *term, const gchar *path, ChafaAlign halign, gint field_width, gboolean use_unicode, gboolean link_label); G_END_DECLS #endif /* __CHICLE_UTIL_H__ */ chafa-1.18.2/tools/chafa/chicle-webp-loader.c000066400000000000000000000165411517447374300206670ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "chicle-webp-loader.h" #define DEFAULT_FRAME_DURATION_MS 50 #define BYTES_PER_PIXEL 4 #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) struct ChicleWebpLoader { ChicleFileMapping *mapping; const guint8 *file_data; size_t file_data_len; gint width, height; ChafaPixelType pixel_type; WebPAnimDecoder *anim_dec; gpointer this_frame_data, next_frame_data; gint this_timestamp, next_timestamp; guint is_animation : 1; }; static gboolean decode_next_frame (ChicleWebpLoader *loader, uint8_t **buf, int *timestamp) { return WebPAnimDecoderGetNext (loader->anim_dec, buf, timestamp); } static gboolean maybe_decode_frame (ChicleWebpLoader *loader) { uint8_t *buf; if (loader->this_frame_data) return TRUE; if (decode_next_frame (loader, &buf, &loader->this_timestamp)) { loader->this_frame_data = g_memdup (buf, loader->width * BYTES_PER_PIXEL * loader->height); } return loader->this_frame_data ? TRUE : FALSE; } static ChicleWebpLoader * chicle_webp_loader_new (void) { return g_new0 (ChicleWebpLoader, 1); } ChicleWebpLoader * chicle_webp_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleWebpLoader *loader = NULL; gboolean success = FALSE; WebPBitstreamFeatures features; WebPAnimDecoderOptions anim_dec_options; WebPData webp_data; WebPAnimInfo anim_info; g_return_val_if_fail (mapping != NULL, NULL); /* Basic validation and info extraction */ if (!chicle_file_mapping_has_magic (mapping, 0, "RIFF", 4) || !chicle_file_mapping_has_magic (mapping, 8, "WEBP", 4)) goto out; loader = chicle_webp_loader_new (); loader->mapping = mapping; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) goto out; if (!WebPGetInfo (loader->file_data, loader->file_data_len, &features.width, &features.height)) goto out; if (WebPGetFeatures (loader->file_data, loader->file_data_len, &features) != VP8_STATUS_OK) goto out; /* Set up the animation decoder */ webp_data.bytes = loader->file_data; webp_data.size = loader->file_data_len; WebPAnimDecoderOptionsInit (&anim_dec_options); anim_dec_options.color_mode = MODE_RGBA; anim_dec_options.use_threads = TRUE; loader->anim_dec = WebPAnimDecoderNew (&webp_data, &anim_dec_options); if (!loader->anim_dec) goto out; /* Get animation info and validate */ if (!WebPAnimDecoderGetInfo (loader->anim_dec, &anim_info)) goto out; if (anim_info.canvas_width < 1 || anim_info.canvas_width >= (1 << 28) || anim_info.canvas_height < 1 || anim_info.canvas_height >= (1 << 28) || (anim_info.canvas_width * (guint64) anim_info.canvas_height * BYTES_PER_PIXEL > IMAGE_BUFFER_SIZE_MAX)) goto out; if (anim_info.frame_count < 1) goto out; /* Store parameters */ if (anim_info.frame_count > 1) loader->is_animation = TRUE; loader->width = anim_info.canvas_width; loader->height = anim_info.canvas_height; /* An opaque image with unassociated alpha set to 0xff is equivalent to * premultiplied alpha. This will speed up resampling later on. */ loader->pixel_type = features.has_alpha ? CHAFA_PIXEL_RGBA8_UNASSOCIATED : CHAFA_PIXEL_RGBA8_PREMULTIPLIED; /* Ensure we can decode a frame. If not, we'll try other loaders */ if (!maybe_decode_frame (loader)) return NULL; success = TRUE; out: if (!success) { if (loader) { g_free (loader); loader = NULL; } } return loader; } void chicle_webp_loader_destroy (ChicleWebpLoader *loader) { if (loader->anim_dec) WebPAnimDecoderDelete (loader->anim_dec); if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); g_free (loader->this_frame_data); loader->this_frame_data = NULL; g_free (loader->next_frame_data); loader->next_frame_data = NULL; g_free (loader); } gboolean chicle_webp_loader_get_is_animation (ChicleWebpLoader *loader) { g_return_val_if_fail (loader != NULL, 0); return loader->is_animation; } gconstpointer chicle_webp_loader_get_frame_data (ChicleWebpLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (!maybe_decode_frame (loader)) return NULL; if (pixel_type_out) *pixel_type_out = loader->pixel_type; if (width_out) *width_out = loader->width; if (height_out) *height_out = loader->height; if (rowstride_out) *rowstride_out = loader->width * BYTES_PER_PIXEL; return loader->this_frame_data; } gint chicle_webp_loader_get_frame_delay (ChicleWebpLoader *loader) { uint8_t *buf; g_return_val_if_fail (loader != NULL, 0); /* The libwebp API complicates this a little. We need to load the next frame * in advance to know how long to hold this frame. */ maybe_decode_frame (loader); if (!loader->next_frame_data) { if (decode_next_frame (loader, &buf, &loader->next_timestamp)) { loader->next_frame_data = g_memdup (buf, loader->width * BYTES_PER_PIXEL * loader->height); } } return loader->next_frame_data ? (loader->next_timestamp - loader->this_timestamp) : DEFAULT_FRAME_DURATION_MS; } void chicle_webp_loader_goto_first_frame (ChicleWebpLoader *loader) { g_return_if_fail (loader != NULL); WebPAnimDecoderReset (loader->anim_dec); g_free (loader->this_frame_data); loader->this_frame_data = NULL; g_free (loader->next_frame_data); loader->next_frame_data = NULL; } gboolean chicle_webp_loader_goto_next_frame (ChicleWebpLoader *loader) { g_return_val_if_fail (loader != NULL, FALSE); g_free (loader->this_frame_data); loader->this_frame_data = loader->next_frame_data; loader->next_frame_data = NULL; if (loader->this_frame_data) { loader->this_timestamp = loader->next_timestamp; return TRUE; } return WebPAnimDecoderHasMoreFrames (loader->anim_dec) ? TRUE : FALSE; } chafa-1.18.2/tools/chafa/chicle-webp-loader.h000066400000000000000000000035311517447374300206670ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_WEBP_LOADER_H__ #define __CHICLE_WEBP_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleWebpLoader ChicleWebpLoader; ChicleWebpLoader *chicle_webp_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_webp_loader_destroy (ChicleWebpLoader *loader); gboolean chicle_webp_loader_get_is_animation (ChicleWebpLoader *loader); gconstpointer chicle_webp_loader_get_frame_data (ChicleWebpLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_webp_loader_get_frame_delay (ChicleWebpLoader *loader); void chicle_webp_loader_goto_first_frame (ChicleWebpLoader *loader); gboolean chicle_webp_loader_goto_next_frame (ChicleWebpLoader *loader); G_END_DECLS #endif /* __CHICLE_WEBP_LOADER_H__ */ chafa-1.18.2/tools/chafa/chicle-xwd-loader.c000066400000000000000000000265341517447374300205370ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "chicle-xwd-loader.h" #define DEBUG(x) #define IMAGE_BUFFER_SIZE_MAX (0xffffffffU >> 2) typedef struct { guint32 header_size; /* Size of the header in bytes */ guint32 file_version; /* X11WD file version (always 07h) */ guint32 pixmap_format; /* Pixmap format */ guint32 pixmap_depth; /* Pixmap depth in pixels */ guint32 pixmap_width; /* Pixmap width in pixels */ guint32 pixmap_height; /* Pixmap height in pixels */ guint32 x_offset; /* Bitmap X offset */ guint32 byte_order; /* Byte order of image data */ guint32 bitmap_unit; /* Bitmap base data size */ guint32 bitmap_bit_order; /* Bit-order of image data */ guint32 bitmap_pad; /* Bitmap scan-line pad*/ guint32 bits_per_pixel; /* Bits per pixel */ guint32 bytes_per_line; /* Bytes per scan-line */ guint32 visual_class; /* Class of the image */ guint32 red_mask; /* Red mask */ guint32 green_mask; /* Green mask */ guint32 blue_mask; /* Blue mask */ guint32 bits_per_rgb; /* Size of each color mask in bits */ guint32 n_colors; /* Number of colors in image */ guint32 color_map_entries; /* Number of entries in color map */ guint32 window_width; /* Window width */ guint32 window_height; /* Window height */ gint32 window_x; /* Window upper left X coordinate */ gint32 window_y; /* Window upper left Y coordinate */ guint32 window_border_width; /* Window border width */ } XwdHeader; typedef struct { guint32 pixel; guint16 red; guint16 green; guint16 blue; guint8 flags; guint8 pad; } XwdColor; struct ChicleXwdLoader { ChicleFileMapping *mapping; gconstpointer file_data; gconstpointer image_data; gsize file_data_len; XwdHeader header; }; DEBUG ( static void dump_header (XwdHeader *header) { g_printerr ("Header size: %u\n" "File version: %u\n" "Pixmap format: %u\n" "Pixmap depth: %u\n" "Pixmap width: %u\n" "Pixmap height: %u\n" "X offset: %u\n" "Byte order: %u\n" "Bitmap unit: %u\n" "Bitmap bit order: %u\n" "Bitmap pad: %u\n" "Bits per pixel: %u\n" "Bytes per line: %u\n" "Visual class: %u\n" "Red mask: %u\n" "Green mask: %u\n" "Blue mask: %u\n" "Bits per RGB: %u\n" "Number of colors: %u\n" "Color map entries: %u\n" "Window width: %u\n" "Window height: %u\n" "Window X: %d\n" "Window Y: %d\n" "Window border width: %u\n---\n", header->header_size, header->file_version, header->pixmap_format, header->pixmap_depth, header->pixmap_width, header->pixmap_height, header->x_offset, header->byte_order, header->bitmap_unit, header->bitmap_bit_order, header->bitmap_pad, header->bits_per_pixel, header->bytes_per_line, header->visual_class, header->red_mask, header->green_mask, header->blue_mask, header->bits_per_rgb, header->n_colors, header->color_map_entries, header->window_width, header->window_height, header->window_x, header->window_y, header->window_border_width); } ) static ChafaPixelType compute_pixel_type (ChicleXwdLoader *loader) { XwdHeader *h = &loader->header; if (h->bits_per_pixel == 24) { if (h->byte_order == 0) return CHAFA_PIXEL_BGR8; else return CHAFA_PIXEL_RGB8; } if (h->bits_per_pixel == 32) { if (h->byte_order == 0) return CHAFA_PIXEL_BGRA8_PREMULTIPLIED; else return CHAFA_PIXEL_ARGB8_PREMULTIPLIED; } return CHAFA_PIXEL_MAX; } #define ASSERT_HEADER(x) if (!(x)) return FALSE #define UNPACK_FIELD_U32(dest, src, field) ((dest)->field = GUINT32_FROM_BE ((src)->field)) #define UNPACK_FIELD_S32(dest, src, field) ((dest)->field = GINT32_FROM_BE ((src)->field)) static gboolean load_header (ChicleXwdLoader *loader) { XwdHeader *h = &loader->header; XwdHeader in; const XwdHeader *inp; if (!chicle_file_mapping_taste (loader->mapping, &in, 0, sizeof (in))) return FALSE; inp = ∈ UNPACK_FIELD_U32 (h, inp, header_size); UNPACK_FIELD_U32 (h, inp, file_version); UNPACK_FIELD_U32 (h, inp, pixmap_format); UNPACK_FIELD_U32 (h, inp, pixmap_depth); UNPACK_FIELD_U32 (h, inp, pixmap_width); UNPACK_FIELD_U32 (h, inp, pixmap_height); UNPACK_FIELD_U32 (h, inp, x_offset); UNPACK_FIELD_U32 (h, inp, byte_order); UNPACK_FIELD_U32 (h, inp, bitmap_unit); UNPACK_FIELD_U32 (h, inp, bitmap_bit_order); UNPACK_FIELD_U32 (h, inp, bitmap_pad); UNPACK_FIELD_U32 (h, inp, bits_per_pixel); UNPACK_FIELD_U32 (h, inp, bytes_per_line); UNPACK_FIELD_U32 (h, inp, visual_class); UNPACK_FIELD_U32 (h, inp, red_mask); UNPACK_FIELD_U32 (h, inp, green_mask); UNPACK_FIELD_U32 (h, inp, blue_mask); UNPACK_FIELD_U32 (h, inp, bits_per_rgb); UNPACK_FIELD_U32 (h, inp, color_map_entries); UNPACK_FIELD_U32 (h, inp, n_colors); UNPACK_FIELD_U32 (h, inp, window_width); UNPACK_FIELD_U32 (h, inp, window_height); UNPACK_FIELD_S32 (h, inp, window_x); UNPACK_FIELD_S32 (h, inp, window_y); UNPACK_FIELD_U32 (h, inp, window_border_width); /* Only support the most common/useful subset of XWD files out there; * namely, that corresponding to screen dumps from modern X.Org servers. * We could check visual_class == 5 too, but the other fields convey all * the info we need. */ ASSERT_HEADER (h->header_size >= sizeof (XwdHeader)); ASSERT_HEADER (h->header_size <= 65535); ASSERT_HEADER (h->file_version == 7); ASSERT_HEADER (h->pixmap_depth == 24); /* Should be zero for truecolor/directcolor. Cap it to prevent overflows. */ ASSERT_HEADER (h->color_map_entries <= 256); /* Xvfb sets bits_per_rgb to 8, but 'convert' uses 24 for the same image data. One * of them is likely misunderstanding. Let's be lenient and accept either. */ ASSERT_HEADER (h->bits_per_rgb == 8 || h->bits_per_rgb == 24); /* These are the pixel formats we allow. */ ASSERT_HEADER (h->bits_per_pixel == 24 || h->bits_per_pixel == 32); /* Enforce sane dimensions. */ ASSERT_HEADER (h->pixmap_width >= 1 && h->pixmap_width <= 65535); ASSERT_HEADER (h->pixmap_height >= 1 && h->pixmap_height <= 65535); /* Make sure rowstride can actually hold a row's worth of data but is not padded to * something ridiculous. */ ASSERT_HEADER (h->bytes_per_line >= h->pixmap_width * (h->bits_per_pixel / 8)); ASSERT_HEADER (h->bytes_per_line <= h->pixmap_width * (h->bits_per_pixel / 8) + 1024); /* If each pixel is four bytes, reject unaligned rowstrides */ ASSERT_HEADER (h->bits_per_pixel != 32 || h->bytes_per_line % 4 == 0); /* Make sure the total allocation/map is not too big. */ ASSERT_HEADER ((gsize) h->bytes_per_line * h->pixmap_height < (1UL << 31) - 65536 - 256 * 32); ASSERT_HEADER (compute_pixel_type (loader) < CHAFA_PIXEL_MAX); if (h->pixmap_height * (gsize) h->bytes_per_line > IMAGE_BUFFER_SIZE_MAX) return FALSE; loader->file_data = chicle_file_mapping_get_data (loader->mapping, &loader->file_data_len); if (!loader->file_data) return FALSE; ASSERT_HEADER (loader->file_data_len >= h->header_size + h->color_map_entries * sizeof (XwdColor) + h->pixmap_height * (gsize) h->bytes_per_line); loader->image_data = (const guint8 *) loader->file_data + h->header_size + h->color_map_entries * sizeof (XwdColor); return TRUE; } static ChicleXwdLoader * chicle_xwd_loader_new (void) { return g_new0 (ChicleXwdLoader, 1); } ChicleXwdLoader * chicle_xwd_loader_new_from_mapping (ChicleFileMapping *mapping) { ChicleXwdLoader *loader = NULL; gboolean success = FALSE; g_return_val_if_fail (mapping != NULL, NULL); loader = chicle_xwd_loader_new (); loader->mapping = mapping; if (!load_header (loader)) { g_free (loader); return NULL; } DEBUG (dump_header (&loader->header)); if (loader->header.pixmap_width < 1 || loader->header.pixmap_width >= (1 << 28) || loader->header.pixmap_height < 1 || loader->header.pixmap_height >= (1 << 28) || (loader->header.pixmap_width * (guint64) loader->header.pixmap_height >= (1 << 29))) goto out; success = TRUE; out: if (!success) { g_free (loader); loader = NULL; } return loader; } void chicle_xwd_loader_destroy (ChicleXwdLoader *loader) { if (loader->mapping) chicle_file_mapping_destroy (loader->mapping); g_free (loader); } gboolean chicle_xwd_loader_get_is_animation (G_GNUC_UNUSED ChicleXwdLoader *loader) { return FALSE; } gconstpointer chicle_xwd_loader_get_frame_data (ChicleXwdLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out) { g_return_val_if_fail (loader != NULL, NULL); if (pixel_type_out) *pixel_type_out = compute_pixel_type (loader); if (width_out) *width_out = loader->header.pixmap_width; if (height_out) *height_out = loader->header.pixmap_height; if (rowstride_out) *rowstride_out = loader->header.bytes_per_line; return loader->image_data; } gint chicle_xwd_loader_get_frame_delay (G_GNUC_UNUSED ChicleXwdLoader *loader) { return 0; } void chicle_xwd_loader_goto_first_frame (G_GNUC_UNUSED ChicleXwdLoader *loader) { } gboolean chicle_xwd_loader_goto_next_frame (G_GNUC_UNUSED ChicleXwdLoader *loader) { return FALSE; } chafa-1.18.2/tools/chafa/chicle-xwd-loader.h000066400000000000000000000035021517447374300205320ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #ifndef __CHICLE_XWD_LOADER_H__ #define __CHICLE_XWD_LOADER_H__ #include #include "chicle-file-mapping.h" G_BEGIN_DECLS typedef struct ChicleXwdLoader ChicleXwdLoader; ChicleXwdLoader *chicle_xwd_loader_new_from_mapping (ChicleFileMapping *mapping); void chicle_xwd_loader_destroy (ChicleXwdLoader *loader); gboolean chicle_xwd_loader_get_is_animation (ChicleXwdLoader *loader); gconstpointer chicle_xwd_loader_get_frame_data (ChicleXwdLoader *loader, ChafaPixelType *pixel_type_out, gint *width_out, gint *height_out, gint *rowstride_out); gint chicle_xwd_loader_get_frame_delay (ChicleXwdLoader *loader); void chicle_xwd_loader_goto_first_frame (ChicleXwdLoader *loader); gboolean chicle_xwd_loader_goto_next_frame (ChicleXwdLoader *loader); G_END_DECLS #endif /* __CHICLE_XWD_LOADER_H__ */ chafa-1.18.2/tools/chafa/ibm-platform.c000066400000000000000000000311321517447374300176230ustar00rootroot00000000000000/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2018-2025 Hans Petter Jansson * * This file is part of Chafa, a program that shows pictures on text terminals. * * Chafa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chafa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Chafa. If not, see . */ #define UNICODE_UNDEF 0 typedef struct { gint c; gunichar u; } CodeMap; /* It's better to keep a single entry per line, since it leaves room for annotation. * Also, maintaining tabular layouts is a pita even when we don't have out-there * Unicode characters messing up the formatting. */ static const CodeMap cp437_codes [] = { { 0x20, 0x0020 }, /* SPACE */ { 0x21, 0x0021 }, /* EXCLAMATION MARK */ { 0x22, 0x0022 }, /* QUOTATION MARK */ { 0x23, 0x0023 }, /* NUMBER SIGN */ { 0x24, 0x0024 }, /* DOLLAR SIGN */ { 0x25, 0x0025 }, /* PERCENT SIGN */ { 0x26, 0x0026 }, /* AMPERSAND */ { 0x27, 0x0027 }, /* APOSTROPHE */ { 0x28, 0x0028 }, /* LEFT PARENTHESIS */ { 0x29, 0x0029 }, /* RIGHT PARENTHESIS */ { 0x2a, 0x002a }, /* ASTERISK */ { 0x2b, 0x002b }, /* PLUS SIGN */ { 0x2c, 0x002c }, /* COMMA */ { 0x2d, 0x002d }, /* HYPHEN-MINUS */ { 0x2e, 0x002e }, /* FULL STOP */ { 0x2f, 0x002f }, /* SOLIDUS */ { 0x30, 0x0030 }, /* DIGIT ZERO */ { 0x31, 0x0031 }, /* DIGIT ONE */ { 0x32, 0x0032 }, /* DIGIT TWO */ { 0x33, 0x0033 }, /* DIGIT THREE */ { 0x34, 0x0034 }, /* DIGIT FOUR */ { 0x35, 0x0035 }, /* DIGIT FIVE */ { 0x36, 0x0036 }, /* DIGIT SIX */ { 0x37, 0x0037 }, /* DIGIT SEVEN */ { 0x38, 0x0038 }, /* DIGIT EIGHT */ { 0x39, 0x0039 }, /* DIGIT NINE */ { 0x3a, 0x003a }, /* COLON */ { 0x3b, 0x003b }, /* SEMICOLON */ { 0x3c, 0x003c }, /* LESS-THAN SIGN */ { 0x3d, 0x003d }, /* EQUALS SIGN */ { 0x3e, 0x003e }, /* GREATER-THAN SIGN */ { 0x3f, 0x003f }, /* QUESTION MARK */ { 0x40, 0x0040 }, /* COMMERCIAL AT */ { 0x41, 0x0041 }, /* LATIN CAPITAL LETTER A */ { 0x42, 0x0042 }, /* LATIN CAPITAL LETTER B */ { 0x43, 0x0043 }, /* LATIN CAPITAL LETTER C */ { 0x44, 0x0044 }, /* LATIN CAPITAL LETTER D */ { 0x45, 0x0045 }, /* LATIN CAPITAL LETTER E */ { 0x46, 0x0046 }, /* LATIN CAPITAL LETTER F */ { 0x47, 0x0047 }, /* LATIN CAPITAL LETTER G */ { 0x48, 0x0048 }, /* LATIN CAPITAL LETTER H */ { 0x49, 0x0049 }, /* LATIN CAPITAL LETTER I */ { 0x4a, 0x004a }, /* LATIN CAPITAL LETTER J */ { 0x4b, 0x004b }, /* LATIN CAPITAL LETTER K */ { 0x4c, 0x004c }, /* LATIN CAPITAL LETTER L */ { 0x4d, 0x004d }, /* LATIN CAPITAL LETTER M */ { 0x4e, 0x004e }, /* LATIN CAPITAL LETTER N */ { 0x4f, 0x004f }, /* LATIN CAPITAL LETTER O */ { 0x50, 0x0050 }, /* LATIN CAPITAL LETTER P */ { 0x51, 0x0051 }, /* LATIN CAPITAL LETTER Q */ { 0x52, 0x0052 }, /* LATIN CAPITAL LETTER R */ { 0x53, 0x0053 }, /* LATIN CAPITAL LETTER S */ { 0x54, 0x0054 }, /* LATIN CAPITAL LETTER T */ { 0x55, 0x0055 }, /* LATIN CAPITAL LETTER U */ { 0x56, 0x0056 }, /* LATIN CAPITAL LETTER V */ { 0x57, 0x0057 }, /* LATIN CAPITAL LETTER W */ { 0x58, 0x0058 }, /* LATIN CAPITAL LETTER X */ { 0x59, 0x0059 }, /* LATIN CAPITAL LETTER Y */ { 0x5a, 0x005a }, /* LATIN CAPITAL LETTER Z */ { 0x5b, 0x005b }, /* LEFT SQUARE BRACKET */ { 0x5c, 0x005c }, /* REVERSE SOLIDUS */ { 0x5d, 0x005d }, /* RIGHT SQUARE BRACKET */ { 0x5e, 0x005e }, /* CIRCUMFLEX ACCENT */ { 0x5f, 0x005f }, /* LOW LINE */ { 0x60, 0x0060 }, /* GRAVE ACCENT */ { 0x61, 0x0061 }, /* LATIN SMALL LETTER A */ { 0x62, 0x0062 }, /* LATIN SMALL LETTER B */ { 0x63, 0x0063 }, /* LATIN SMALL LETTER C */ { 0x64, 0x0064 }, /* LATIN SMALL LETTER D */ { 0x65, 0x0065 }, /* LATIN SMALL LETTER E */ { 0x66, 0x0066 }, /* LATIN SMALL LETTER F */ { 0x67, 0x0067 }, /* LATIN SMALL LETTER G */ { 0x68, 0x0068 }, /* LATIN SMALL LETTER H */ { 0x69, 0x0069 }, /* LATIN SMALL LETTER I */ { 0x6a, 0x006a }, /* LATIN SMALL LETTER J */ { 0x6b, 0x006b }, /* LATIN SMALL LETTER K */ { 0x6c, 0x006c }, /* LATIN SMALL LETTER L */ { 0x6d, 0x006d }, /* LATIN SMALL LETTER M */ { 0x6e, 0x006e }, /* LATIN SMALL LETTER N */ { 0x6f, 0x006f }, /* LATIN SMALL LETTER O */ { 0x70, 0x0070 }, /* LATIN SMALL LETTER P */ { 0x71, 0x0071 }, /* LATIN SMALL LETTER Q */ { 0x72, 0x0072 }, /* LATIN SMALL LETTER R */ { 0x73, 0x0073 }, /* LATIN SMALL LETTER S */ { 0x74, 0x0074 }, /* LATIN SMALL LETTER T */ { 0x75, 0x0075 }, /* LATIN SMALL LETTER U */ { 0x76, 0x0076 }, /* LATIN SMALL LETTER V */ { 0x77, 0x0077 }, /* LATIN SMALL LETTER W */ { 0x78, 0x0078 }, /* LATIN SMALL LETTER X */ { 0x79, 0x0079 }, /* LATIN SMALL LETTER Y */ { 0x7a, 0x007a }, /* LATIN SMALL LETTER Z */ { 0x7b, 0x007b }, /* LEFT CURLY BRACKET */ { 0x7c, 0x007c }, /* VERTICAL LINE */ { 0x7d, 0x007d }, /* RIGHT CURLY BRACKET */ { 0x7e, 0x007e }, /* TILDE */ { 0x80, 0x00c7 }, /* LATIN CAPITAL LETTER C WITH CEDILLA */ { 0x81, 0x00fc }, /* LATIN SMALL LETTER U WITH DIAERESIS */ { 0x82, 0x00e9 }, /* LATIN SMALL LETTER E WITH ACUTE */ { 0x83, 0x00e2 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX */ { 0x84, 0x00e4 }, /* LATIN SMALL LETTER A WITH DIAERESIS */ { 0x85, 0x00e0 }, /* LATIN SMALL LETTER A WITH GRAVE */ { 0x86, 0x00e5 }, /* LATIN SMALL LETTER A WITH RING ABOVE */ { 0x87, 0x00e7 }, /* LATIN SMALL LETTER C WITH CEDILLA */ { 0x88, 0x00ea }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX */ { 0x89, 0x00eb }, /* LATIN SMALL LETTER E WITH DIAERESIS */ { 0x8a, 0x00e8 }, /* LATIN SMALL LETTER E WITH GRAVE */ { 0x8b, 0x00ef }, /* LATIN SMALL LETTER I WITH DIAERESIS */ { 0x8c, 0x00ee }, /* LATIN SMALL LETTER I WITH CIRCUMFLEX */ { 0x8d, 0x00ec }, /* LATIN SMALL LETTER I WITH GRAVE */ { 0x8e, 0x00c4 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS */ { 0x8f, 0x00c5 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE */ { 0x90, 0x00c9 }, /* LATIN CAPITAL LETTER E WITH ACUTE */ { 0x91, 0x00e6 }, /* LATIN SMALL LIGATURE AE */ { 0x92, 0x00c6 }, /* LATIN CAPITAL LIGATURE AE */ { 0x93, 0x00f4 }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX */ { 0x94, 0x00f6 }, /* LATIN SMALL LETTER O WITH DIAERESIS */ { 0x95, 0x00f2 }, /* LATIN SMALL LETTER O WITH GRAVE */ { 0x96, 0x00fb }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX */ { 0x97, 0x00f9 }, /* LATIN SMALL LETTER U WITH GRAVE */ { 0x98, 0x00ff }, /* LATIN SMALL LETTER Y WITH DIAERESIS */ { 0x99, 0x00d6 }, /* LATIN CAPITAL LETTER O WITH DIAERESIS */ { 0x9a, 0x00dc }, /* LATIN CAPITAL LETTER U WITH DIAERESIS */ { 0x9b, 0x00a2 }, /* CENT SIGN */ { 0x9c, 0x00a3 }, /* POUND SIGN */ { 0x9d, 0x00a5 }, /* YEN SIGN */ { 0x9e, 0x20a7 }, /* PESETA SIGN */ { 0x9f, 0x0192 }, /* LATIN SMALL LETTER F WITH HOOK */ { 0xa0, 0x00e1 }, /* LATIN SMALL LETTER A WITH ACUTE */ { 0xa1, 0x00ed }, /* LATIN SMALL LETTER I WITH ACUTE */ { 0xa2, 0x00f3 }, /* LATIN SMALL LETTER O WITH ACUTE */ { 0xa3, 0x00fa }, /* LATIN SMALL LETTER U WITH ACUTE */ { 0xa4, 0x00f1 }, /* LATIN SMALL LETTER N WITH TILDE */ { 0xa5, 0x00d1 }, /* LATIN CAPITAL LETTER N WITH TILDE */ { 0xa6, 0x00aa }, /* FEMININE ORDINAL INDICATOR */ { 0xa7, 0x00ba }, /* MASCULINE ORDINAL INDICATOR */ { 0xa8, 0x00bf }, /* INVERTED QUESTION MARK */ { 0xa9, 0x2310 }, /* REVERSED NOT SIGN */ { 0xaa, 0x00ac }, /* NOT SIGN */ { 0xab, 0x00bd }, /* VULGAR FRACTION ONE HALF */ { 0xac, 0x00bc }, /* VULGAR FRACTION ONE QUARTER */ { 0xad, 0x00a1 }, /* INVERTED EXCLAMATION MARK */ { 0xae, 0x00ab }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ { 0xaf, 0x00bb }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ { 0xb0, 0x2591 }, /* LIGHT SHADE */ { 0xb1, 0x2592 }, /* MEDIUM SHADE */ { 0xb2, 0x2593 }, /* DARK SHADE */ { 0xb3, 0x2502 }, /* BOX DRAWINGS LIGHT VERTICAL */ { 0xb4, 0x2524 }, /* BOX DRAWINGS LIGHT VERTICAL AND LEFT */ { 0xb5, 0x2561 }, /* BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE */ { 0xb6, 0x2562 }, /* BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE */ { 0xb7, 0x2556 }, /* BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE */ { 0xb8, 0x2555 }, /* BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE */ { 0xb9, 0x2563 }, /* BOX DRAWINGS DOUBLE VERTICAL AND LEFT */ { 0xba, 0x2551 }, /* BOX DRAWINGS DOUBLE VERTICAL */ { 0xbb, 0x2557 }, /* BOX DRAWINGS DOUBLE DOWN AND LEFT */ { 0xbc, 0x255d }, /* BOX DRAWINGS DOUBLE UP AND LEFT */ { 0xbd, 0x255c }, /* BOX DRAWINGS UP DOUBLE AND LEFT SINGLE */ { 0xbe, 0x255b }, /* BOX DRAWINGS UP SINGLE AND LEFT DOUBLE */ { 0xbf, 0x2510 }, /* BOX DRAWINGS LIGHT DOWN AND LEFT */ { 0xc0, 0x2514 }, /* BOX DRAWINGS LIGHT UP AND RIGHT */ { 0xc1, 0x2534 }, /* BOX DRAWINGS LIGHT UP AND HORIZONTAL */ { 0xc2, 0x252c }, /* BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ { 0xc3, 0x251c }, /* BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ { 0xc4, 0x2500 }, /* BOX DRAWINGS LIGHT HORIZONTAL */ { 0xc5, 0x253c }, /* BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ { 0xc6, 0x255e }, /* BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE */ { 0xc7, 0x255f }, /* BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE */ { 0xc8, 0x255a }, /* BOX DRAWINGS DOUBLE UP AND RIGHT */ { 0xc9, 0x2554 }, /* BOX DRAWINGS DOUBLE DOWN AND RIGHT */ { 0xca, 0x2569 }, /* BOX DRAWINGS DOUBLE UP AND HORIZONTAL */ { 0xcb, 0x2566 }, /* BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL */ { 0xcc, 0x2560 }, /* BOX DRAWINGS DOUBLE VERTICAL AND RIGHT */ { 0xcd, 0x2550 }, /* BOX DRAWINGS DOUBLE HORIZONTAL */ { 0xce, 0x256c }, /* BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL */ { 0xcf, 0x2567 }, /* BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE */ { 0xd0, 0x2568 }, /* BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE */ { 0xd1, 0x2564 }, /* BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE */ { 0xd2, 0x2565 }, /* BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE */ { 0xd3, 0x2559 }, /* BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE */ { 0xd4, 0x2558 }, /* BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE */ { 0xd5, 0x2552 }, /* BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE */ { 0xd6, 0x2553 }, /* BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE */ { 0xd7, 0x256b }, /* BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE */ { 0xd8, 0x256a }, /* BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE */ { 0xd9, 0x2518 }, /* BOX DRAWINGS LIGHT UP AND LEFT */ { 0xda, 0x250c }, /* BOX DRAWINGS LIGHT DOWN AND RIGHT */ { 0xdb, 0x2588 }, /* FULL BLOCK */ { 0xdc, 0x2584 }, /* LOWER HALF BLOCK */ { 0xdd, 0x258c }, /* LEFT HALF BLOCK */ { 0xde, 0x2590 }, /* RIGHT HALF BLOCK */ { 0xdf, 0x2580 }, /* UPPER HALF BLOCK */ { 0xe0, 0x03b1 }, /* GREEK SMALL LETTER ALPHA */ { 0xe1, 0x00df }, /* LATIN SMALL LETTER SHARP S */ { 0xe2, 0x0393 }, /* GREEK CAPITAL LETTER GAMMA */ { 0xe3, 0x03c0 }, /* GREEK SMALL LETTER PI */ { 0xe4, 0x03a3 }, /* GREEK CAPITAL LETTER SIGMA */ { 0xe5, 0x03c3 }, /* GREEK SMALL LETTER SIGMA */ { 0xe6, 0x00b5 }, /* MICRO SIGN */ { 0xe7, 0x03c4 }, /* GREEK SMALL LETTER TAU */ { 0xe8, 0x03a6 }, /* GREEK CAPITAL LETTER PHI */ { 0xe9, 0x0398 }, /* GREEK CAPITAL LETTER THETA */ { 0xea, 0x03a9 }, /* GREEK CAPITAL LETTER OMEGA */ { 0xeb, 0x03b4 }, /* GREEK SMALL LETTER DELTA */ { 0xec, 0x221e }, /* INFINITY */ { 0xed, 0x03c6 }, /* GREEK SMALL LETTER PHI */ { 0xee, 0x03b5 }, /* GREEK SMALL LETTER EPSILON */ { 0xef, 0x2229 }, /* INTERSECTION */ { 0xf0, 0x2261 }, /* IDENTICAL TO */ { 0xf1, 0x00b1 }, /* PLUS-MINUS SIGN */ { 0xf2, 0x2265 }, /* GREATER-THAN OR EQUAL TO */ { 0xf3, 0x2264 }, /* LESS-THAN OR EQUAL TO */ { 0xf4, 0x2320 }, /* TOP HALF INTEGRAL */ { 0xf5, 0x2321 }, /* BOTTOM HALF INTEGRAL */ { 0xf6, 0x00f7 }, /* DIVISION SIGN */ { 0xf7, 0x2248 }, /* ALMOST EQUAL TO */ { 0xf8, 0x00b0 }, /* DEGREE SIGN */ { 0xf9, 0x2219 }, /* BULLET OPERATOR */ { 0xfa, 0x00b7 }, /* MIDDLE DOT */ { 0xfb, 0x221a }, /* SQUARE ROOT */ { 0xfc, 0x207f }, /* SUPERSCRIPT LATIN SMALL LETTER N */ { 0xfd, 0x00b2 }, /* SUPERSCRIPT TWO */ { 0xfe, 0x25a0 }, /* BLACK SQUARE */ { -1, 0 } }; chafa-1.18.2/tools/chafa/manifest.rc000066400000000000000000000001221517447374300172150ustar00rootroot00000000000000#include CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "ms-utf8.xml" chafa-1.18.2/tools/chafa/ms-utf8.xml000066400000000000000000000006071517447374300171160ustar00rootroot00000000000000 UTF-8 chafa-1.18.2/tools/chafa/qoi.h000066400000000000000000000442741517447374300160420ustar00rootroot00000000000000/* Copyright (c) 2021, Dominic Szablewski - https://phoboslab.org SPDX-License-Identifier: MIT QOI - The "Quite OK Image" format for fast, lossless image compression -- About QOI encodes and decodes images in a lossless format. Compared to stb_image and stb_image_write QOI offers 20x-50x faster encoding, 3x-4x faster decoding and 20% better compression. -- Synopsis // Define `QOI_IMPLEMENTATION` in *one* C/C++ file before including this // library to create the implementation. #define QOI_IMPLEMENTATION #include "qoi.h" // Encode and store an RGBA buffer to the file system. The qoi_desc describes // the input pixel data. qoi_write("image_new.qoi", rgba_pixels, &(qoi_desc){ .width = 1920, .height = 1080, .channels = 4, .colorspace = QOI_SRGB }); // Load and decode a QOI image from the file system into a 32bbp RGBA buffer. // The qoi_desc struct will be filled with the width, height, number of channels // and colorspace read from the file header. qoi_desc desc; void *rgba_pixels = qoi_read("image.qoi", &desc, 4); -- Documentation This library provides the following functions; - qoi_read -- read and decode a QOI file - qoi_decode -- decode the raw bytes of a QOI image from memory - qoi_write -- encode and write a QOI file - qoi_encode -- encode an rgba buffer into a QOI image in memory See the function declaration below for the signature and more information. If you don't want/need the qoi_read and qoi_write functions, you can define QOI_NO_STDIO before including this library. This library uses malloc() and free(). To supply your own malloc implementation you can define QOI_MALLOC and QOI_FREE before including this library. This library uses memset() to zero-initialize the index. To supply your own implementation you can define QOI_ZEROARR before including this library. -- Data Format A QOI file has a 14 byte header, followed by any number of data "chunks" and an 8-byte end marker. struct qoi_header_t { char magic[4]; // magic bytes "qoif" uint32_t width; // image width in pixels (BE) uint32_t height; // image height in pixels (BE) uint8_t channels; // 3 = RGB, 4 = RGBA uint8_t colorspace; // 0 = sRGB with linear alpha, 1 = all channels linear }; Images are encoded row by row, left to right, top to bottom. The decoder and encoder start with {r: 0, g: 0, b: 0, a: 255} as the previous pixel value. An image is complete when all pixels specified by width * height have been covered. Pixels are encoded as - a run of the previous pixel - an index into an array of previously seen pixels - a difference to the previous pixel value in r,g,b - full r,g,b or r,g,b,a values The color channels are assumed to not be premultiplied with the alpha channel ("un-premultiplied alpha"). A running array[64] (zero-initialized) of previously seen pixel values is maintained by the encoder and decoder. Each pixel that is seen by the encoder and decoder is put into this array at the position formed by a hash function of the color value. In the encoder, if the pixel value at the index matches the current pixel, this index position is written to the stream as QOI_OP_INDEX. The hash function for the index is: index_position = (r * 3 + g * 5 + b * 7 + a * 11) % 64 Each chunk starts with a 2- or 8-bit tag, followed by a number of data bits. The bit length of chunks is divisible by 8 - i.e. all chunks are byte aligned. All values encoded in these data bits have the most significant bit on the left. The 8-bit tags have precedence over the 2-bit tags. A decoder must check for the presence of an 8-bit tag first. The byte stream's end is marked with 7 0x00 bytes followed a single 0x01 byte. The possible chunks are: .- QOI_OP_INDEX ----------. | Byte[0] | | 7 6 5 4 3 2 1 0 | |-------+-----------------| | 0 0 | index | `-------------------------` 2-bit tag b00 6-bit index into the color index array: 0..63 A valid encoder must not issue 2 or more consecutive QOI_OP_INDEX chunks to the same index. QOI_OP_RUN should be used instead. .- QOI_OP_DIFF -----------. | Byte[0] | | 7 6 5 4 3 2 1 0 | |-------+-----+-----+-----| | 0 1 | dr | dg | db | `-------------------------` 2-bit tag b01 2-bit red channel difference from the previous pixel between -2..1 2-bit green channel difference from the previous pixel between -2..1 2-bit blue channel difference from the previous pixel between -2..1 The difference to the current channel values are using a wraparound operation, so "1 - 2" will result in 255, while "255 + 1" will result in 0. Values are stored as unsigned integers with a bias of 2. E.g. -2 is stored as 0 (b00). 1 is stored as 3 (b11). The alpha value remains unchanged from the previous pixel. .- QOI_OP_LUMA -------------------------------------. | Byte[0] | Byte[1] | | 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 | |-------+-----------------+-------------+-----------| | 1 0 | green diff | dr - dg | db - dg | `---------------------------------------------------` 2-bit tag b10 6-bit green channel difference from the previous pixel -32..31 4-bit red channel difference minus green channel difference -8..7 4-bit blue channel difference minus green channel difference -8..7 The green channel is used to indicate the general direction of change and is encoded in 6 bits. The red and blue channels (dr and db) base their diffs off of the green channel difference and are encoded in 4 bits. I.e.: dr_dg = (cur_px.r - prev_px.r) - (cur_px.g - prev_px.g) db_dg = (cur_px.b - prev_px.b) - (cur_px.g - prev_px.g) The difference to the current channel values are using a wraparound operation, so "10 - 13" will result in 253, while "250 + 7" will result in 1. Values are stored as unsigned integers with a bias of 32 for the green channel and a bias of 8 for the red and blue channel. The alpha value remains unchanged from the previous pixel. .- QOI_OP_RUN ------------. | Byte[0] | | 7 6 5 4 3 2 1 0 | |-------+-----------------| | 1 1 | run | `-------------------------` 2-bit tag b11 6-bit run-length repeating the previous pixel: 1..62 The run-length is stored with a bias of -1. Note that the run-lengths 63 and 64 (b111110 and b111111) are illegal as they are occupied by the QOI_OP_RGB and QOI_OP_RGBA tags. .- QOI_OP_RGB ------------------------------------------. | Byte[0] | Byte[1] | Byte[2] | Byte[3] | | 7 6 5 4 3 2 1 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | |-------------------------+---------+---------+---------| | 1 1 1 1 1 1 1 0 | red | green | blue | `-------------------------------------------------------` 8-bit tag b11111110 8-bit red channel value 8-bit green channel value 8-bit blue channel value The alpha value remains unchanged from the previous pixel. .- QOI_OP_RGBA ---------------------------------------------------. | Byte[0] | Byte[1] | Byte[2] | Byte[3] | Byte[4] | | 7 6 5 4 3 2 1 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | 7 .. 0 | |-------------------------+---------+---------+---------+---------| | 1 1 1 1 1 1 1 1 | red | green | blue | alpha | `-----------------------------------------------------------------` 8-bit tag b11111111 8-bit red channel value 8-bit green channel value 8-bit blue channel value 8-bit alpha channel value */ /* ----------------------------------------------------------------------------- Header - Public functions */ #ifndef QOI_H #define QOI_H #ifdef __cplusplus extern "C" { #endif /* A pointer to a qoi_desc struct has to be supplied to all of qoi's functions. It describes either the input format (for qoi_write and qoi_encode), or is filled with the description read from the file header (for qoi_read and qoi_decode). The colorspace in this qoi_desc is an enum where 0 = sRGB, i.e. gamma scaled RGB channels and a linear alpha channel 1 = all channels are linear You may use the constants QOI_SRGB or QOI_LINEAR. The colorspace is purely informative. It will be saved to the file header, but does not affect how chunks are en-/decoded. */ #define QOI_SRGB 0 #define QOI_LINEAR 1 typedef struct { unsigned int width; unsigned int height; unsigned char channels; unsigned char colorspace; } qoi_desc; #ifndef QOI_NO_STDIO /* Encode raw RGB or RGBA pixels into a QOI image and write it to the file system. The qoi_desc struct must be filled with the image width, height, number of channels (3 = RGB, 4 = RGBA) and the colorspace. The function returns 0 on failure (invalid parameters, or fopen or malloc failed) or the number of bytes written on success. */ int qoi_write(const char *filename, const void *data, const qoi_desc *desc); /* Read and decode a QOI image from the file system. If channels is 0, the number of channels from the file header is used. If channels is 3 or 4 the output format will be forced into this number of channels. The function either returns NULL on failure (invalid data, or malloc or fopen failed) or a pointer to the decoded pixels. On success, the qoi_desc struct will be filled with the description from the file header. The returned pixel data should be free()d after use. */ void *qoi_read(const char *filename, qoi_desc *desc, int channels); #endif /* QOI_NO_STDIO */ /* Encode raw RGB or RGBA pixels into a QOI image in memory. The function either returns NULL on failure (invalid parameters or malloc failed) or a pointer to the encoded data on success. On success the out_len is set to the size in bytes of the encoded data. The returned qoi data should be free()d after use. */ void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len); /* Decode a QOI image from memory. The function either returns NULL on failure (invalid parameters or malloc failed) or a pointer to the decoded pixels. On success, the qoi_desc struct is filled with the description from the file header. The returned pixel data should be free()d after use. */ void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels); #ifdef __cplusplus } #endif #endif /* QOI_H */ /* ----------------------------------------------------------------------------- Implementation */ #ifdef QOI_IMPLEMENTATION #include #include #ifndef QOI_MALLOC #define QOI_MALLOC(sz) malloc(sz) #define QOI_FREE(p) free(p) #endif #ifndef QOI_ZEROARR #define QOI_ZEROARR(a) memset((a),0,sizeof(a)) #endif #define QOI_OP_INDEX 0x00 /* 00xxxxxx */ #define QOI_OP_DIFF 0x40 /* 01xxxxxx */ #define QOI_OP_LUMA 0x80 /* 10xxxxxx */ #define QOI_OP_RUN 0xc0 /* 11xxxxxx */ #define QOI_OP_RGB 0xfe /* 11111110 */ #define QOI_OP_RGBA 0xff /* 11111111 */ #define QOI_MASK_2 0xc0 /* 11000000 */ #define QOI_COLOR_HASH(C) (C.rgba.r*3 + C.rgba.g*5 + C.rgba.b*7 + C.rgba.a*11) #define QOI_MAGIC \ (((unsigned int)'q') << 24 | ((unsigned int)'o') << 16 | \ ((unsigned int)'i') << 8 | ((unsigned int)'f')) #define QOI_HEADER_SIZE 14 /* 2GB is the max file size that this implementation can safely handle. We guard against anything larger than that, assuming the worst case with 5 bytes per pixel, rounded down to a nice clean value. 400 million pixels ought to be enough for anybody. */ #define QOI_PIXELS_MAX ((unsigned int)400000000) typedef union { struct { unsigned char r, g, b, a; } rgba; unsigned int v; } qoi_rgba_t; static const unsigned char qoi_padding[8] = {0,0,0,0,0,0,0,1}; static void qoi_write_32(unsigned char *bytes, int *p, unsigned int v) { bytes[(*p)++] = (0xff000000 & v) >> 24; bytes[(*p)++] = (0x00ff0000 & v) >> 16; bytes[(*p)++] = (0x0000ff00 & v) >> 8; bytes[(*p)++] = (0x000000ff & v); } static unsigned int qoi_read_32(const unsigned char *bytes, int *p) { unsigned int a = bytes[(*p)++]; unsigned int b = bytes[(*p)++]; unsigned int c = bytes[(*p)++]; unsigned int d = bytes[(*p)++]; return a << 24 | b << 16 | c << 8 | d; } void *qoi_encode(const void *data, const qoi_desc *desc, int *out_len) { int i, max_size, p, run; int px_len, px_end, px_pos, channels; unsigned char *bytes; const unsigned char *pixels; qoi_rgba_t index[64]; qoi_rgba_t px, px_prev; if ( data == NULL || out_len == NULL || desc == NULL || desc->width == 0 || desc->height == 0 || desc->channels < 3 || desc->channels > 4 || desc->colorspace > 1 || desc->height >= QOI_PIXELS_MAX / desc->width ) { return NULL; } max_size = desc->width * desc->height * (desc->channels + 1) + QOI_HEADER_SIZE + sizeof(qoi_padding); p = 0; bytes = (unsigned char *) QOI_MALLOC(max_size); if (!bytes) { return NULL; } qoi_write_32(bytes, &p, QOI_MAGIC); qoi_write_32(bytes, &p, desc->width); qoi_write_32(bytes, &p, desc->height); bytes[p++] = desc->channels; bytes[p++] = desc->colorspace; pixels = (const unsigned char *)data; QOI_ZEROARR(index); run = 0; px_prev.rgba.r = 0; px_prev.rgba.g = 0; px_prev.rgba.b = 0; px_prev.rgba.a = 255; px = px_prev; px_len = desc->width * desc->height * desc->channels; px_end = px_len - desc->channels; channels = desc->channels; for (px_pos = 0; px_pos < px_len; px_pos += channels) { px.rgba.r = pixels[px_pos + 0]; px.rgba.g = pixels[px_pos + 1]; px.rgba.b = pixels[px_pos + 2]; if (channels == 4) { px.rgba.a = pixels[px_pos + 3]; } if (px.v == px_prev.v) { run++; if (run == 62 || px_pos == px_end) { bytes[p++] = QOI_OP_RUN | (run - 1); run = 0; } } else { int index_pos; if (run > 0) { bytes[p++] = QOI_OP_RUN | (run - 1); run = 0; } index_pos = QOI_COLOR_HASH(px) % 64; if (index[index_pos].v == px.v) { bytes[p++] = QOI_OP_INDEX | index_pos; } else { index[index_pos] = px; if (px.rgba.a == px_prev.rgba.a) { signed char vr = px.rgba.r - px_prev.rgba.r; signed char vg = px.rgba.g - px_prev.rgba.g; signed char vb = px.rgba.b - px_prev.rgba.b; signed char vg_r = vr - vg; signed char vg_b = vb - vg; if ( vr > -3 && vr < 2 && vg > -3 && vg < 2 && vb > -3 && vb < 2 ) { bytes[p++] = QOI_OP_DIFF | (vr + 2) << 4 | (vg + 2) << 2 | (vb + 2); } else if ( vg_r > -9 && vg_r < 8 && vg > -33 && vg < 32 && vg_b > -9 && vg_b < 8 ) { bytes[p++] = QOI_OP_LUMA | (vg + 32); bytes[p++] = (vg_r + 8) << 4 | (vg_b + 8); } else { bytes[p++] = QOI_OP_RGB; bytes[p++] = px.rgba.r; bytes[p++] = px.rgba.g; bytes[p++] = px.rgba.b; } } else { bytes[p++] = QOI_OP_RGBA; bytes[p++] = px.rgba.r; bytes[p++] = px.rgba.g; bytes[p++] = px.rgba.b; bytes[p++] = px.rgba.a; } } } px_prev = px; } for (i = 0; i < (int)sizeof(qoi_padding); i++) { bytes[p++] = qoi_padding[i]; } *out_len = p; return bytes; } void *qoi_decode(const void *data, int size, qoi_desc *desc, int channels) { const unsigned char *bytes; unsigned int header_magic; unsigned char *pixels; qoi_rgba_t index[64]; qoi_rgba_t px; int px_len, chunks_len, px_pos; int p = 0, run = 0; if ( data == NULL || desc == NULL || (channels != 0 && channels != 3 && channels != 4) || size < QOI_HEADER_SIZE + (int)sizeof(qoi_padding) ) { return NULL; } bytes = (const unsigned char *)data; header_magic = qoi_read_32(bytes, &p); desc->width = qoi_read_32(bytes, &p); desc->height = qoi_read_32(bytes, &p); desc->channels = bytes[p++]; desc->colorspace = bytes[p++]; if ( desc->width == 0 || desc->height == 0 || desc->channels < 3 || desc->channels > 4 || desc->colorspace > 1 || header_magic != QOI_MAGIC || desc->height >= QOI_PIXELS_MAX / desc->width || /* hpj: The following avoids slow decode on crafted files, * and Chafa doesn't handle bigger images anyway */ desc->width > 65535 || desc->height > 65535 || /* hpj: This vetoes image buffers bigger than 1GB */ desc->width * (unsigned long long) desc->height * channels > (0xffffffffU >> 2) ) { return NULL; } if (channels == 0) { channels = desc->channels; } px_len = desc->width * desc->height * channels; pixels = (unsigned char *) QOI_MALLOC(px_len); if (!pixels) { return NULL; } QOI_ZEROARR(index); px.rgba.r = 0; px.rgba.g = 0; px.rgba.b = 0; px.rgba.a = 255; chunks_len = size - (int)sizeof(qoi_padding); for (px_pos = 0; px_pos < px_len; px_pos += channels) { if (run > 0) { run--; } else if (p < chunks_len) { int b1 = bytes[p++]; if (b1 == QOI_OP_RGB) { px.rgba.r = bytes[p++]; px.rgba.g = bytes[p++]; px.rgba.b = bytes[p++]; } else if (b1 == QOI_OP_RGBA) { px.rgba.r = bytes[p++]; px.rgba.g = bytes[p++]; px.rgba.b = bytes[p++]; px.rgba.a = bytes[p++]; } else if ((b1 & QOI_MASK_2) == QOI_OP_INDEX) { px = index[b1]; } else if ((b1 & QOI_MASK_2) == QOI_OP_DIFF) { px.rgba.r += ((b1 >> 4) & 0x03) - 2; px.rgba.g += ((b1 >> 2) & 0x03) - 2; px.rgba.b += ( b1 & 0x03) - 2; } else if ((b1 & QOI_MASK_2) == QOI_OP_LUMA) { int b2 = bytes[p++]; int vg = (b1 & 0x3f) - 32; px.rgba.r += vg - 8 + ((b2 >> 4) & 0x0f); px.rgba.g += vg; px.rgba.b += vg - 8 + (b2 & 0x0f); } else if ((b1 & QOI_MASK_2) == QOI_OP_RUN) { run = (b1 & 0x3f); } index[QOI_COLOR_HASH(px) % 64] = px; } pixels[px_pos + 0] = px.rgba.r; pixels[px_pos + 1] = px.rgba.g; pixels[px_pos + 2] = px.rgba.b; if (channels == 4) { pixels[px_pos + 3] = px.rgba.a; } } return pixels; } #ifndef QOI_NO_STDIO #include int qoi_write(const char *filename, const void *data, const qoi_desc *desc) { FILE *f = fopen(filename, "wb"); int size, err; void *encoded; if (!f) { return 0; } encoded = qoi_encode(data, desc, &size); if (!encoded) { fclose(f); return 0; } fwrite(encoded, 1, size, f); fflush(f); err = ferror(f); fclose(f); QOI_FREE(encoded); return err ? 0 : size; } void *qoi_read(const char *filename, qoi_desc *desc, int channels) { FILE *f = fopen(filename, "rb"); int size, bytes_read; void *pixels, *data; if (!f) { return NULL; } fseek(f, 0, SEEK_END); size = ftell(f); if (size <= 0 || fseek(f, 0, SEEK_SET) != 0) { fclose(f); return NULL; } data = QOI_MALLOC(size); if (!data) { fclose(f); return NULL; } bytes_read = fread(data, 1, size, f); fclose(f); pixels = (bytes_read != size) ? NULL : qoi_decode(data, bytes_read, desc, channels); QOI_FREE(data); return pixels; } #endif /* QOI_NO_STDIO */ #endif /* QOI_IMPLEMENTATION */ chafa-1.18.2/tools/completions/000077500000000000000000000000001517447374300163605ustar00rootroot00000000000000chafa-1.18.2/tools/completions/Makefile.am000066400000000000000000000007711517447374300204210ustar00rootroot00000000000000PREFIX=${datadir} EXTRA_DIST = \ fish-completion.fish \ zsh-completion.zsh \ bash-completion.sh .PHONY: install-zsh-completion install-zsh-completion: install -Dm644 zsh-completion.zsh $(PREFIX)/zsh/site-functions/_chafa .PHONY: install-fish-completion install-fish-completion: install -Dm644 fish-completion.fish $(PREFIX)/fish/vendor_completions.d/chafa.fish .PHONY: install-bash-completion install-bash-completion: install -Dm644 bash-completion.sh $(PREFIX)/bash-completion/completions/chafa chafa-1.18.2/tools/completions/bash-completion.sh000066400000000000000000000044561517447374300220110ustar00rootroot00000000000000_chafa() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--help -h --version -v --verbose --probe --files --files0 --format -f --optimize -O --relative --passthrough --polite --align --clear --center -C --exact-size --fit-width --font-ratio --grid -g --label -l --link --margin-bottom --margin-right --scale --size -s --stretch --view-size --animate --duration -d --speed --watch --bg --colors -c --color-extractor --color-space --dither --dither-grain --dither-intensity --fg --invert --preprocess -p --threshold -t --threads --work -w --fg-only --fill --glyph-file --symbols --dump-detect --fuzz-options --zoom" if [[ ${cur} == -* ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 fi case "${prev}" in --format|-f) COMPREPLY=( $(compgen -W "iterm kitty sixels symbols" -- "${cur}") ) ;; --optimize|-O) COMPREPLY=( $(compgen -W "0 1 2 3 4 5 6 7 8 9" -- "${cur}") ) ;; --relative|--polite|--animate|--preprocess|-p|--center|-C|--label) COMPREPLY=( $(compgen -W "on off" -- "${cur}") ) ;; --passthrough) COMPREPLY=( $(compgen -W "auto none screen tmux" -- "${cur}") ) ;; --exact-size|--link|--probe) COMPREPLY=( $(compgen -W "auto on off" -- "${cur}") ) ;; --grid) COMPREPLY=( $(compgen -W "auto" -- "${cur}") ) ;; --scale) COMPREPLY=( $(compgen -W "max" -- "${cur}") ) ;; --colors|-c) COMPREPLY=( $(compgen -W "none 2 8 16/8 16 240 256 full" -- "${cur}") ) ;; --color-extractor) COMPREPLY=( $(compgen -W "average median" -- "${cur}") ) ;; --color-space) COMPREPLY=( $(compgen -W "rgb din99d" -- "${cur}") ) ;; --dither) COMPREPLY=( $(compgen -W "none ordered diffusion noise" -- "${cur}") ) ;; --fill|--symbols) local symbols="all asci braille extra imported narrow solid ugly alnum bad diagonal geometric inverted none space vhalf alpha block digit half latin quad stipple wedge ambiguous border dot hhalf legacy sextant technical wide" COMPREPLY=( $(compgen -W "${symbols}" -- "${cur}") ) ;; --work|-w) COMPREPLY=( $(compgen -W "1 2 3 4 5 6 7 8 9" -- "${cur}") ) ;; esac return 0 } complete -o default -F _chafa chafa chafa-1.18.2/tools/completions/fish-completion.fish000066400000000000000000000124151517447374300223360ustar00rootroot00000000000000complete -c chafa -e complete -c chafa -l 'files' -x -a '(- _files)' -d 'Read list of files to process from PATH (newline-separated), or "-" for stdin' complete -c chafa -l 'files0' -x -a '(- _files)' -d 'Read list of files to process from PATH (NUL-separated), or "-" for stdin' complete -c chafa -o 'h' -l 'help' -d 'Show help' complete -c chafa -l 'probe' -x -a 'auto on off' -d 'Probe terminal\'s capabilities and wait for response' complete -c chafa -l 'version' -d 'Show version' complete -c chafa -o 'v' -l 'verbose' -d 'Be verbose' complete -c chafa -o 'f' -l 'format' -x -a 'iterm kitty sixels symbols' -d 'Set output format' complete -c chafa -o 'O' -l 'optimize' -x -a "(seq 0 9)" -d 'Compress the output by using control sequences intelligently' complete -c chafa -l 'relative' -x -a 'on off' -d 'Use relative cursor positioning' complete -c chafa -l 'passthrough' -x -a 'auto none screen tmux' -d 'Graphics protocol passthrough' complete -c chafa -l 'polite' -x -a 'on off' -d 'Polite mode' complete -c chafa -l 'align' -x -d 'Horizontal and vertical alignment' complete -c chafa -l 'clear' -d 'Clear screen before processing each file' complete -c chafa -l 'exact-size' -x -a 'auto on off' -d 'Try to match the input\'s size exactly' complete -c chafa -l 'fit-width' -d 'Fit images to view\'s width, possibly exceeding their height' complete -c chafa -l 'font-ratio' -x -d 'Target font\'s width/height ratio' complete -c chafa -l 'grid' -x -a 'auto' -d 'Lay out images in a grid of CxR columns/rows per screenful' complete -c chafa -o 'g' -l 'grid-on' -d 'Alias for "--grid auto"' complete -c chafa -l 'label' -x -a 'on off' -d 'Labeling filenames below images' complete -c chafa -o 'l' -l 'label-on' -d 'Alias for "--label on"' complete -c chafa -l 'link' -x -a 'auto on off' -d 'Turns labels into clickable hyperlinks' complete -c chafa -l 'margin-bottom' -x -d 'Reserve at least NUM rows at the bottom as a safety margin' complete -c chafa -l 'margin-right' -x -d 'Reserve at least NUM columns safety margin on right-hand side' complete -c chafa -l 'scale' -x -d 'Scale image, respecting view\'s dimentions. Specify "max" to fit view' complete -c chafa -o 's' -l 'size' -x -d 'Set maximum image dimensions in columns and rows' complete -c chafa -l 'stretch' -d 'Stretch image to fit output dimentions, ignoring aspect. Implies --scale max' complete -c chafa -l 'view-size' -x -d 'Set the view size in columns and rows' complete -c chafa -l 'animate' -x -a 'on off' -d 'Whether to allow animation' complete -c chafa -s 'd' -l 'duration' -x -d 'How long to show each file' complete -c chafa -l 'speed' -x -d 'Animation speed' complete -c chafa -l 'watch' -d 'Watch a single input file, redisplaying it whenever its contents change' complete -c chafa -l 'bg' -x -d 'Background color of display (color name or hex)' complete -c chafa -l 'colors' -x -a 'none 2 8 16/8 16 240 256 full' -d 'Set output color mode' complete -c chafa -l 'color-extractor' -x -a 'average median' -d 'Method for extracting color from an area' complete -c chafa -l 'color-space' -x -a 'rgb din99d' -d 'Color space used for quantization' complete -c chafa -l 'dither' -x -a 'none ordered diffusion noise' -d 'Set output dither mode' complete -c chafa -l 'dither-grain' -x -d 'Set dimentions of dither grains in 1/8ths of a character cell' complete -c chafa -l 'dither-intensity' -x -d 'Multiplier for dither intensity [0.0 - inf]' complete -c chafa -l 'fg' -x -d 'Foreground color of display (color name or hex)' complete -c chafa -l 'invert' -d 'Swap --fg and --bg' complete -c chafa -s 'p' -l 'preprocess' -x -a 'on off' -d 'Turn on/off image preprocessing' complete -c chafa -s 't' -l 'threshold' -x -d 'Lower threshold for full transparency [0.0 - 1.0]' complete -c chafa -l 'threads' -x -d 'Maximum number of CPU threads to use' complete -c chafa -s 'w' -l 'work' -x -a "(seq 1 9)" -d 'How hard to work in terms of CPU and memory' complete -c chafa -l 'fg-only' -d 'Leave the background color untouched' complete -c chafa -l 'fill' -x -d 'Specify character symbols to use for fill/gradients' complete -c chafa -l 'glyph-file' -r -d 'Load glyph information from FILE' complete -c chafa -l 'symbols' -x -d 'Specify character symbols to employ in final output' chafa-1.18.2/tools/completions/zsh-completion.zsh000066400000000000000000000123161517447374300220640ustar00rootroot00000000000000#compdef chafa local symbols=(all asci braille extra imported narrow solid ugly alnum bad diagonal geometric inverted none space vhalf alpha block digit half latin quad stipple wedge ambiguous border dot hhalf legacy sextant technical wide) local options=( '(- : *)'{-h,--help}"[Show help]" '(- : *)'--version"[Show version]" {-v,--verbose}"[Be verbose]" --align"[Horizontal and vertical alignment]" --animate"[Whether to allow animation. Defaults to on]:BOOL:(on off)" --bg"[Background color of display (color name or hex).]:COLOR" {-C,--center}"[Center images. Defaults to off]:BOOL:(on off)" --clear"[Clear screen before processing each file]" {-c,--colors}"[Set output color mode. Defaults to best guess]:MODE:(none 2 8 16/8 16 240 256 full)" --color-extractor"[Method for extracting color from an area. Average is the default]:EXTR:(average median)" --color-space"[Color space used for quantization. Defaults to rgb, which is faster but less accurate]:CS:(rgb din99d)" --dither"[Set output dither mode. No effect with 24-bit color. Defaults to none]:DITHER:(none ordered diffusion noise)" --dither-grain"[Set dimensions of dither grains in 1/8ths of a character cell. Defaults to 4x4]:WxH:(1 2 4 8)" --dither-intensity"[Multiplier for dither intensity. Defaults to 1.0]:NUM 0.0 - inf" {-d,--duration}"[The time to show each file]:SECONDS" --exact-size"[Try to match the input's size exactly. Defaults to auto]:MODE:(auto on off)" --fg"[Foreground color of display (color name or hex).]:COLOR:(black blue cyan default gray green magenta orange red white)" --fg-only"[Leave the background color untouched]" --files"[Read list of files to process from PATH (newline-separated), or '-' for stdin]:FILE:_files" --files0"[Read list of files to process from PATH (NUL-separated), or '-' for stdin]:FILE:_files" --fill"[Specify character symbols to use for fill/gradients. Defaults to none]:SYMS:($symbols)" --fit-width"[Fit images to view's width, possibly exceeding their height]" --font-ratio"[Target font's width/height ratio. Can be specified as a real number or a fraction. Defaults to 1/2]:W/H" {-f,--format}"[Set output format]:FORMAT:(iterm kitty sixels symbols)" --glyph-file"[Load glyph information from FILE]:FILE:_files" --grid"[Lay out images in a grid of CxR columns/rows per screenful. C or R may be omitted, e.g. '--grid 4'. Can be 'auto']:CxR" {-g,--grid-on}"[Alias for '--grid auto']" --invert"[Invert video. For display with bright backgrounds in color modes 2 and none. Swaps --fg and --bg]" --label"[Labeling filenames below images. Defaults to off]:BOOL:(on off)" {-l,--label-on}"[Alias for '--label on']" --link"[Turns labels into clickable hyperlinks. Use with '--label on'. Defaults to auto]:MODE:(auto on off)" --margin-bottom"[When terminal size is detected, reserve at least NUM rows at the bottom as a safety margin. Can be used to prevent images from scrolling out. Defaults to 1.]:NUM" --margin-right"[When terminal size is detected, reserve at least NUM columns on the right-hand side as a safety margin. Defaults to 0.]:NUM" {-O,--optimize}"[Compress the output by using control sequences. 0 disables, 9 enables every available optimization. Defaults to 5, except for when used with '-c none', where it defaults to 0]:NUM:("{0..9}")" --passthrough"[Graphics protocol passthrough. Defaults to auto]:MODE:(auto none screen tmux)" --polite"[Polite mode. Defaults to on. Turning this off may enhance presentation and prevent interference from other programs, but risks leaving the terminal in an altered state (rude).]:BOOL:(on off)" {-p,--preprocess}"[Image preprocessing. Defaults to on with 16 colors or lower, off otherwise]:BOOL:(on off)" --probe"[Probe terminal's capabilities and wait for response. A positive real number denotes the maximum time to wait for a response, in seconds. Defaults to 5.0]:MODE:(auto on off)" --relative"[Use relative cursor positioning. Defaults to off]:BOOL:(on off)" --scale"[Scale image, respecting terminal's maximum dimensions. 1.0 approximates original pixel dimensions. Specify max to use all available space. Defaults to 1.0 for pixel graphics and 4.0 for symbols]:NUM" {-s,--size}"[Set maximum output dimensions in columns and rows. By default this will be the size of your terminal, or 80x25 if size detection fails]:WxH" --speed"[Set the speed animations will play at. This can be either a unitless multiplier, or a real number followed by fps to apply a specific framerate.]:SPEED" --stretch"[Stretch image to fit output dimensions; ignore aspect. Implies --scale max]" --symbols"[Specify character symbols to employ in final output]:SYMS:($symbols)" --threads"[Maximum number of CPU threads to use. If left unspecified or negative, this will equal available CPU cores]:NUM" {-t,--threshold}"[Threshold above which full transparency will be used 0.0 - 1.0]:NUM" --view-size"[Set the view size in columns and rows]:WxH" --watch"[Watch a single input file, redisplaying it whenever its contents change. Will run until manually interrupted or, if --duration is set, until it expires.]" {-w,--work}"[How hard to work in terms of CPU and memory. 1 is the cheapest, 9 is the most accurate. Defaults to 5]:NUM:("{1..9}")" ) _arguments $options '*:: :_files' chafa-1.18.2/tools/fontgen/000077500000000000000000000000001517447374300154645ustar00rootroot00000000000000chafa-1.18.2/tools/fontgen/Makefile.am000066400000000000000000000000671517447374300175230ustar00rootroot00000000000000EXTRA_DIST = \ README.md \ chafa8x8.py \ compare.py chafa-1.18.2/tools/fontgen/README.md000066400000000000000000000073331517447374300167510ustar00rootroot00000000000000Chafa8x8 Custom Block Font === ## Advantages of this custom font 1. One can read large fonts from images more easily. 2. Very good at dealing with some natural image textures. 3. Higher definition compared to block glyphs in standard Unicode. ## How to build this font 1. Prepare many images, and put them to a folder, e.g. `~/coco/*.jpg`. 2. Create dataset from those images. `./chafa8x8.py CreateDataset --glob "$HOME/coco/*.jpg"`. Note, don't miss the quotes because the wildcard should be expanded by python's `glob` instead of the shell. Although the default parameters should be fine, the optional arguments are: (1) `-Mc ` specifies the number of vectors to sample from each image file. The default is `16`. Namely, in total 16 random crops (converted to vectors) are sampled from each image; (2) `-N ` specifies the vector length. The default is 64 for 8x8 blocks. After this, a fine named `chafa8x8.npz` will be created for the following clustering step. 3. Run K-Means algorithm to find cluster center vectors. `./chafa8x8.py Clustering`. This will create the optimal vectors. The optional parameter `-C ` specifies how many vectors you want (i.e., how many optimal 8x8 blocks you want). The actual usable vectors (glyphs) will be less than this number after post processing (such as deduplication). The results will be stored in `chafa8x8.raw.json` by default. Note, this step is slow. For GPU accelerated computing, see the misc notes in the next section. 4. Post-process. Generate C code, SVG images and TTF font. `./chafa8x8.py GenA`. This is actually a composed command. It executes the following four steps: (1) It invokes `./chafa8x8.py Postproc` to deduplicate the optimal glyphs. The results will be written in `chafa8x8.json`; (2) Then it invokes `./chafa8x8.py GenC` to generate C header from json as `chafa8x8.h`; (3) Next, it invokes `./chafa8x8.py GenSVG` to convert the optimal glyphs from json into SVG files under the `chafa8x8_svg` directory; (4) Lastly, it invokes `./chafa8x8.py GenFont` to create the font file `chafa8x8.ttf` from the json result. ## Misc Notes 1. Python dependencies: `pip3 install numpy scipy scikit-learn tqdm`. 2. Note, in order to generate a usable font, the `python3-fontforge` (for Debian bullseye and newer) package has to be installed as well. It will be used in the `./chafa8x8.py GenA` step. It will automatically invoke `chafa8x8.py GenFont` subcommand for creating the font. 3. Note, the clustering step is the most time-consuming procedure. If the created dataset is very large (e.g., more than 1 million vectors inside), it won't be surprising to run for several hours or even longer. Although the result can be better with a large dataset, the resulting fonts should be good to use as long as, say, the dataset size is more than 10 times larger than the number of optimal glyphs we want. 4. You may take a quick glance at the glyphs from the json files, e.g., for the finalized glyphs: `./chafa8x8.py Dump --json chafa8x8.json | less`, and for the preliminary glyphs before deduplication: `./chafa8x8.py Dump --json chafa8x8.raw.json | less`. 5. The clustering step can be accelerated using Nvidia GPU (through CUDA). You need to install faiss first: `pip3 install faiss-gpu`. To use it, just specify the backend in the command line: `./chafa8x8.py Clustering --backend faiss`. ## Todos - [ ] update `compare.py` with the latest usage. ## Acknowledgement The core algorithm used to generate the glyphs is [K-Means](https://en.wikipedia.org/wiki/K-means_clustering), one of the clustering algorithms in the machine learning literature. You can generate a font by using some image dataset e.g. [MSCOCO](http://cocodataset.org) dataset (research-oriented). ## License Copyright (C) 2018 Mo Zhou, LGPLv3+ chafa-1.18.2/tools/fontgen/chafa8x8.py000077500000000000000000000320061517447374300174540ustar00rootroot00000000000000#!/usr/bin/env python3 # This script is written for Chafa in order to generate custom fonts. # Copyright (C) 2018-2023 Mo Zhou # License: LGPLv3+ import os import sys import argparse import glob try: import ujson as json except ModuleNotFoundError: import json import time import random from PIL import Image from subprocess import call import numpy as np from typing import * # Preserved Unicode Plane for Private use, see wikipedia for detail. UNICODE_BASE = 0x100000 def bdump8x8(v: np.ndarray, *, clang: bool = False, padding: int = 0) -> str: ''' dump the 8x8 bitmap. v: np.ndarray -- the vector (bitmap) to dump clang: bool -- dump C code intead of plain text padding: int -- number of spaces to indent in clang mode ''' assert(v.size == 64) dump = [] for (i, v) in enumerate(v): if i % 8 == 0 and clang: dump.append(' '*padding + "\"") if v: dump.append('X') else: dump.append(' ' if clang else '.') if (i+1) % 8 == 0 and clang: dump.append("\"") if (i+1) % 8 == 0: dump.append('\n') return ''.join(dump) def mainCreateDataset(argv: List[str]): ''' Generate dataset used for generating chafa8x8 font from MS-COCO dataset http://cocodataset.org/ ''' ag = argparse.ArgumentParser() ag.add_argument('--glob', type=str, default='~/coco/*.jpg', help='image file glob pattern to be expanded by python') ag.add_argument('-Mc', type=int, default=16, help='num crops per image') ag.add_argument('-N', type=int, default=64, help='vector length') ag.add_argument('--save', type=str, default='chafa8x8.npz') ag = ag.parse_args(argv) from tqdm import tqdm if not os.path.exists(ag.save): # Glob images images = glob.glob(ag.glob, recursive=True) Mi = len(images) print( f'=> Found {Mi} images. Will sample {ag.Mc} vectors from each image') print(f' -> Dataset size M = {Mi*ag.Mc}') print( f' -> The resulting dataset takes {Mi*ag.Mc*ag.N/(1024**2)} MiB space.') # Sample Mi*Mc vectors as the dataset from those images print(f'=> Sampling vectors from every image ...') dataset = np.zeros((Mi*ag.Mc, ag.N), dtype=np.uint8) for i in tqdm(range(Mi)): image = random.choice(images) image = Image.open(image) width, height = image.size for c in range(ag.Mc): w = random.randrange(16, min(width, height//2, 48)) h = 2*w # ratio: h/w = 2/1 woff = random.randrange(0, width - w) hoff = random.randrange(0, height - h) box = (woff, hoff, woff+w, hoff+h) region = image.crop(box).convert('1') region = region.resize((8, 8)) region = np.array(region).ravel() dataset[i*ag.Mc+c, :] = region # save the dataset as acche np.savez(ag.save, dataset=dataset) else: print(f'=> Dataset already generated: {ag.save}') def mainClustering(argv: List[str]): ''' Run K-Means algorithm on the dataset. For large-scale training, MiniBatchKMeans will be much faster than KMeans. (This will still take some time if dataset is large enough) ''' ag = argparse.ArgumentParser() ag.add_argument('--dataset', type=str, default='chafa8x8.npz') ag.add_argument('--save', type=str, default='chafa8x8.raw.json') ag.add_argument('-C', type=int, default=5120, help='number of clusters') ag.add_argument('-B', '--backend', type=str, default='sklearn', choices=('sklearn', 'faiss'), help='k-means backend') ag.add_argument('-I', '--iterations', type=int, default=100, help='number of iterations for K-means algorithm (faiss)') ag = ag.parse_args(argv) print(f'=> loading dataset from {ag.dataset}') dataset = np.load(ag.dataset)['dataset'] # Findout the cluster centers with KMeans print('=> Clustering ...') if ag.backend == 'sklearn': from sklearn.cluster import KMeans, MiniBatchKMeans kmeans = MiniBatchKMeans(n_clusters=ag.C, init='k-means++', init_size=37*ag.C, batch_size=8*ag.C, compute_labels=False, verbose=True).fit(dataset) centers = (kmeans.cluster_centers_ >= 0.5).astype(np.uint8) # Save the result to JSON file centers = list(sorted([list(map(int, center)) for center in centers], key=lambda x: sum(x))) json.dump(centers, open(ag.save, 'w')) elif ag.backend == 'faiss': import faiss # pip3 install faiss-gpu dataset = dataset.astype(np.float32) # uint8 to float32 print('dataset type', dataset.dtype, ', size', dataset.shape) clus = faiss.Clustering(dataset.shape[1], ag.C) clus.verbose = True clus.niter = ag.iterations clus.max_points_per_centroid = 10000000 res = faiss.StandardGpuResources() cfg = faiss.GpuIndexFlatConfig() cfg.useFloat16 = False index = faiss.GpuIndexFlatL2(res, dataset.shape[1], cfg) clus.train(dataset, index) centroids = faiss.vector_float_to_array(clus.centroids) centroids = centroids.reshape(ag.C, dataset.shape[1]) centroids = (centroids >= 0.5).astype(np.uint8) print('centroids', centroids.shape, centroids.dtype) # sort and save centroids = list(sorted( [list(map(int, c)) for c in centroids], key=lambda x: sum(x) )) json.dump(centroids, open(ag.save, 'w')) print(f'=> {ag.save}') def mainPostproc(argv: List[str]): ''' Post-processing to make the glyphs "smoother" and do deduplication Default convolution kernel: Gaussian 3x3 ''' ag = argparse.ArgumentParser() ag.add_argument('--json', type=str, default='chafa8x8.raw.json') ag.add_argument('--save', type=str, default='chafa8x8.json') ag = ag.parse_args(argv) from scipy.signal import convolve2d as conv2d # load raw vectors centers = json.load(open(ag.json, 'r')) print(' -> (before) number of centers:', len(centers)) # [default kernel] Gaussian kernel (kernel size = 3) Kg = np.array([[1/16, 1/8, 1/16], [1/8, 1/4, 1/8], [1/16, 1/8, 1/16]]) # mean value (glyphs tends to have round corner instead of sharp ones) Km = np.ones((3, 3))/9 # Select Kg as the default kernel K = Kg for (i, center) in enumerate(centers): center = np.array(center).reshape((8, 8)) center = conv2d(center, K, 'same').ravel() centers[i] = (center >= 0.5) centers = np.unique(np.array(centers), axis=0) print(' -> (after) number of centers:', centers.shape[0]) centers = list(sorted([list(map(int, center)) for center in centers], key=lambda x: sum(x))) json.dump(centers, open(ag.save, 'w')) print(f'=> Result saved to {ag.save}') def mainDump(argv: List[str]): ''' Dump human-readable bitmaps from json file ''' ag = argparse.ArgumentParser() ag.add_argument('--json', type=str, required=True) ag = ag.parse_args(argv) centers = json.load(open(ag.json, 'r')) for (i, center) in enumerate(centers): center = np.array(center) print('________', i) print(bdump8x8(center)) def mainGenC(argv: List[str]): ''' Generate C code ''' ag = argparse.ArgumentParser() ag.add_argument('--json', type=str, default='chafa8x8.json') ag.add_argument('--dst', type=str, default='chafa8x8.h') ag = ag.parse_args(argv) f = open(ag.dst, 'w') f.write(f'/* Auto-generated by {os.path.basename(__file__)}\n') f.write(f' * Version: {time.ctime()}\n') f.write(f' */\n') centers = json.load(open(ag.json, 'r')) for (i, center) in enumerate(centers): code = UNICODE_BASE + i comment = (1 not in center) if comment: f.write('#if 0\n') f.write('{\n') f.write(f' /* Chafa8x8 Font, ID: {i}, Unicode: 0x{code:x} */\n') f.write(f' CHAFA_SYMBOL_TAG_CUSTOM,\n') f.write(f' 0x{code:x},\n') f.write(bdump8x8(np.array(center), clang=True, padding=4)) f.write('},\n') if comment: f.write('#endif\n') f.close() def mainGenSVG(argv: List[str]): ''' Generate SVG files ''' ag = argparse.ArgumentParser() ag.add_argument('--json', type=str, default='chafa8x8.json') ag.add_argument('--dir', type=str, default='chafa8x8_svg') ag = ag.parse_args(argv) if not os.path.exists(ag.dir): os.mkdir(ag.dir) centers = json.load(open(ag.json, 'r')) for (i, center) in enumerate(centers): f = open(os.path.join(ag.dir, f'{i}.svg'), 'w') f.write('''\ ''') template = '\n' center = np.array(center).reshape(8, 8).astype(np.uint8) indeces = np.argwhere(center > 0) for index in indeces: r, c = index _w = (50 + 500.0 + 50) / 8.0 _h = (200 + 1000.0 + 75) / 8.0 f.write(template.format(w=_w, h=_h, x=-50+c*_w, y=-200+r*_h)) f.write(''' \n''') f.close() def mainGenBDF(argv: List[str]): ''' Generate BDF font (it is a plain text format!) https://en.wikipedia.org/wiki/Glyph_Bitmap_Distribution_Format ''' ag = argparse.ArgumentParser() ag.add_argument('--json', type=str, default='chafa8x8.json') ag.add_argument('--bdf', type=str, default='chafa8x8.bdf') ag = ag.parse_args(argv) # open file with open(ag.json, 'rt') as f: j = json.load(f) # List[List[int]] bdf = open(ag.bdf, 'wt') # write bdf header _timestamp_ = time.ctime().replace(' ', '-').replace(':', '-') bdf.writelines([ 'STARTFONT 2.1\n', f'FONT chafa8x8-{len(j)}-{_timestamp_}\n', 'SIZE 16 75 75\n', 'FONTBOUNDINGBOX 16 16 0 -2\n', '\n', 'STARTPROPERTIES 2\n', 'FONT_ASCENT 14\n', 'FONT_DESCENT 2\n', 'ENDPROPERTIES\n', '\n', f'CHARS {len(j)}\n', '\n', ]) # write characters _base_ = 0x100000 for (i, vector) in enumerate(j): # start char bdf.writelines([ f'COMMENT Chafa8x8-glyph-id-{i}\n', f'STARTCHAR U+{hex(_base_ + i)}\n', f'ENCODING {int(_base_ + i)}\n', f'SWIDTH 500 0\n', f'DWIDTH 8 0\n', 'BBX 8 16 0 -2\n', 'BITMAP\n', ]) # glyph representation for i in range(0, 64, 8): line = 0b0 for j in range(8): line = line + (0b1 << j) * vector[i + j] line = '{:02x}'.format(line).upper() bdf.writelines([line + '\n'] * 2) # end char bdf.writelines(['ENDCHAR\n', '\n']) # end font bdf.write('ENDFONT\n') # close file bdf.close() def mainGenFont(argv: List[str]): ''' Generate Font file (ttf) using fontforge ''' ag = argparse.ArgumentParser() ag.add_argument('--json', type=str, default='chafa8x8.json') ag.add_argument('--ttf', type=str, default='chafa8x8.ttf') ag = ag.parse_args(argv) try: import fontforge as ff except ModuleNotFoundError: print('You need to install the python3-fontforge package to generate the font') exit(1) import json N = len(json.load(open('chafa8x8.json', 'r'))) try: font = ff.font() font.clear() font.copyright = "(C) 2018 Mo Zhou , LGPLv3+" font.fontname = "Chafa8x8" font.familyname = "monospace" font.fullname = "Chafa8x8 block glyphs by K-Means for character art" font.version = "0a" font.encoding = 'Custom' print('Number of glyphs:', N) for i in range(N): glyph = font.createChar(0x100000 + i) glyph.importOutlines('chafa8x8_svg/%d.svg' % i) glyph.left_side_bearing = 0 glyph.right_side_bearing = 0 glyph.width = 500 glyph.vwidth = 1000 # font.save('chafa8x8.sfd') font.generate(ag.ttf) font.close() except Exception as e: print(e) print(f'done. the font has been written as {ag.ttf}') def mainGenA(argv: List[str]): print('calling ./chafa8x8.py Postproc') call(['./chafa8x8.py', 'Postproc']) print('calling ./chafa8x8.py GenC') call(['./chafa8x8.py', 'GenC']) print('calling ./chafa8x8.py GenSVG') call(['./chafa8x8.py', 'GenSVG']) print('calling ./chafa8x8.py GenFont') call(['./chafa8x8.py', 'GenFont']) # experimental #print('calling ./chafa8x8.py GenBDF') #call(['./chafa8x8.py', 'GenBDF']) #call('bdftopcf -o chafa8x8.pcf chafa8x8.bdf'.split()) if __name__ == '__main__': eval(f'main{sys.argv[1]}')(sys.argv[2:]) chafa-1.18.2/tools/fontgen/compare.py000077500000000000000000000014621517447374300174720ustar00rootroot00000000000000#!/usr/bin/env python3 # Just a simple tool to compare the results using different symbol sets # (C) 2018 Mo Zhou # LGPLv3+ import glob import argparse import random from subprocess import call if __name__ == '__main__': ag = argparse.ArgumentParser() ag.add_argument('--glob', type=str, required=True) ag.add_argument('-n', type=int, default=32) ag = ag.parse_args() images = glob.glob(ag.glob, recursive=True) print(f'=> found {len(images)} images') for i in range(ag.n): im = random.choice(images) print('<<<<<< chafa: block') # FIXME: the command is oudated call(['chafa', '-s', '80x24', '--symbols', 'block', im]) print('------') call(['chafa', '-s', '80x24', '--symbols', 'custom', im]) print('>>>>>> chafa: symbols=custom')